From 8722a9920c1f6119bf6e769cba270e63097f8e25 Mon Sep 17 00:00:00 2001
From: chai <215380520@qq.com>
Date: Thu, 23 May 2024 10:08:29 +0800
Subject: + astar project
---
.../Graphs/Grid/Rules/GridGraphRules.cs | 293 +++++++++++++++++++++
1 file changed, 293 insertions(+)
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Rules/GridGraphRules.cs
(limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Rules/GridGraphRules.cs')
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Rules/GridGraphRules.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Rules/GridGraphRules.cs
new file mode 100644
index 0000000..174b7d2
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Rules/GridGraphRules.cs
@@ -0,0 +1,293 @@
+using System.Collections.Generic;
+
+namespace Pathfinding.Graphs.Grid.Rules {
+ using Pathfinding.Serialization;
+ using Pathfinding.Jobs;
+ using Unity.Jobs;
+ using Unity.Collections;
+ using Unity.Mathematics;
+
+ public class CustomGridGraphRuleEditorAttribute : System.Attribute {
+ public System.Type type;
+ public string name;
+ public CustomGridGraphRuleEditorAttribute(System.Type type, string name) {
+ this.type = type;
+ this.name = name;
+ }
+ }
+
+ ///
+ /// Container for all rules in a grid graph.
+ ///
+ ///
+ /// // Get the first grid graph in the scene
+ /// var gridGraph = AstarPath.active.data.gridGraph;
+ ///
+ /// gridGraph.rules.AddRule(new Pathfinding.Graphs.Grid.Rules.RuleAnglePenalty {
+ /// penaltyScale = 10000,
+ /// curve = AnimationCurve.Linear(0, 0, 90, 1),
+ /// });
+ ///
+ ///
+ /// See:
+ /// See: grid-rules (view in online documentation for working links)
+ ///
+ [JsonOptIn]
+ public class GridGraphRules {
+ List >[] jobSystemCallbacks;
+ List >[] mainThreadCallbacks;
+
+ /// List of all rules
+ [JsonMember]
+ List rules = new List();
+
+ long lastHash;
+
+ /// Context for when scanning or updating a graph
+ public class Context {
+ /// Graph which is being scanned or updated
+ public GridGraph graph;
+ /// Data for all the nodes as NativeArrays
+ public GridGraphScanData data;
+ ///
+ /// Tracks dependencies between jobs to allow parallelism without tediously specifying dependencies manually.
+ /// Always use when scheduling jobs.
+ ///
+ public JobDependencyTracker tracker => data.dependencyTracker;
+ }
+
+ public void AddRule (GridGraphRule rule) {
+ rules.Add(rule);
+ lastHash = -1;
+ }
+
+ public void RemoveRule (GridGraphRule rule) {
+ rules.Remove(rule);
+ lastHash = -1;
+ }
+
+ public IReadOnlyList GetRules () {
+ if (rules == null) rules = new List();
+ return rules.AsReadOnly();
+ }
+
+ long Hash () {
+ long hash = 196613;
+
+ for (int i = 0; i < rules.Count; i++) {
+ if (rules[i] != null && rules[i].enabled) hash = hash * 1572869 ^ (long)rules[i].Hash;
+ }
+ return hash;
+ }
+
+ public void RebuildIfNecessary () {
+ var newHash = Hash();
+
+ if (newHash == lastHash && jobSystemCallbacks != null && mainThreadCallbacks != null) return;
+ lastHash = newHash;
+ Rebuild();
+ }
+
+ public void Rebuild () {
+ rules = rules ?? new List();
+ jobSystemCallbacks = jobSystemCallbacks ?? new List >[6];
+ for (int i = 0; i < jobSystemCallbacks.Length; i++) {
+ if (jobSystemCallbacks[i] != null) jobSystemCallbacks[i].Clear();
+ }
+ mainThreadCallbacks = mainThreadCallbacks ?? new List >[6];
+ for (int i = 0; i < mainThreadCallbacks.Length; i++) {
+ if (mainThreadCallbacks[i] != null) mainThreadCallbacks[i].Clear();
+ }
+ for (int i = 0; i < rules.Count; i++) {
+ if (rules[i].enabled) rules[i].Register(this);
+ }
+ }
+
+ public void DisposeUnmanagedData () {
+ if (rules != null) {
+ for (int i = 0; i < rules.Count; i++) {
+ if (rules[i] != null) {
+ rules[i].DisposeUnmanagedData();
+ rules[i].SetDirty();
+ }
+ }
+ }
+ }
+
+ static void CallActions (List > actions, Context context) {
+ if (actions != null) {
+ try {
+ for (int i = 0; i < actions.Count; i++) actions[i](context);
+ } catch (System.Exception e) {
+ UnityEngine.Debug.LogException(e);
+ }
+ }
+ }
+
+ ///
+ /// Executes the rules for the given pass.
+ /// Call handle.Complete on, or wait for, all yielded job handles.
+ ///
+ public IEnumerator ExecuteRule (GridGraphRule.Pass rule, Context context) {
+ if (jobSystemCallbacks == null) Rebuild();
+ CallActions(jobSystemCallbacks[(int)rule], context);
+
+ if (mainThreadCallbacks[(int)rule] != null && mainThreadCallbacks[(int)rule].Count > 0) {
+ if (!context.tracker.forceLinearDependencies) yield return context.tracker.AllWritesDependency;
+ CallActions(mainThreadCallbacks[(int)rule], context);
+ }
+ }
+
+ public void ExecuteRuleMainThread (GridGraphRule.Pass rule, Context context) {
+ if (jobSystemCallbacks[(int)rule] != null && jobSystemCallbacks[(int)rule].Count > 0) throw new System.Exception("A job system pass has been added for the " + rule + " pass. " + rule + " only supports main thread callbacks.");
+ if (context.tracker != null) context.tracker.AllWritesDependency.Complete();
+ CallActions(mainThreadCallbacks[(int)rule], context);
+ }
+
+ ///
+ /// Adds a pass callback that uses the job system.
+ /// This rule should only schedule jobs using the `Context.tracker` dependency tracker. Data is not safe to access directly in the callback
+ ///
+ /// This method should only be called from rules in their Register method.
+ ///
+ public void AddJobSystemPass (GridGraphRule.Pass pass, System.Action action) {
+ var index = (int)pass;
+
+ if (jobSystemCallbacks[index] == null) {
+ jobSystemCallbacks[index] = new List >();
+ }
+ jobSystemCallbacks[index].Add(action);
+ }
+
+ ///
+ /// Adds a pass callback that runs in the main thread.
+ /// The callback may access and modify any data in the context.
+ /// You do not need to schedule jobs in order to access the data.
+ ///
+ /// Warning: Not all data in the Context is valid for every pass. For example you cannot access node connections in the BeforeConnections pass
+ /// since they haven't been calculated yet.
+ ///
+ /// This is a bit slower than since parallelism and the burst compiler cannot be used.
+ /// But if you need to use non-thread-safe APIs or data then this is a good choice.
+ ///
+ /// This method should only be called from rules in their Register method.
+ ///
+ public void AddMainThreadPass (GridGraphRule.Pass pass, System.Action action) {
+ var index = (int)pass;
+
+ if (mainThreadCallbacks[index] == null) {
+ mainThreadCallbacks[index] = new List >();
+ }
+ mainThreadCallbacks[index].Add(action);
+ }
+
+ /// Deprecated: Use AddJobSystemPass or AddMainThreadPass instead
+ [System.Obsolete("Use AddJobSystemPass or AddMainThreadPass instead")]
+ public void Add (GridGraphRule.Pass pass, System.Action action) {
+ AddJobSystemPass(pass, action);
+ }
+ }
+
+ ///
+ /// Custom rule for a grid graph.
+ /// See:
+ /// See: grid-rules (view in online documentation for working links)
+ ///
+ [JsonDynamicType]
+ // Compatibility with old versions
+ [JsonDynamicTypeAlias("Pathfinding.RuleTexture", typeof(RuleTexture))]
+ [JsonDynamicTypeAlias("Pathfinding.RuleAnglePenalty", typeof(RuleAnglePenalty))]
+ [JsonDynamicTypeAlias("Pathfinding.RuleElevationPenalty", typeof(RuleElevationPenalty))]
+ [JsonDynamicTypeAlias("Pathfinding.RulePerLayerModifications", typeof(RulePerLayerModifications))]
+ public abstract class GridGraphRule {
+ /// Only enabled rules are executed
+ [JsonMember]
+ public bool enabled = true;
+ int dirty = 1;
+
+ ///
+ /// Where in the scanning process a rule will be executed.
+ /// Check the documentation for to see which data fields are valid in which passes.
+ ///
+ public enum Pass {
+ ///
+ /// Before the collision testing phase but after height testing.
+ /// This is very early. Most data is not valid by this point.
+ ///
+ /// You can use this if you want to modify the node positions and still have it picked up by the collision testing code.
+ ///
+ BeforeCollision,
+ ///
+ /// Before connections are calculated.
+ /// At this point height testing and collision testing has been done (if they are enabled).
+ ///
+ /// This is the most common pass to use.
+ /// If you are modifying walkability here then connections and erosion will be calculated properly.
+ ///
+ BeforeConnections,
+ ///
+ /// After connections are calculated.
+ ///
+ /// If you are modifying connections directly you should do that in this pass.
+ ///
+ /// Note: If erosion is used then this pass will be executed twice. One time before erosion and one time after erosion
+ /// when the connections are calculated again.
+ ///
+ AfterConnections,
+ ///
+ /// After erosion is calculated but before connections have been recalculated.
+ ///
+ /// If no erosion is used then this pass will not be executed.
+ ///
+ AfterErosion,
+ ///
+ /// After everything else.
+ /// This pass is executed after everything else is done.
+ /// You should not modify walkability in this pass because then the node connections will not be up to date.
+ ///
+ PostProcess,
+ ///
+ /// After the graph update has been applied to the graph.
+ ///
+ /// This pass can only be added as a main-thread pass.
+ ///
+ /// Warning: No native data in the context is valid at this point. It has all been disposed.
+ /// You cannot modify any data in this pass.
+ ///
+ AfterApplied,
+ }
+
+ ///
+ /// Hash of the settings for this rule.
+ /// The method will be called again whenever the hash changes.
+ /// If the hash does not change it is assumed that the method does not need to be called again.
+ ///
+ public virtual int Hash => dirty;
+
+ ///
+ /// Call if you have changed any setting of the rule.
+ /// This will ensure that any cached data the rule uses is rebuilt.
+ /// If you do not do this then any settings changes may not affect the graph when it is rescanned or updated.
+ ///
+ /// The purpose of this method call is to cause the property to change. If your custom rule overrides the Hash property to
+ /// return a hash of some settings, then you do not need to call this method for the changes the hash function already accounts for.
+ ///
+ public virtual void SetDirty () {
+ dirty++;
+ }
+
+ ///
+ /// Called when the rule is removed or the graph is destroyed.
+ /// Use this to e.g. clean up any NativeArrays that the rule uses.
+ ///
+ /// Note: The rule should remain valid after this method has been called.
+ /// However the method is guaranteed to be called before the rule is executed again.
+ ///
+ public virtual void DisposeUnmanagedData () {
+ }
+
+ /// Does preprocessing and adds callbacks to the object
+ public virtual void Register (GridGraphRules rules) {
+ }
+ }
+}
--
cgit v1.1-26-g67d0