Ejemplo n.º 1
0
 public void AssignSourceName(GlobalPath filePath)
 {
     AssignSourcePathToSection(filePath, FunctionsCode);
     AssignSourcePathToSection(filePath, InitializationCode);
     AssignSourcePathToSection(filePath, MainCode);
 }
    // Update is called once per frame
    void Update()
    {
        Vector3 position;

        if (Input.GetMouseButtonDown(0))
        {
            //if there is a valid position
            if (this.MouseClickPosition(out position))
            {
                //if this is the first click we're setting the start point
                if (this.currentClickNumber == 1)
                {
                    //show the start sphere, hide the end one
                    //this is just a small adjustment to better see the debug sphere
                    this.startDebugSphere.transform.position = position + Vector3.up;
                    this.startDebugSphere.SetActive(true);
                    this.endDebugSphere.SetActive(false);
                    this.currentClickNumber = 2;
                    this.startPosition      = position;
                    this.currentSolution    = null;
                    this.draw = false;
                }
                else
                {
                    //we're setting the end point
                    //this is just a small adjustment to better see the debug sphere
                    this.endDebugSphere.transform.position = position + Vector3.up;
                    this.endDebugSphere.SetActive(true);
                    this.currentClickNumber = 1;
                    this.endPosition        = position;
                    this.draw = true;
                    //initialize the search algorithm
                    this.AStarPathFinding.InitializePathfindingSearch(this.startPosition, this.endPosition);
                }
            }
        }
        else if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            this.InitializePathFinding(this.p5.transform.localPosition, this.p6.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            this.InitializePathFinding(this.p1.transform.localPosition, this.p2.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            this.InitializePathFinding(this.p2.transform.localPosition, this.p4.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            this.InitializePathFinding(this.p2.transform.localPosition, this.p5.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            this.InitializePathFinding(this.p1.transform.localPosition, this.p3.transform.localPosition);
        }

        //call the pathfinding method if the user specified a new goal
        if (this.AStarPathFinding.InProgress)
        {
            var finished = this.AStarPathFinding.Search(out this.currentSolution);
        }
    }
Ejemplo n.º 3
0
 public PathValue(GlobalPath path, SafeSharedObjects sharedObjects) : this()
 {
     Path = path;
     this.sharedObjects = sharedObjects;
 }
Ejemplo n.º 4
0
 public void CanHandleGlobalPathWithLessThanZeroDepth()
 {
     GlobalPath.FromString("othervolume:/test/../../");
 }
Ejemplo n.º 5
0
    private static void CreateClusterGraph()
    {
        Cluster cluster;
        Gateway gateway;

        //get cluster game objects
        var clusters = GameObject.FindGameObjectsWithTag("Cluster");

        //sort by name to be able to manually create the master clusters
        Array.Sort(clusters, CompareObNames);


        //get gateway game objects
        var gateways = GameObject.FindGameObjectsWithTag("Gateway");
        //get the NavMeshGraph from the current scene
        NavMeshPathGraph navMesh = GameObject.Find("Navigation Mesh").GetComponent <NavMeshRig>().NavMesh.Graph;

        ClusterGraph clusterGraph = ScriptableObject.CreateInstance <ClusterGraph>();

        //create gateway instances for each gateway game object
        for (int i = 0; i < gateways.Length; i++)
        {
            var gatewayGO = gateways[i];
            gateway = ScriptableObject.CreateInstance <Gateway>();
            gateway.Initialize(i, gatewayGO);
            clusterGraph.gateways.Add(gateway);
        }

        //create cluster instances for each cluster game object and check for connections through gateways
        foreach (var clusterGO in clusters)
        {
            cluster = ScriptableObject.CreateInstance <Cluster>();
            cluster.Initialize(clusterGO);
            clusterGraph.clusters.Add(cluster);

            //determine intersection between cluster and gateways and add connections when they intersect
            foreach (var gate in clusterGraph.gateways)
            {
                if (MathHelper.BoundingBoxIntersection(cluster.min, cluster.max, gate.min, gate.max))
                {
                    cluster.gateways.Add(gate);
                    gate.clusters.Add(cluster);
                }
            }
        }
        //Creating master clusters
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[1], clusterGraph.clusters[2]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[3], clusterGraph.clusters[4], clusterGraph.clusters[5], clusterGraph.clusters[18]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[19], clusterGraph.clusters[20], clusterGraph.clusters[21], clusterGraph.clusters[22], clusterGraph.clusters[23]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[24], clusterGraph.clusters[25], clusterGraph.clusters[26], clusterGraph.clusters[27], clusterGraph.clusters[28], clusterGraph.clusters[29]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[7], clusterGraph.clusters[8], clusterGraph.clusters[9], clusterGraph.clusters[10], clusterGraph.clusters[11], clusterGraph.clusters[12], clusterGraph.clusters[13], clusterGraph.clusters[14]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[6], clusterGraph.clusters[16], clusterGraph.clusters[17]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[0]));
        clusterGraph.MasterClusters.Add(new MasterCluster(clusterGraph.clusters[15]));

        // Second stage of the algorithm, calculation of the Gateway table

        GlobalPath solution = null;
        float      cost;
        Gateway    startGate;
        Gateway    endGate;
        int        gatewaysCount = gateways.Length;
        int        k, j;
        var        pathfindingAlgorithm = new NodeArrayAStarPathFinding(navMesh, new EuclidianHeuristic());

        GatewayDistanceTableRow[] distanceTable = new GatewayDistanceTableRow[gatewaysCount];

        for (k = 0; k < gatewaysCount; k++)
        {
            GatewayDistanceTableRow distanceTableRow = ScriptableObject.CreateInstance <GatewayDistanceTableRow>();
            distanceTableRow.Initialize(gatewaysCount);

            startGate = clusterGraph.gateways[k];

            for (j = 0; j < gatewaysCount; j++)
            {
                endGate = clusterGraph.gateways[j];

                if (startGate == endGate)
                {
                    cost = 0;
                }
                else
                {
                    pathfindingAlgorithm.InitializePathfindingSearch(startGate.Localize(), endGate.Localize());
                    pathfindingAlgorithm.Search(out solution);
                    solution.CalculateLength();
                    cost = solution.Length;
                }
                GatewayDistanceTableEntry entry = ScriptableObject.CreateInstance <GatewayDistanceTableEntry>();
                entry.Initialize(startGate.Localize(), endGate.Localize(), cost);

                distanceTableRow.AddEntry(entry, j);
            }
            distanceTable[k] = distanceTableRow;
        }

        clusterGraph.gatewayDistanceTable = distanceTable;

        //create a new asset that will contain the ClusterGraph and save it to disk (DO NOT REMOVE THIS LINE)
        clusterGraph.SaveToAssetDatabase();
    }
Ejemplo n.º 6
0
 public void SetPath(GlobalPath path)
 {
     FollowPathMovement.Path = path;
 }
Ejemplo n.º 7
0
        public void CanHandleChangingExtensionOfRootPaths()
        {
            GlobalPath path = GlobalPath.FromString("othervolume:");

            path.ChangeExtension("txt");
        }
Ejemplo n.º 8
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO put the code from the previous LAB here
            //you will get compiler errors, because I change the method names in the IOpenSet and IClosedSet interfaces
            //sorry but I had to do it because if not, Unity profiler would consider the Search method in Open and Closed to be the same
            //and you would not be able to see the difference in performance searching the Open Set and in searching the closed set

            //so just replace this.Open.Search(...) by this.Open.SearchInOpen(...) and all other methods where you get the compilation errors

            var   CurrentSearchNodes = 0;
            var   NodesProcessed     = 0;
            var   MaxOpenSize        = 0;
            float StartTime          = Time.realtimeSinceStartup;

            while (true)
            {
                if (Open.CountOpen() > MaxOpenSize)
                {
                    MaxOpenSize = Open.CountOpen();
                }

                if (Open.CountOpen() == 0)
                {
                    solution            = null;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    this.InProgress     = false;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(true);
                }


                if (NodesPerSearch < CurrentSearchNodes)
                {
                    if (returnPartialSolution)
                    {
                        solution = CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
                    }
                    else
                    {
                        solution = null;
                    }

                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(false);
                }

                NodeRecord CurrentNode = Open.GetBestAndRemove();

                if (CurrentNode.node == GoalNode)
                {
                    InProgress          = false;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    solution            = CalculateSolution(CurrentNode, false);
                    return(true);
                }

                Closed.AddToClosed(CurrentNode);
                CurrentSearchNodes++;
                NodesProcessed++;
                var NodeActions = CurrentNode.node.OutEdgeCount;

                for (int i = 0; i < NodeActions; i++)
                {
                    ProcessChildNode(CurrentNode, CurrentNode.node.EdgeOut(i));
                }
            }
        }
        //devolve true se acabou (porque encontrou sol ou nao ha nenhuma) ou false se ainda nao acabou
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO: implement this
            //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
            //something like this
            //var outConnections = bestNode.node.OutEdgeCount;
            //for (int i = 0; i < outConnections; i++)
            //{
            //this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
            var startTime      = Time.realtimeSinceStartup;
            var processedNodes = 0;

            while (processedNodes < this.NodesPerFrame)
            {
                //se houver nos no conj open
                if (this.Open.CountOpen() > 0)
                {
                    NodeRecord bestNode = this.Open.GetBestAndRemove();
                    if (bestNode.node == this.GoalNode)
                    {
                        //encontrou a sol
                        this.InProgress          = false;
                        solution                 = this.CalculateSolution(bestNode, returnPartialSolution);
                        this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                        return(true);
                    }
                    //se nao passa ao proximo no
                    this.Closed.AddToClosed(bestNode);
                    this.TotalExploredNodes++;
                    processedNodes++;

                    //para ver as ligacoes do no que acabamos de ver
                    var outConnections = bestNode.node.OutEdgeCount;
                    for (int i = 0; i < outConnections; i++)
                    {
                        this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                    }
                    this.MaxOpenNodes = Mathf.Max(this.Open.CountOpen(), this.MaxOpenNodes);
                }
                else
                {
                    //se nao ha solucao retorna null e true
                    this.InProgress          = false;
                    solution                 = null;
                    this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                    return(true);
                }
            }

            //se ja corremos o metodo ate ao numero de nos estabelecido e ainda nao encontrou o no
            if (returnPartialSolution)
            {
                //vai devolver o melhor ate agora
                solution = this.CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
            }
            else
            {
                solution = null;
            }

            this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
            return(false);
        }
Ejemplo n.º 10
0
 public PathValue FromPath(VolumePath volumePath, string volumeId)
 {
     return(new PathValue(GlobalPath.FromVolumePath(volumePath, volumeId), sharedObjects));
 }
    private void Update()
    {
        foreach (var pedestrian in this.Pedestrians)
        {
            pedestrian.Update();
        }

        Vector3 testMouseClickPosition;

        if (TargeterComponent.GetGoalPosition(out testMouseClickPosition))
        {
            this.mouseClickPosition = testMouseClickPosition;
            Actuator.SetGoalPosition(this.mouseClickPosition);
            DecomposerComponent.Initialize(this.mouseClickPosition);
            this.startPosition      = this.character.KinematicData.position;
            currentSmoothedSolution = null;
        }

        if (this.character.KinematicData.Arrived)
        {
            //NOTE: stops the char from going forward before it flips back
            this.character.KinematicData.velocity = Vector3.zero;
            return;
        }

        // Path recalculation for the car actuator
        if (currentSmoothedSolution != null)
        {
            float distanceToPath = (character.KinematicData.position - currentSmoothedSolution.GetPosition((Actuator.GetMovement() as DynamicFollowPath).CurrentParam)).sqrMagnitude;

            if (distanceToPath > 400 && DecomposerComponent.Initialize(this.mouseClickPosition)) // 400 = 20^2
            {
                Debug.Log("searching");
                this.startPosition = this.character.KinematicData.position;
                Actuator.SetGoalPosition(this.mouseClickPosition);
                this.CalculatePath      = true;
                currentSmoothedSolution = null;
                currentSolution         = null;
            }
        }

        if (this.CalculatePath)
        {
            //Debug.Log("CALCULATE PATH");
            DecomposerComponent.CalculatePath(out this.currentSolution);
        }

        if (this.currentSolution != null &&
            (this.currentSmoothedSolution == null || DecomposerComponent.InNewLocalPath(this.currentSmoothedSolution) || this.violation))
        {
            //Debug.Log("NEW LINE");
            this.currentSmoothedSolution = DecomposerComponent.SmoothPath(this.currentSolution);
            Actuator.SetPath(currentSmoothedSolution);
        }

        if (this.currentSmoothedSolution == null)
        {
            return;
        }

        GlobalPath actuatorPath = null;
        GlobalPath pathToFollow = currentSmoothedSolution;

        violation = false;

        for (int i = 0; i < ITERATIONS_LIMIT; i++)
        {
            actuatorPath = Actuator.GetPath(pathToFollow);

            foreach (IConstraint constraint in PathConstraints)
            {
                Vector3 suggestedPosition;
                violation = constraint.WillViolate(actuatorPath, out suggestedPosition);
                if (violation)
                {
                    pathToFollow = new GlobalPath();
                    pathToFollow.LocalPaths.Add(new LineSegmentPath(character.KinematicData.position, suggestedPosition));
                    //Debug.Log("Path collision violation");
                    break;
                }
            }

            if (violation)
            {
                continue;
            }

            // restrições de output
            foreach (IConstraint constraint in MovementConstraints)
            {
                Vector3 suggestedPosition;
                violation = constraint.WillViolate(actuatorPath, out suggestedPosition);
                if (violation)
                {
                    pathToFollow = new GlobalPath();
                    pathToFollow.LocalPaths.Add(new LineSegmentPath(character.KinematicData.position, suggestedPosition));
                    //Debug.Log("Movement collision violation");
                    break;
                }
            }

            if (!violation)
            {
                break;
            }
        }

        Debug.DrawLine(this.character.KinematicData.position, actuatorPath.LocalPaths[0].EndPosition, Color.black);

        //NOTE: setting new legal path for the actuator and clearing auxiliary variable
        if (!violation)
        {
            Actuator.SetPath(actuatorPath);
            actuatorPath = null;
        }

        character.MovementOutput = Actuator.GetOutput(actuatorPath, character);

        this.character.Update();
    }
Ejemplo n.º 12
0
 public override void LoadDump(Dump dump)
 {
     Path = GlobalPath.FromString(dump[DumpPath] as string);
 }
Ejemplo n.º 13
0
        void Update()
        {
            if (Time.time > this.nextUpdateTime)
            {
                this.nextUpdateTime = Time.time + DECISION_MAKING_INTERVAL;

                //first step, perceptions
                //update the agent's goals based on the state of the world
                this.SurviveGoal.InsistenceValue = this.GameManager.characterData.MaxHP - this.GameManager.characterData.HP;

                this.BeQuickGoal.InsistenceValue += DECISION_MAKING_INTERVAL * 0.1f;
                if (this.BeQuickGoal.InsistenceValue > 10.0f)
                {
                    this.BeQuickGoal.InsistenceValue = 10.0f;
                }

                this.GainXPGoal.InsistenceValue += 0.1f; //increase in goal over time
                if (this.GameManager.characterData.XP > this.previousXP)
                {
                    this.GainXPGoal.InsistenceValue -= this.GameManager.characterData.XP - this.previousXP;
                    this.previousXP = this.GameManager.characterData.XP;
                }

                this.GetRichGoal.InsistenceValue += 0.05f; //increase in goal over time
                if (this.GetRichGoal.InsistenceValue > 10)
                {
                    this.GetRichGoal.InsistenceValue = 10.0f;
                }

                if (this.GameManager.characterData.Money > this.previousGold)
                {
                    this.GetRichGoal.InsistenceValue -= this.GameManager.characterData.Money - this.previousGold;
                    this.previousGold = this.GameManager.characterData.Money;
                }

                this.SurviveGoalText.text = "Survive: " + this.SurviveGoal.InsistenceValue;
                this.GainXPGoalText.text  = "Gain XP: " + this.GainXPGoal.InsistenceValue.ToString("F1");
                this.BeQuickGoalText.text = "Be Quick: " + this.BeQuickGoal.InsistenceValue.ToString("F1");
                this.GetRichGoalText.text = "GetRich: " + this.GetRichGoal.InsistenceValue.ToString("F1");

                //initialize GOAP Decision Making Proccess
                this.GOAPDecisionMaking.InitializeDecisionMakingProcess();
            }

            if (this.GOAPDecisionMaking.InProgress)
            {
                //choose an action using the GOB Decision Making process
                var action = this.GOAPDecisionMaking.ChooseAction();
                if (action != null)
                {
                    action.Execute();
                    this.CurrentAction = action;
                }
            }

            this.TotalProcessingTimeText.text = "Process. Time: " + this.GOAPDecisionMaking.TotalProcessingTime.ToString("F");
            this.BestDiscontentmentText.text  = "Best Discontentment: " + this.GOAPDecisionMaking.BestDiscontentmentValue.ToString("F");
            this.ProcessedActionsText.text    = "Act. comb. processed: " + this.GOAPDecisionMaking.TotalActionCombinationsProcessed;

            if (this.GOAPDecisionMaking.BestAction != null)
            {
                var actionText = "";
                foreach (var action in this.GOAPDecisionMaking.BestActionSequence)
                {
                    if (action != null)
                    {
                        actionText += "\n" + action.Name;
                    }
                }
                this.BestActionText.text = "Best Action Sequence: " + actionText;
            }
            else
            {
                this.BestActionText.text = "Best Action Sequence:\nNone";
            }

            //call the pathfinding method if the user specified a new goal
            if (this.AStarPathFinding.InProgress)
            {
                var finished = this.AStarPathFinding.Search(out this.currentSolution);
                if (finished && this.currentSolution != null)
                {
                    //lets smooth out the Path
                    this.startPosition           = this.Character.KinematicData.position;
                    this.currentSmoothedSolution = StringPullingPathSmoothing.SmoothPath(this.Character.KinematicData, this.currentSolution);
                    this.currentSmoothedSolution.CalculateLocalPathsFromPathPositions(this.Character.KinematicData.position);

                    //TODO: use your own configuration for the DynamicFollowPath
                    //throw new System.NotImplementedException();
                    this.Character.Movement = new DynamicFollowPath(this.Character.KinematicData, this.currentSmoothedSolution)
                    {
                        MaxAcceleration = 40.0f,
                        MaxSpeed        = 20.0f
                    };
                }
            }

            this.Character.Update();
        }
Ejemplo n.º 14
0
 public override Path GetPath(GlobalPath path)
 {
     return(path);
 }
Ejemplo n.º 15
0
    private static void CreateClusterGraph()
    {
        Cluster cluster;
        Gateway gateway;

        //get cluster game objects
        var clusters = GameObject.FindGameObjectsWithTag("Cluster");
        //get gateway game objects
        var gateways = GameObject.FindGameObjectsWithTag("Gateway");
        //get the NavMeshGraph from the current scene
        NavMeshPathGraph navMesh = GameObject.Find("Navigation Mesh").GetComponent <NavMeshRig>().NavMesh.Graph;

        ClusterGraph clusterGraph = ScriptableObject.CreateInstance <ClusterGraph>();

        //create gateway instances for each gateway game object
        for (int i = 0; i < gateways.Length; i++)
        {
            var gatewayGO = gateways[i];
            gateway = ScriptableObject.CreateInstance <Gateway>();
            gateway.Initialize(i, gatewayGO);
            clusterGraph.gateways.Add(gateway);
        }

        //create cluster instances for each cluster game object and check for connections through gateways
        foreach (var clusterGO in clusters)
        {
            cluster = ScriptableObject.CreateInstance <Cluster>();
            cluster.Initialize(clusterGO);
            clusterGraph.clusters.Add(cluster);

            //determine intersection between cluster and gateways and add connections when they intersect
            foreach (var gate in clusterGraph.gateways)
            {
                if (MathHelper.BoundingBoxIntersection(cluster.min, cluster.max, gate.min, gate.max))
                {
                    cluster.gateways.Add(gate);
                    gate.clusters.Add(cluster);
                }
            }
        }

        // Second stage of the algorithm, calculation of the Gateway table

        GlobalPath solution = null;
        float      cost;
        Gateway    startGate;
        Gateway    endGate;

        var pathfindingAlgorithm = new NodeArrayAStarPathFinding(navMesh, new EuclideanDistanceHeuristic());

        //TODO implement the rest of the algorithm here, i.e. build the GatewayDistanceTable
        clusterGraph.gatewayDistanceTable = new GatewayDistanceTableRow[clusterGraph.gateways.Count];

        for (int i = 0; i < clusterGraph.gateways.Count; i++)
        {
            startGate = clusterGraph.gateways[i];
            clusterGraph.gatewayDistanceTable[i]         = ScriptableObject.CreateInstance <GatewayDistanceTableRow>();
            clusterGraph.gatewayDistanceTable[i].entries = new GatewayDistanceTableEntry[clusterGraph.gateways.Count];
            for (int j = 0; j < clusterGraph.gateways.Count; j++)
            {
                endGate = clusterGraph.gateways[j];
                pathfindingAlgorithm.InitializePathfindingSearch(startGate.center, endGate.center);
                pathfindingAlgorithm.Search(out solution);

                cost = solution.Length;
                clusterGraph.gatewayDistanceTable[i].entries[j] = ScriptableObject.CreateInstance <GatewayDistanceTableEntry>();
                clusterGraph.gatewayDistanceTable[i].entries[j].startGatewayPosition = startGate.center;
                clusterGraph.gatewayDistanceTable[i].entries[j].endGatewayPosition   = endGate.center;
                clusterGraph.gatewayDistanceTable[i].entries[j].shortestDistance     = cost;
            }
        }

        //create a new asset that will contain the ClusterGraph and save it to disk (DO NOT REMOVE THIS LINE)
        clusterGraph.SaveToAssetDatabase();
    }
Ejemplo n.º 16
0
        public void Start()
        {
            this.draw = true;

            this.navMesh   = NavigationManager.Instance.NavMeshGraphs[0];
            this.Character = new DynamicCharacter(this.gameObject);
            this.currentSmoothedSolution = new GlobalPath();
            //initialize your pathfinding algorithm here!
            //use goalBoundingPathfinding for a more efficient algorithm

            this.Initialize(NavigationManager.Instance.NavMeshGraphs[0], new NodeArrayAStarPathFinding(NavigationManager.Instance.NavMeshGraphs[0], new EuclidianHeuristic()));


            //initialization of the GOB decision making
            //let's start by creating 4 main goals

            this.SurviveGoal = new Goal(SURVIVE_GOAL, 2.0f);

            this.GainXPGoal = new Goal(GAIN_XP_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };

            this.GetRichGoal = new Goal(GET_RICH_GOAL, 1.0f)
            {
                InsistenceValue = 5.0f,
                ChangeRate      = 0.2f
            };

            this.BeQuickGoal = new Goal(BE_QUICK_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };

            this.Goals = new List <Goal>();
            this.Goals.Add(this.SurviveGoal);
            this.Goals.Add(this.BeQuickGoal);
            this.Goals.Add(this.GetRichGoal);
            this.Goals.Add(this.GainXPGoal);

            //initialize the available actions

            this.Actions = new List <Action>();


            foreach (var chest in GameObject.FindGameObjectsWithTag("Chest"))
            {
                this.Actions.Add(new PickUpChest(this, chest));
            }

            foreach (var potion in GameObject.FindGameObjectsWithTag("ManaPotion"))
            {
                this.Actions.Add(new GetManaPotion(this, potion));
            }

            foreach (var potion in GameObject.FindGameObjectsWithTag("HealthPotion"))
            {
                this.Actions.Add(new GetHealthPotion(this, potion));
            }

            foreach (var enemy in GameObject.FindGameObjectsWithTag("Skeleton"))
            {
                this.Actions.Add(new SwordAttack(this, enemy));
                this.Actions.Add(new Fireball(this, enemy));
            }

            foreach (var enemy in GameObject.FindGameObjectsWithTag("Orc"))
            {
                this.Actions.Add(new SwordAttack(this, enemy));
                this.Actions.Add(new Fireball(this, enemy));
            }

            foreach (var enemy in GameObject.FindGameObjectsWithTag("Dragon"))
            {
                this.Actions.Add(new SwordAttack(this, enemy));
                this.Actions.Add(new Fireball(this, enemy));
            }

            var worldModel = new CurrentStateWorldModel(this.GameManager, this.Actions, this.Goals);

            if (this.MCTSActive)
            {
                //this.MCTSDecisionMaking = new MCTS(worldModel);
                //this.MCTSDecisionMaking = new MCTSBiasedPlayout(worldModel);
                this.MCTSDecisionMaking = new MCTSRave(worldModel);
            }
            else
            {
                this.GOAPDecisionMaking = new DepthLimitedGOAPDecisionMaking(worldModel, this.Actions, this.Goals);
            }
        }
Ejemplo n.º 17
0
        public static YieldFinishedCompile CompileScriptToFile(GlobalPath scriptPath, int lineNumber, string fileContent, CompilerOptions compilerOptions, Volume storageVolume, GlobalPath storagePath)
        {
            var ret = new YieldFinishedCompile(scriptPath, lineNumber, fileContent, string.Empty, compilerOptions);

            ret.compileMode = CompileMode.FILE;
            ret.volume      = storageVolume;
            ret.outPath     = storagePath;
            return(ret);
        }
Ejemplo n.º 18
0
        public override void Execute(SafeSharedObjects shared)
        {
            // run() is strange.  It needs two levels of args - the args to itself, and the args it is meant to
            // pass on to the program it's invoking.  First, these are the args to run itself:
            object volumeId   = PopValueAssert(shared, true);
            object pathObject = PopValueAssert(shared, true);

            AssertArgBottomAndConsume(shared);

            // Now the args it is going to be passing on to the program:
            var progArgs = new List <object>();
            int argc     = CountRemainingArgs(shared);

            for (int i = 0; i < argc; ++i)
            {
                progArgs.Add(PopValueAssert(shared, true));
            }
            AssertArgBottomAndConsume(shared);

            if (shared.VolumeMgr == null)
            {
                return;
            }

            GlobalPath path       = shared.VolumeMgr.GlobalPathFromObject(pathObject);
            Volume     volume     = shared.VolumeMgr.GetVolumeFromPath(path);
            VolumeFile volumeFile = volume.Open(path) as VolumeFile;

            FileContent content = volumeFile != null?volumeFile.ReadAll() : null;

            if (content == null)
            {
                throw new Exception(string.Format("File '{0}' not found", path));
            }

            if (shared.ScriptHandler == null)
            {
                return;
            }

            if (volumeId != null)
            {
                throw new KOSObsoletionException("v1.0.2", "run [file] on [volume]", "None", "");
            }
            else
            {
                // clear the "program" compilation context
                shared.Cpu.StartCompileStopwatch();
                shared.ScriptHandler.ClearContext("program");
                //string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName;
                var options = new CompilerOptions {
                    LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                };
                var programContext = shared.Cpu.SwitchToProgramContext();

                List <CodePart> codeParts;
                if (content.Category == FileCategory.KSM)
                {
                    string prefix = programContext.Program.Count.ToString();
                    codeParts = content.AsParts(path, prefix);
                    programContext.AddParts(codeParts);
                    shared.Cpu.StopCompileStopwatch();
                }
                else
                {
                    shared.Cpu.YieldProgram(YieldFinishedCompile.RunScript(path, 1, content.String, "program", options));
                }
            }

            // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up,
            // it needs to put the return stack in a weird order.  Its return value needs to be buried UNDER the args to the
            // program it's calling:
            UsesAutoReturn = false;

            shared.Cpu.PushArgumentStack(0); // dummy return that all functions have.

            // Put the args for the program being called back on in the same order they were in before (so read the list backward):
            shared.Cpu.PushArgumentStack(new KOSArgMarkerType());
            for (int i = argc - 1; i >= 0; --i)
            {
                shared.Cpu.PushArgumentStack(progArgs[i]);
            }
        }
Ejemplo n.º 19
0
 public MovementOutput GetOutput(GlobalPath suggestedPath, DynamicCharacter character)
 {
     return(base.GetOutput(suggestedPath, character));
 }
Ejemplo n.º 20
0
        public override bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            var startTime      = Time.realtimeSinceStartup;
            var processedNodes = 0;
            int count;

            while (processedNodes < this.NodesPerSearch)
            {
                count = this.Open.CountOpen();
                if (count == 0)
                {
                    solution        = null;
                    this.InProgress = false;
                    this.CleanUp();
                    this.TotalProcessingTime += Time.realtimeSinceStartup - startTime;
                    return(true);
                }

                if (count > this.MaxOpenNodes)
                {
                    this.MaxOpenNodes = count;
                }

                var bestNode = this.NodeRecordArray.GetBestAndRemove();

                //goal node found, return the shortest Path
                if (bestNode.node == this.GoalNode)
                {
                    solution        = this.CalculateSolution(bestNode, false);
                    this.InProgress = false;
                    this.CleanUp();
                    this.TotalProcessingTime += Time.realtimeSinceStartup - startTime;
                    return(true);
                }

                this.NodeRecordArray.AddToClosed(bestNode);

                processedNodes++;
                this.TotalProcessedNodes++;


                //put your code here

                //or if you would like, you can change just these lines of code this in the original A* Pathfinding Class,
                //create a ProcessChildNode method in the base class with the code from the previous A* algorithm.
                //if you do this, then you don't need to implement this search method method. Don't forget to override the ProcessChildMethod if you do this
                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                }
            }

            this.TotalProcessingTime += Time.realtimeSinceStartup - startTime;

            //this is very unlikely but it might happen that we process all nodes alowed in this cycle but there are no more nodes to process
            if (this.Open.CountOpen() == 0)
            {
                solution        = null;
                this.InProgress = false;
                this.CleanUp();
                return(true);
            }

            //if the caller wants create a partial Path to reach the current best node so far
            if (returnPartialSolution)
            {
                var bestNodeSoFar = this.Open.PeekBest();
                solution = this.CalculateSolution(bestNodeSoFar, true);
            }
            else
            {
                solution = null;
            }
            return(false);
        }
Ejemplo n.º 21
0
        public void CanFailToCombineOutside()
        {
            GlobalPath path = GlobalPath.FromString("othervolume:123");

            path.Combine("..", "..");
        }
Ejemplo n.º 22
0
    // Update is called once per frame
    void Update()
    {
        Vector3 position;

        if (Input.GetMouseButtonDown(0))
        {
            //if there is a valid position
            if (this.MouseClickPosition(out position))
            {
                //if this is the first click we're setting the start point
                if (this.currentClickNumber == 1)
                {
                    //show the start sphere, hide the end one
                    //this is just a small adjustment to better see the debug sphere
                    this.startDebugSphere.transform.position = position + Vector3.up;
                    this.startDebugSphere.SetActive(true);
                    this.endDebugSphere.SetActive(false);
                    this.currentClickNumber = 2;
                    this.startPosition      = position;
                    this.currentSolution    = null;
                    this.draw = false;
                }
                else
                {
                    //we're setting the end point
                    //this is just a small adjustment to better see the debug sphere
                    this.endDebugSphere.transform.position = position + Vector3.up;
                    this.endDebugSphere.SetActive(true);
                    this.currentClickNumber = 1;
                    this.endPosition        = position;
                    this.draw = true;
                    //initialize the search algorithm
                    this.AStarPathFinding.InitializePathfindingSearch(this.startPosition, this.endPosition);
                }
            }
        }
        else if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            this.InitializePathFinding(this.p5.transform.localPosition, this.p6.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            this.InitializePathFinding(this.p1.transform.localPosition, this.p2.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            this.InitializePathFinding(this.p2.transform.localPosition, this.p4.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            this.InitializePathFinding(this.p2.transform.localPosition, this.p5.transform.localPosition);
        }
        else if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            this.InitializePathFinding(this.p1.transform.localPosition, this.p3.transform.localPosition);
        }

        //call the pathfinding method if the user specified a new goal
        if (this.AStarPathFinding.InProgress)
        {
            var finished = this.AStarPathFinding.Search(out this.currentSolution, false);
            if (finished)
            {
                followThePath = true;
                this.AStarPathFinding.InProgress = false;
                this.dynamicFollowPath.SetPath(this.currentSolution);
                this.dynamicFollowPath.finished     = false;
                this.dynamicFollowPath.currentParam = 0;
            }
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var finished = this.AStarPathFinding.Search(out this.currentSolution, true);
            if (finished)
            {
                this.AStarPathFinding.InProgress = false;
            }
        }
        if (followThePath)
        {
            if (this.dynamicFollowPath.finished == true)
            {
                //ignore because it reached the end
                //Debug.Log("ACABOU");
            }
            else
            {
                this.character.Movement = this.dynamicFollowPath;

                if (this.character.Movement != null)
                {
                    this.character.Update();
                }
            }
        }
    }
Ejemplo n.º 23
0
 public abstract Path GetPath(GlobalPath path);
        //this method should return true if the Search process finished (i.e either because it found a solution or because there was no solution
        //it should return false if the search process didn't finish yet
        //when returning true, the solution parameter should be set to null if there is no solution. Otherwise it must contain the found solution
        //if the parameter returnPartialSolution is true, then the user wants to have a partial path to the best node so far even when the search has not finished searching
        public virtual bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            var        startTime = Time.realtimeSinceStartup;
            NodeRecord bestNode;
            uint       nodes = this.NodesPerSearch;

            for (; nodes > 0; nodes--)
            {
                if (this.Open.CountOpen() == 0)
                {
                    this.CleanUp();
                    solution        = null;
                    this.InProgress = false;
                    if (returnPartialSolution)
                    {
                        this.TotalProcessingTime = Time.realtimeSinceStartup - this.StartTime;
                    }
                    else
                    {
                        this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                    }

                    return(true);
                }
                bestNode = this.Open.GetBestAndRemove();
                if (bestNode.node.Equals(this.GoalNode))
                {
                    this.CleanUp();
                    solution        = this.CalculateSolution(bestNode, returnPartialSolution);
                    this.InProgress = false;
                    if (returnPartialSolution)
                    {
                        this.TotalProcessingTime = Time.realtimeSinceStartup - this.StartTime;
                    }
                    else
                    {
                        this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                    }
                    return(true);
                }
                this.Open.RemoveFromOpen(bestNode);
                this.Closed.AddToClosed(bestNode);
                this.TotalProcessedNodes++;

                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                }

                if (this.Open.CountOpen() > this.MaxOpenNodes)
                {
                    this.MaxOpenNodes = this.Open.CountOpen();
                }
            }

            if (returnPartialSolution == true)
            {
                solution = this.CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
                return(true);
            }

            solution = null;
            return(false);
        }
Ejemplo n.º 25
0
    private static void CreateClusterGraph()
    {
        Cluster cluster;
        Gateway gateway;

        //get cluster game objects
        var clusters = GameObject.FindGameObjectsWithTag("Cluster");
        //get gateway game objects
        var gateways = GameObject.FindGameObjectsWithTag("Gateway");
        //get the NavMeshGraph from the current scene
        NavMeshPathGraph navMesh = GameObject.Find("Navigation Mesh").GetComponent <NavMeshRig>().NavMesh.Graph;

        ClusterGraph clusterGraph = ScriptableObject.CreateInstance <ClusterGraph>();

        //create gateway instances for each gateway game object
        for (int i = 0; i < gateways.Length; i++)
        {
            var gatewayGO = gateways[i];
            gateway = ScriptableObject.CreateInstance <Gateway>();
            gateway.Initialize(i, gatewayGO);
            clusterGraph.gateways.Add(gateway);
        }

        //create cluster instances for each cluster game object and check for connections through gateways
        foreach (var clusterGO in clusters)
        {
            cluster = ScriptableObject.CreateInstance <Cluster>();
            cluster.Initialize(clusterGO);
            clusterGraph.clusters.Add(cluster);

            //determine intersection between cluster and gateways and add connections when they intersect
            foreach (var gate in clusterGraph.gateways)
            {
                if (MathHelper.BoundingBoxIntersection(cluster.min, cluster.max, gate.min, gate.max))
                {
                    cluster.gateways.Add(gate);
                    gate.clusters.Add(cluster);
                }
            }
        }

        // Second stage of the algorithm, calculation of the Gateway table

        GlobalPath solution = null;
        float      cost;

        var pathfindingManager = new PathfindingManager();

        pathfindingManager.Initialize(navMesh, new NodeArrayAStarPathFinding(navMesh, new EuclideanDistanceHeuristic()));

        //TODO implement the rest of the algorithm here, i.e. build the GatewayDistanceTable
        clusterGraph.gatewayDistanceTable = new GatewayDistanceTableRow[clusterGraph.CountGateways()];

        foreach (Gateway startGate in clusterGraph.gateways)
        {
            Vector3 startGatePosition = startGate.Localize();
            GatewayDistanceTableRow startGateToOthers = new GatewayDistanceTableRow();
            startGateToOthers.entries = new GatewayDistanceTableEntry[clusterGraph.CountGateways()];
            foreach (Gateway endGate in clusterGraph.gateways)
            {
                Vector3 endGatePosition        = endGate.Localize();
                GatewayDistanceTableEntry cell = new GatewayDistanceTableEntry();
                cell.startGatewayPosition = startGatePosition;
                cell.endGatewayPosition   = endGatePosition;

                if (startGatePosition == endGatePosition)
                {
                    cost = 0;
                }
                else
                {
                    pathfindingManager.AStarPathFinding.InitializePathfindingSearch(startGatePosition, endGatePosition);
                    while (pathfindingManager.AStarPathFinding.InProgress)
                    {
                        var finished = pathfindingManager.AStarPathFinding.Search(out solution);
                        if (finished)
                        {
                            pathfindingManager.AStarPathFinding.InProgress = false;
                        }
                    }
                    cost = solution.Length;
                }
                cell.shortestDistance = cost;
                startGateToOthers.entries[endGate.id] = cell;
            }
            clusterGraph.gatewayDistanceTable[startGate.id] = startGateToOthers;
        }

        //create a new asset that will contain the ClusterGraph and save it to disk (DO NOT REMOVE THIS LINE)
        clusterGraph.SaveToAssetDatabase();
    }
Ejemplo n.º 26
0
        public override void Execute(SharedObjects shared)
        {
            // run() is strange.  It needs two levels of args - the args to itself, and the args it is meant to
            // pass on to the program it's invoking.  First, these are the args to run itself:
            object volumeId   = PopValueAssert(shared, true);
            object pathObject = PopValueAssert(shared, true);

            AssertArgBottomAndConsume(shared);

            // Now the args it is going to be passing on to the program:
            var progArgs = new List <object>();
            int argc     = CountRemainingArgs(shared);

            for (int i = 0; i < argc; ++i)
            {
                progArgs.Add(PopValueAssert(shared, true));
            }
            AssertArgBottomAndConsume(shared);

            if (shared.VolumeMgr == null)
            {
                return;
            }

            GlobalPath path       = shared.VolumeMgr.GlobalPathFromObject(pathObject);
            Volume     volume     = shared.VolumeMgr.GetVolumeFromPath(path);
            VolumeFile volumeFile = volume.Open(path) as VolumeFile;

            FileContent content = volumeFile != null?volumeFile.ReadAll() : null;

            if (content == null)
            {
                throw new Exception(string.Format("File '{0}' not found", path));
            }

            if (shared.ScriptHandler == null)
            {
                return;
            }

            if (volumeId != null)
            {
                Volume targetVolume = shared.VolumeMgr.GetVolume(volumeId);
                if (targetVolume != null)
                {
                    if (shared.ProcessorMgr != null)
                    {
                        var options = new CompilerOptions {
                            LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                        };

                        List <CodePart> parts   = shared.ScriptHandler.Compile(path, 1, volumeFile.ReadAll().String, "program", options);
                        var             builder = new ProgramBuilder();
                        builder.AddRange(parts);
                        List <Opcode> program = builder.BuildProgram();
                        shared.ProcessorMgr.RunProgramOn(program, targetVolume);
                    }
                }
                else
                {
                    throw new KOSFileException("Volume not found");
                }
            }
            else
            {
                // clear the "program" compilation context
                shared.Cpu.StartCompileStopwatch();
                shared.ScriptHandler.ClearContext("program");
                //string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName;
                var options = new CompilerOptions {
                    LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                };
                var programContext = ((CPU)shared.Cpu).SwitchToProgramContext();

                List <CodePart> codeParts;
                if (content.Category == FileCategory.KSM)
                {
                    string prefix = programContext.Program.Count.ToString();
                    codeParts = content.AsParts(path, prefix);
                }
                else
                {
                    try
                    {
                        codeParts = shared.ScriptHandler.Compile(path, 1, content.String, "program", options);
                    }
                    catch (Exception)
                    {
                        // If it died due to a compile error, then we won't really be able to switch to program context
                        // as was implied by calling Cpu.SwitchToProgramContext() up above.  The CPU needs to be
                        // told that it's still in interpreter context, or else it fails to advance the interpreter's
                        // instruction pointer and it will just try the "call run()" instruction again:
                        shared.Cpu.BreakExecution(false);
                        throw;
                    }
                }
                programContext.AddParts(codeParts);
                shared.Cpu.StopCompileStopwatch();
            }

            // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up,
            // it needs to put the return stack in a weird order.  Its return value needs to be buried UNDER the args to the
            // program it's calling:
            UsesAutoReturn = false;

            shared.Cpu.PushStack(0); // dummy return that all functions have.

            // Put the args for the program being called back on in the same order they were in before (so read the list backward):
            shared.Cpu.PushStack(new KOSArgMarkerType());
            for (int i = argc - 1; i >= 0; --i)
            {
                shared.Cpu.PushStack(progArgs[i]);
            }
        }
Ejemplo n.º 27
0
        void Update()
        {
            if (Time.time > this.nextUpdateTime || this.GameManager.WorldChanged)
            {
                this.GameManager.WorldChanged = false;
                this.nextUpdateTime           = Time.time + DECISION_MAKING_INTERVAL;

                //first step, perceptions
                //update the agent's goals based on the state of the world
                this.SurviveGoal.InsistenceValue = this.GameManager.characterData.MaxHP - this.GameManager.characterData.HP;

                this.BeQuickGoal.InsistenceValue += DECISION_MAKING_INTERVAL * 0.1f;
                if (this.BeQuickGoal.InsistenceValue > 10.0f)
                {
                    this.BeQuickGoal.InsistenceValue = 10.0f;
                }

                this.GainXPGoal.InsistenceValue += 0.1f;                 //increase in goal over time
                if (this.GameManager.characterData.XP > this.previousXP)
                {
                    this.GainXPGoal.InsistenceValue -= this.GameManager.characterData.XP - this.previousXP;
                    this.previousXP = this.GameManager.characterData.XP;
                }

                this.GetRichGoal.InsistenceValue += 0.1f;                 //increase in goal over time
                if (this.GetRichGoal.InsistenceValue > 10)
                {
                    this.GetRichGoal.InsistenceValue = 10.0f;
                }

                if (this.GameManager.characterData.Money > this.previousGold)
                {
                    this.GetRichGoal.InsistenceValue -= this.GameManager.characterData.Money - this.previousGold;
                    this.previousGold = this.GameManager.characterData.Money;
                }

                this.SurviveGoalText.text = "Survive: " + this.SurviveGoal.InsistenceValue;
                this.GainXPGoalText.text  = "Gain XP: " + this.GainXPGoal.InsistenceValue.ToString("F1");
                this.BeQuickGoalText.text = "Be Quick: " + this.BeQuickGoal.InsistenceValue.ToString("F1");
                this.GetRichGoalText.text = "GetRich: " + this.GetRichGoal.InsistenceValue.ToString("F1");

                //initialize Decision Making Proccess
                this.CurrentAction = null;

                if (!MCTSActive)
                {
                    this.GOAPDecisionMaking.InitializeDecisionMakingProcess();
                }
                else
                {
                    this.MCTSAlgorithm.InitializeMCTSearch();
                }
            }

            if (!MCTSActive)
            {
                this.UpdateDLGOAP();
            }
            else
            {
                this.UpdateMCTS();
            }


            if (this.CurrentAction != null)
            {
                if (this.CurrentAction.CanExecute())
                {
                    this.CurrentAction.Execute();
                }
            }

            //call the pathfinding method if the user specified a new goal
            if (this.AStarPathFinding.InProgress)
            {
                var finished = this.AStarPathFinding.Search(out this.currentSolution);
                if (finished && this.currentSolution != null)
                {
                    //lets smooth out the Path
                    this.startPosition = this.Character.KinematicData.position;

                    this.currentSmoothedSolution = PathSmoothing.Instance.SmoothPath(this.currentSolution);

                    this.currentSmoothedSolution.CalculateLocalPathsFromPathPositions(this.Character.KinematicData.position);

                    this.Character.Movement = new DynamicFollowPath(this.Character.KinematicData, this.currentSmoothedSolution)
                    {
                        MaxAcceleration = 200.0f,
                        MaxSpeed        = 40.0f
                    };
                }
            }


            this.Character.Update();
            //manage the character's animation
            if (this.Character.KinematicData.velocity.sqrMagnitude > 0.1)
            {
                this.characterAnimator.SetBool("Walking", true);
            }
            else
            {
                this.characterAnimator.SetBool("Walking", false);
            }
        }
Ejemplo n.º 28
0
        public override void Execute(SharedObjects shared)
        {
            // NOTE: The built-in load() function actually ends up returning
            // two things on the stack: on top is a boolean for whether the program
            // was already loaded, and under that is an integer for where to jump to
            // to call it.  The load() function is NOT meant to be called directly from
            // a user script.
            // (unless it's being called in compile-only mode, in which case it
            // returns the default dummy zero on the stack like everything else does).

            bool       defaultOutput = false;
            bool       justCompiling = false;                        // is this load() happening to compile, or to run?
            GlobalPath outPath       = null;
            object     topStack      = PopValueAssert(shared, true); // null if there's no output file (output file means compile, not run).

            if (topStack != null)
            {
                justCompiling = true;
                string outputArg = topStack.ToString();
                if (outputArg.Equals("-default-compile-out-"))
                {
                    defaultOutput = true;
                }
                else
                {
                    outPath = shared.VolumeMgr.GlobalPathFromObject(outputArg);
                }
            }

            object skipAlreadyObject     = PopValueAssert(shared, false);
            bool   skipIfAlreadyCompiled = (skipAlreadyObject is bool) ? (bool)skipAlreadyObject : false;

            object pathObject = PopValueAssert(shared, true);

            AssertArgBottomAndConsume(shared);

            if (pathObject == null)
            {
                throw new KOSFileException("No filename to load was given.");
            }

            GlobalPath path   = shared.VolumeMgr.GlobalPathFromObject(pathObject);
            Volume     volume = shared.VolumeMgr.GetVolumeFromPath(path);

            VolumeFile file = volume.Open(path, !justCompiling) as VolumeFile; // if running, look for KSM first.  If compiling look for KS first.

            if (file == null)
            {
                throw new KOSFileException(string.Format("Can't find file '{0}'.", path));
            }
            path = GlobalPath.FromVolumePath(file.Path, shared.VolumeMgr.GetVolumeId(volume));

            if (skipIfAlreadyCompiled && !justCompiling)
            {
                var programContext = ((CPU)shared.Cpu).SwitchToProgramContext();
                int programAddress = programContext.GetAlreadyCompiledEntryPoint(path.ToString());
                if (programAddress >= 0)
                {
                    // TODO - The check could also have some dependancy on whether the file content changed on
                    //     disk since last time, but that would also mean having to have a way to clear out the old
                    //     copy of the compiled file from the program context, which right now doesn't exist. (Without
                    //     that, doing something like a loop that re-wrote a file and re-ran it 100 times would leave
                    //     100 old dead copies of the compiled opcodes in memory, only the lastmost copy being really used.)

                    // We're done here.  Skip the compile.  Point the caller at the already-compiled version.
                    shared.Cpu.PushStack(programAddress);
                    this.ReturnValue = true; // tell caller that it already existed.
                    return;
                }
            }

            FileContent fileContent = file.ReadAll();

            // filename is now guaranteed to have an extension.  To make default output name, replace the extension with KSM:
            if (defaultOutput)
            {
                outPath = path.ChangeExtension(Volume.KOS_MACHINELANGUAGE_EXTENSION);
            }

            if (path.Equals(outPath))
            {
                throw new KOSFileException("Input and output paths must differ.");
            }

            if (shared.VolumeMgr == null)
            {
                return;
            }
            if (shared.VolumeMgr.CurrentVolume == null)
            {
                throw new KOSFileException("Volume not found");
            }

            if (shared.ScriptHandler != null)
            {
                shared.Cpu.StartCompileStopwatch();
                var options = new CompilerOptions {
                    LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                };
                // add this program to the address space of the parent program,
                // or to a file to save:
                if (justCompiling)
                {
                    // since we've already read the file content, use the volume from outPath instead of the source path
                    volume = shared.VolumeMgr.GetVolumeFromPath(outPath);
                    List <CodePart> compileParts = shared.ScriptHandler.Compile(path, 1, fileContent.String, string.Empty, options);
                    VolumeFile      written      = volume.SaveFile(outPath, new FileContent(compileParts));
                    if (written == null)
                    {
                        throw new KOSFileException("Can't save compiled file: not enough space or access forbidden");
                    }
                }
                else
                {
                    var             programContext = ((CPU)shared.Cpu).SwitchToProgramContext();
                    List <CodePart> parts;
                    if (fileContent.Category == FileCategory.KSM)
                    {
                        string prefix = programContext.Program.Count.ToString();
                        parts = fileContent.AsParts(path, prefix);
                    }
                    else
                    {
                        parts = shared.ScriptHandler.Compile(path, 1, fileContent.String, "program", options);
                    }
                    int programAddress = programContext.AddObjectParts(parts, path.ToString());
                    // push the entry point address of the new program onto the stack
                    shared.Cpu.PushStack(programAddress);
                    this.ReturnValue = false; // did not already exist.
                }
                shared.Cpu.StopCompileStopwatch();
            }
        }
Ejemplo n.º 29
0
 public PathValue FromPath(GlobalPath path)
 {
     return(new PathValue(path, sharedObjects));
 }
 public bool InNewLocalPath(GlobalPath currentSolution)
 {
     return(currentSolution.Switched);
 }