コード例 #1
0
        /// <summary>
        ///		Loads a new script and creates a process out of it, then associates it
        ///		with this virtual machine.
        /// </summary>
        /// <param name="url">Url of file this script is in.</param>
        /// <param name="cache">If set to true this scripts byte code will be cached for quick loading.</param>
        public ScriptProcess LoadScript(object url, bool cache)
        {
            DebugLogger.WriteLog("Loading script into virtual machine from " + url);

            HighPreformanceTimer timer = new HighPreformanceTimer();

            if (Resources.ResourceManager.ResourceIsCached(url.ToString()))
            {
                ScriptProcess oldProcess = (ScriptProcess)Resources.ResourceManager.RetrieveResource(url.ToString());

                // Create process and hand loading over to it.
                ScriptProcess process = new ScriptProcess(this, (ScriptProcess)oldProcess);
                process.Url = url as string;
                _processes.Add(process);

                DebugLogger.WriteLog("Loaded script from cache in "+timer.DurationMillisecond+".");

                return process;
            }

            // Open a stream so we can read in the script.
            Stream stream = StreamFactory.RequestStream(url, StreamMode.Open);
            if (stream == null) return null;
            BinaryReader reader = new BinaryReader(stream);

            // Check if this script is already compiled or not.
            if (reader.ReadByte() == 'C' && reader.ReadByte() == 'R' && reader.ReadByte() == 'X')
            {
                // Clean up our file handle.
                reader.Close();
                stream.Close();

                // Create process and hand loading over to it.
                ScriptProcess process = new ScriptProcess(this, url);
                process.Url = url as string;
                _processes.Add(process);

                if (cache == true) Resources.ResourceManager.CacheResource(url.ToString(), process);

                DebugLogger.WriteLog("Script loaded in " + timer.DurationMillisecond + ".");
                return process;
            }
            else
            {
                // Clean up our file handle.
                reader.Close();

                // Compiler script to byte code.
                ScriptCompiler compiler = new ScriptCompiler();
                if (compiler.Compile(url) > 0)
                {
                    bool serious = false;
                    foreach (CompileError error in compiler.ErrorList)
                        if (error.AlertLevel == ErrorAlertLevel.Error || error.AlertLevel == ErrorAlertLevel.FatalError)
                            serious = true;

                    if (serious == true)
                    {
                        DebugLogger.WriteLog(compiler.ErrorList.Count + " error(s) occured while compiling script from " + url.ToString() + ".");
                        foreach (CompileError error in compiler.ErrorList)
                            DebugLogger.WriteLog("\t" + error.ToString());
                        return null;
                    }
                }

                // Create a memory stream and dump the byte code into it.
                Stream memoryStream = new MemoryStream();
                if (memoryStream == null) return null;
                BinaryWriter memoryWriter = new BinaryWriter(memoryStream);
                BinaryReader memoryReader = new BinaryReader(memoryStream);

                compiler.DumpExecutableFile(memoryWriter);

                // Create process and hand loading over to it.
                memoryStream.Position = 0;
                ScriptProcess process = new ScriptProcess(this, memoryReader);
                process.Url = url as string;
                _processes.Add(process);

                memoryReader.Close();
                memoryWriter.Close();
                memoryStream.Close();
                stream.Close();

                if (cache == true) Resources.ResourceManager.CacheResource(url.ToString(), process);
                DebugLogger.WriteLog("Script loaded in " + timer.DurationMillisecond + ".");
                return process;
            }
        }
コード例 #2
0
        /// <summary>
        ///		Called by the asset manager whenever a script is modified.
        /// </summary>
        /// <param name="sender">The script window that invoked this event.</param>
        /// <param name="e">Arguments explaining why this event occured.</param>
        private void ScriptModified(object sender, EventArgs e)
        {
            ScriptEditorWindow editorWindow = sender as ScriptEditorWindow;

            // Compile the script.
            ScriptCompiler compiler = new ScriptCompiler();
            bool errorOccured = false;
            string errorDescription = "";
            if (compiler.Compile(editorWindow.Url) > 0)
                foreach (CompileError error in compiler.ErrorList)
                    if (error.AlertLevel == ErrorAlertLevel.Error || error.AlertLevel == ErrorAlertLevel.FatalError)
                    {
                        errorDescription += (errorDescription == "" ? "" : "\n") + error.ToString();
                        errorOccured = true;
                    }

            // If an error occured notify the user if not then
            // insert a new scripted entity into the map.
            if (errorOccured == true)
            {
                MessageBox.Show("Unable to recompile object's script, the following error(s) occured while attempt to compile object's script.\n\n" + errorDescription, "Compile Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                DebugLogger.WriteLog("Object's script recompile aborted. The following error(s) occured while attempting to compile object's script.\n\n" + errorDescription, LogAlertLevel.Warning);
                return;
            }

            foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
            {
                if (node is ScriptedEntityNode == false) continue;
                ScriptedEntityNode scriptEntityNode = node as ScriptedEntityNode;
                if (scriptEntityNode.ScriptProcess.Url.ToLower() != ((string)editorWindow.Url).ToLower()) continue;

                // Dump the compiled code into a memory stream.
                MemoryStream memStream = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(memStream);
                BinaryReader reader = new BinaryReader(memStream);
                compiler.DumpExecutableFile(writer);
                memStream.Position = 0;

                // Store current values of properties so we can set them in the
                // new script later.
                Hashtable propertyValueTable = new Hashtable();
                foreach (Symbol symbol in scriptEntityNode.ScriptProcess.GlobalScope.Symbols)
                {
                    if (symbol is VariableSymbol == false || ((VariableSymbol)symbol).IsProperty == false) continue;
                    VariableSymbol propertySymbol = symbol as VariableSymbol;
                    propertyValueTable.Add(propertySymbol.Identifier, propertySymbol);
                }

                // Create a new scripted entity with the given script attached to it.
                ScriptProcess previousScript = scriptEntityNode.ScriptProcess;
                scriptEntityNode.ScriptProcess = new ScriptProcess(null, reader);
                scriptEntityNode.ScriptProcess.Url = previousScript.Url;

                // Free up the streams.
                memStream.Close();
                reader.Close();
                writer.Close();

                // Go through each property in this process and set its value to
                // the old one (if it exists).
                foreach (Symbol symbol in scriptEntityNode.ScriptProcess.GlobalScope.Symbols)
                {
                    if (symbol is VariableSymbol == false || ((VariableSymbol)symbol).IsProperty == false) continue;
                    VariableSymbol propertySymbol = symbol as VariableSymbol;
                    if (propertyValueTable.Contains(propertySymbol.Identifier) == true)
                    {
                        VariableSymbol previousPropertySymbol = (VariableSymbol)propertyValueTable[propertySymbol.Identifier];
                        if (previousPropertySymbol.DataType != propertySymbol.DataType) continue;
                        switch (propertySymbol.DataType.DataType)
                        {
                            case DataType.Bool:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetBooleanGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Byte:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetByteGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Double:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetDoubleGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Float:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetFloatGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Int:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetIntegerGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Long:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetLongGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.Short:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetShortGlobal(propertySymbol.Identifier));
                                break;
                            case DataType.String:
                                scriptEntityNode.ScriptProcess[0].SetGlobalVariable(propertySymbol.Identifier, previousScript[0].GetStringGlobal(propertySymbol.Identifier));
                                break;
                        }
                    }
                }

                if (_entityPropertiesWindow != null && _entityPropertiesWindow.Entity == node)
                    _entityPropertiesWindow.SyncronizeData();
            }
        }
コード例 #3
0
        /// <summary>
        ///		Copys a directory tree from one location to another, unlike the one in IOMethods this
        ///		one will also increment a progress bar as it copys the directory tree.
        /// </summary>
        /// <param name="from">The source directory tree.</param>
        /// <param name="to">The destination path of the directory tree.</param>
        private void CopyDirectoryWithProgress(string from, string to)
        {
            // Append a directory seperator to the end of the path.
            if (to[to.Length - 1] != Path.DirectorySeparatorChar)
                to += Path.DirectorySeparatorChar;

            // If the destination directory does not exist then create it.
            if (Directory.Exists(to) == false) Directory.CreateDirectory(to);

            // Retrieve all the files in the directory to be copied.
            string[] files = Directory.GetFileSystemEntries(from);

            // Update the progress bar.
            DebugLogger.WriteLog("Copying directory \"" + from + "\"...");
            _subTaskProgress = 0;
            _subTask = "Copying directory: " + from;
            _logStack.Push(_subTask);

            // Go through each sub directory and file and copy it.
            int index = 1;
            foreach (string file in files)
            {
                if (Directory.Exists(file) == true)
                    CopyDirectoryWithProgress(file, to + Path.GetFileName(file));
                else
                {
                    _logStack.Push("Copying file \"" + file + "\"...");

                    // Check if its a script file which would mean we have to compile it.
                    if (file.ToLower().EndsWith(".fs") == true || file.ToLower().EndsWith(".fso") == true)
                    {
                        // See if we should compile it or not.
                        if (_compileScripts == true)
                        {
                            // Create a compile and compile the script.
                            ScriptCompiler compiler = new ScriptCompiler();
                            _logStack.Push("Compiling script \"" + file + "\"...");

                            // If there are any errors when compiling the script yell
                            // at the user.
                            string errorMessage = "";
                            bool showErrorMessage = false;
                            if (compiler.Compile(file, _compileFlags, _scriptDefineList, _scriptIncludePathList) > 0)
                            {
                                errorMessage = compiler.ErrorList.Count + " errors occured while compiling the script \""+file+"\" \n\n";
                                foreach (CompileError error in compiler.ErrorList)
                                {
                                    if (error.AlertLevel == ErrorAlertLevel.Error ||
                                        error.AlertLevel == ErrorAlertLevel.FatalError ||
                                        (error.AlertLevel == ErrorAlertLevel.Warning && _treatWarningsAsErrors == true) ||
                                        (error.AlertLevel == ErrorAlertLevel.Message && _treatMessagesAsErrors == true)
                                        ) showErrorMessage = true;
                                    errorMessage += error.ToString() + "\n";
                                }
                            }
                            if (showErrorMessage == true)
                            {
                                DebugLogger.WriteLog(errorMessage, LogAlertLevel.Error);
                                _logStack.Push(errorMessage);
                            }

                            // Dump the compiled byte code to the build directory.
                            if (showErrorMessage == false)
                                compiler.DumpExecutableFile(to + Path.GetFileName(file));
                        }

                        // Copy the source code if we have been told to keep it.
                        if (_keepScriptSource == true)
                            File.Copy(file, to + Path.GetFileName(file), true);
                    }

                    // Check if its a script script file.
                    else if (file.ToLower().EndsWith(".fsl") == true)
                    {
                        if (_keepScriptSource == true)
                            File.Copy(file, to + Path.GetFileName(file), true);
                    }

                    // Its a normal file so we can just ignore it.
                    else
                        File.Copy(file, to + Path.GetFileName(file), true);
                }

                _subTaskProgress = (int)(((float)index / (float)files.Length) * 100.0f);
                _subTask = "Copying directory: " + from;
            }
        }
コード例 #4
0
        /// <summary>
        ///		Inserts the current object into the map at the cursors position (or center-screen - 
        ///     - if this is not the active window) at the highest level on the scene graph
        /// </summary>
        private void InsertCurrentObject(bool inCenter, string overrideObjectURL)
        {
            string objectURL = overrideObjectURL != "" ? overrideObjectURL : _assetManagerWindow.SelectedObjectURL;
            EntityNode entity = null;

            // Keep a log of this insertion.
            DebugLogger.WriteLog("Inserting object of type '" + objectURL + "' into map");

            // Check the extension to see if this is a built-in object or not.
            if (objectURL.IndexOf(".fso") >= 0)
            {
                // Compile the script.
                ScriptCompiler compiler = new ScriptCompiler();
                bool errorOccured = false;
                string errorDescription = "\t";
                if (compiler.Compile(objectURL) > 0)
                    foreach (CompileError error in compiler.ErrorList)
                        if (error.AlertLevel == ErrorAlertLevel.Error || error.AlertLevel == ErrorAlertLevel.FatalError)
                        {
                            errorDescription += (errorDescription == "" ? "" : "\n\t") + error.ToString();
                            errorOccured = true;
                        }

                // If an error occured notify the user if not then
                // insert a new scripted entity into the map.
                if (errorOccured == true)
                {
                    MessageBox.Show("Unable to insert object into map, the following error(s) occured while attempt to compile this objects script.\n\n"+errorDescription,"Compile Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    DebugLogger.WriteLog("Object insertion aborted. The following error(s) occured while attempting to compile this objects script.\n\n" + errorDescription, LogAlertLevel.Warning);
                }
                else
                {
                    // Dump the compiled code into a memory stream.
                    MemoryStream memStream = new MemoryStream();
                    BinaryWriter writer = new BinaryWriter(memStream);
                    BinaryReader reader = new BinaryReader(memStream);
                    compiler.DumpExecutableFile(writer);
                    memStream.Position = 0;

                    // Create a new scripted entity with the given script attached to it.
                    ScriptedEntityNode scriptedEntity = new ScriptedEntityNode();
                    entity = scriptedEntity;
                    entity.RenderMode = EntityRenderMode.Rectangle;
                    entity.BoundingRectangle = new Rectangle(0, 0, 16, 16);
                    entity.Width = 16;
                    entity.Height = 16;
                    entity.Name = Path.GetFileNameWithoutExtension(objectURL);

                    ScriptProcess process = new ScriptProcess(VirtualMachine.GlobalInstance, reader);
                    process.Url = objectURL;
                    if (process.DefaultEditorState != null)
                        process.ChangeState(process.DefaultEditorState.Identifier);
                    else
                        process.State = null;
                    scriptedEntity.ScriptProcess = process;

                    // Are we allowed to place the entity?
                    bool canPlace = true;
                    string placeError = "This entity has been flagged as unplaceable. Please choose another or check this objects script.";
                    foreach (Define define in process.Defines)
                    {
                        switch (define.Ident.ToUpper())
                        {
                            case "UNPLACEABLE":
                                canPlace = false;
                                break;
                            case "UNPLACEABLE_ERROR":
                                placeError = define.Value;
                                break;
                        }
                    }
                    if (canPlace == false)
                    {
                        MessageBox.Show(placeError, "Unplaceable", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity);

                    // Invoke OnCreate event.
                    scriptedEntity.ScriptProcess[0].InvokeFunction("OnCreate", true, false);

                    // Free up the streams.
                    memStream.Close();
                    reader.Close();
                    writer.Close();
                }
            }

            // Its built in so create the object requested.
            else
            {
                switch (objectURL.ToLower())
                {
                    case "tilemap segment":
                        TilemapSegmentNode segment = new TilemapSegmentNode(8, 8, 16, 16);
                        Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(segment);
                        segment.IsGridVisible = true;
                        entity = segment;
                        break;

                    case "emitter":
                        entity = new EmitterNode();
                        Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity);
                        entity.BoundingRectangle = new Rectangle(0, 0, 16, 16);
                        entity.Width = 16;
                        entity.Height = 16;
                        break;

                    case "entity":
                        entity = new EntityNode();
                        Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity);
                        entity.BoundingRectangle = new Rectangle(0, 0, 16, 16);
                        entity.Width = 16;
                        entity.Height = 16;
                        break;

                    case "path marker":
                        entity = new PathMarkerNode();
                        Engine.Engine.GlobalInstance.Map.SceneGraph.RootNode.AddChild(entity);
                        entity.BoundingRectangle = new Rectangle(0, 0, 16, 16);
                        entity.Width = 16;
                        entity.Height = 16;
                        entity.Image = _pathMarkerImage;
                        entity.RenderMode = EntityRenderMode.Image;
                        entity.Name = "Path Marker " + MathMethods.Random(MathMethods.Random(0, 10000), MathMethods.Random(10000, 10000000));

                        foreach (EntityNode selEntity in _selectedEntityList)
                            if (selEntity is PathMarkerNode && ((PathMarkerNode)selEntity).NextNodeName == "")
                            {
                                ((PathMarkerNode)selEntity).NextNode = (PathMarkerNode)entity;
                                ((PathMarkerNode)selEntity).NextNodeName = entity.Name;
                            }

                        break;
                }
            }

            if (entity == null) return;

            // Find the correct position for our new entity.
            int mapX, mapY;
            if (inCenter == false)
            {
                mapX = (int)Editor.GlobalInstance.CameraNode.Transformation.X + (int)((mousePositionBeforeRightClick[0] / Editor.GlobalInstance.CameraNode.Zoom));
                mapY = (int)Editor.GlobalInstance.CameraNode.Transformation.Y + (int)((mousePositionBeforeRightClick[1] / Editor.GlobalInstance.CameraNode.Zoom));
            }
            else
            {
                mapX = (int)Editor.GlobalInstance.CameraNode.Transformation.X + (int)(((mapPanel.ClientSize.Width - entity.BoundingRectangle.Width) / 2) / Editor.GlobalInstance.CameraNode.Zoom);
                mapY = (int)Editor.GlobalInstance.CameraNode.Transformation.Y + (int)(((mapPanel.ClientSize.Height - entity.BoundingRectangle.Height) / 2) / Editor.GlobalInstance.CameraNode.Zoom);
            }

            if (_snapToGrid == true)
            {
                mapX = (mapX / _gridWidth) * _gridWidth;
                mapY = (mapY / _gridHeight) * _gridHeight;
            }

            entity.Position(mapX, mapY, 0.0f);
            entity.IsBoundingBoxVisible = _viewBoundingBoxs;
            entity.IsEventLinesVisible = _viewEventLines;
            entity.IsCollisionBoxVisible = _viewCollisionBoxs;
            entity.ForceVisibility = true;

            ClearSelection();
            AddEntityToSelection(entity);

            // Update the scene graph window if it exists.
            if (_sceneGraphWindow != null) _sceneGraphWindow.SyncronizeData();

            // Update this entitys event nodes and the event nodes of others.
            foreach (SceneNode node in Engine.Engine.GlobalInstance.Map.SceneGraph.EnumerateNodes())
            {
                EntityNode subNode = node as EntityNode;
                if (subNode == null) continue;
                if (subNode.Event.ToLower() == entity.Name.ToString().ToLower()) subNode.EventNodes.Add(entity);
            }

            PushUndoOperation(new InsertNodesUndoOperation(new SceneNode[] { entity }));
            SyncronizeWindow();

            _mapChangedSinceSave = true;
        }
コード例 #5
0
        /// <summary>
        ///		Compiles the given directory to the current pak file.
        /// </summary>
        /// <param name="from">Directory to compile.</param>
        private void CompileDirectoryToPak(string from)
        {
            // Retrieve all the files in the directory to be copied.
            string[] files = Directory.GetFileSystemEntries(from);

            if (from != Directory.GetCurrentDirectory() && from.ToLower().StartsWith(Directory.GetCurrentDirectory().ToLower()))
                from = from.Substring(Directory.GetCurrentDirectory().Length + 1);

            // Update the progress bar.
            _subTaskProgress = 0;
            _subTask = "Paking directory: " + from;
            _logStack.Push(_subTask);
            DebugLogger.WriteLog("Paking directory \"" + from + "\"...");

            // Go through each sub directory and file and copy it.
            int index = 1;
            foreach (string subFile in files)
            {
                string file = subFile;

                if (file.ToLower().StartsWith(Directory.GetCurrentDirectory().ToLower()))
                    file = file.Substring(Directory.GetCurrentDirectory().Length + 1);

                if (Directory.Exists(file) == true)
                    CompileDirectoryToPak(file);
                else
                {
                    DebugLogger.WriteLog("Paking file \"" + file + "\"...");
                    _logStack.Push("Paking file \"" + file + "\"...");

                    // Check if its a script file which would mean we have to compile it.
                    if (file.ToLower().EndsWith(".fso") == true || file.ToLower().EndsWith(".fs") == true)
                    {
                        // See if we should compile it or not.
                        if (_compileScripts == true)
                        {
                            // Create a compile and compile the script.
                            ScriptCompiler compiler = new ScriptCompiler();
                            DebugLogger.WriteLog("Compiling script \"" + file + "\"...");
                            _logStack.Push("Compiling script \"" + file + "\"...");

                            // If there are any errors when compiling the script yell
                            // at the user.
                            string errorMessage = "";
                            bool showErrorMessage = false;
                            if (compiler.Compile(file, _compileFlags, _scriptDefineList, _scriptIncludePathList) > 0)
                            {
                                errorMessage = compiler.ErrorList.Count + " errors occured while compiling the script \"" + file + "\" \n\n";
                                foreach (CompileError error in compiler.ErrorList)
                                {
                                    if (error.AlertLevel == ErrorAlertLevel.Error ||
                                        error.AlertLevel == ErrorAlertLevel.FatalError ||
                                        (error.AlertLevel == ErrorAlertLevel.Warning && _treatWarningsAsErrors == true) ||
                                        (error.AlertLevel == ErrorAlertLevel.Message && _treatMessagesAsErrors == true)
                                        ) showErrorMessage = true;
                                    errorMessage += error.ToString() + "\n";
                                }
                            }
                            if (showErrorMessage == true)
                            {
                                DebugLogger.WriteLog(errorMessage, LogAlertLevel.Error);
                                _logStack.Push(errorMessage);
                            }

                            // Dump the compiled byte code to a temporary folder and set its path
                            // as this files path.
                            if (showErrorMessage == false)
                            {
                                string tempFile = Path.GetTempFileName();
                                compiler.DumpExecutableFile(tempFile);
                                PakFile(tempFile, file);
                            }

                            // Copy the source code if we have been told to keep it.
                            if (_keepScriptSource == true)
                                PakFile(file, file + ".source");
                        }
                        else
                        {
                            PakFile(file, file);
                        }
                    }

                    // Check if its a library script file.
                    else if (file.ToLower().EndsWith(".fsl") == true)
                    {
                        if (_keepScriptSource == true)
                            PakFile(file, file);
                    }

                    // Its a normal file so pak it normally.
                    else
                        PakFile(file, file);
                }

                _subTaskProgress = (int)((100.0f / (float)files.Length) * index);
                _subTask = "Compiling directory: " + from;
            }
        }