- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXGfxLib/ScriptManager.cs

Go to the documentation of this file.

    00001 //BSD License
    00002 //DXGfx® - http://www.eteractions.com
    00003 //Copyright (c) 2005
    00004 //by Guillaume Randon
    00005 //Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    00006 //and associated documentation files (the "Software"), to deal in the Software without restriction,
    00007 //including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00008 //and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    00009 //subject to the following conditions:
    00010 //The above copyright notice and this permission notice shall be included in all copies or substantial
    00011 //portions of the Software.
    00012 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    00013 //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
    00014 //AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    00015 //DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00016 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00017 using System;
    00018 using System.Collections;
    00019 using System.Collections.Generic;
    00020 using System.Text;
    00021 using System.IO;
    00022 using System.Reflection;
    00023 using Microsoft.CSharp;
    00024 using System.CodeDom.Compiler;
    00025
    00026 namespace DXGfxLib
    00027 {
    00040     public class ScriptManager
    00041     {
    00045         private Hashtable scripts = null;
    00046
    00050         private string[] referencedAssemblies = null;
    00051
    00055         private static ScriptManager globalInstance = null;
    00056
    00060         private Assembly scriptsAssembly = null;
    00061
    00065         public bool scriptsAreReady = false;
    00066
    00070         public string lastCompilationErrorMessage = "";
    00071
    00076         public ScriptManager()
    00077         {
    00078             if (globalInstance != null)
    00079             {
    00080                 throw new Exception("There is already one scriptManager we don't expect to have several active at the same time!");
    00081             }
    00082             else
    00083             {
    00084                 globalInstance = this;
    00085             }
    00086             scripts = new Hashtable();
    00087             BuildReferences();
    00088         }
    00089
    00093         public void Dispose()
    00094         {
    00095             globalInstance = null;
    00096         }
    00097
    00102         public static ScriptManager GetGlobalInstance()
    00103         {
    00104             if (globalInstance == null)
    00105             {
    00106                 throw new Exception("There is no scriptManager!");
    00107             }
    00108             return globalInstance;
    00109         }
    00110
    00117         public void RegisterScript(Script script)
    00118         {
    00119             if (!scripts.Contains(script.name))
    00120             {
    00121                 scripts.Add(script.name, script);
    00122             }
    00123         }
    00124
    00129         public void ScriptUpdated(Script script)
    00130         {
    00131             RegisterScript(script);
    00132             scriptsAreReady = false;
    00133         }
    00134
    00139         public void UnRegisterScript(Script script)
    00140         {
    00141             scripts.Remove(script.name);
    00142         }
    00143
    00147         public void GetReady()
    00148         {
    00149             if (!scriptsAreReady)
    00150             {
    00151                 if (scriptsAssembly != null)
    00152                 {
    00153                     // It is still not possible to unload an assembly.
    00154                     // Putting the assembly in a different appdomain to unload it requires a lot of additional work.
    00155                     // We do nothing here for now.
    00156                 }
    00157                 lastCompilationErrorMessage = "";
    00158                 scriptsAssembly = Compile(ref lastCompilationErrorMessage);
    00159             }
    00160         }
    00161
    00167         public Assembly Compile(ref string errors)
    00168         {
    00169             // Obtains in-memory running instance of the C# compiler
    00170             CSharpCodeProvider csc = new CSharpCodeProvider();
    00171             ICodeCompiler icc = csc.CreateCompiler();
    00172
    00173             // Set input params for the compiler
    00174             CompilerParameters co = new CompilerParameters();
    00175
    00176
    00177             foreach (string referencedAssembly in referencedAssemblies)
    00178             {
    00179                 co.ReferencedAssemblies.Add(referencedAssembly);
    00180             }
    00181
    00182             IDictionaryEnumerator scriptEnum = scripts.GetEnumerator();
    00183             string[] sources = new string[scripts.Count];
    00184             int count = 0;
    00185
    00186             string tempScriptsFolderName = "tmpScripts";
    00187             while (scriptEnum.MoveNext())
    00188             {
    00189                 Script script = scriptEnum.Value as Script;
    00190                 if (script != null)
    00191                 {
    00192                     if (!Directory.Exists(tempScriptsFolderName))
    00193                     {
    00194                         Directory.CreateDirectory(tempScriptsFolderName);
    00195                     }
    00196                     string csFileName = tempScriptsFolderName + "\\" + StringUtil.GetName(script.fileName);
    00197                     File.WriteAllText(csFileName, script.GetSrcForCompilation());
    00198                     sources[count] = csFileName;
    00199                     // We do recompile our script assembly so we need to reset all scripts
    00200                     // as references to current instances of derived class are going to be invalid.
    00201                     script.Reset();
    00202                     count++;
    00203                 }
    00204                 else
    00205                 {
    00206                     throw new Exception("Scripts Hashtable is corrupted!");
    00207                 }
    00208             }
    00209
    00210             co.GenerateInMemory = true;
    00211
    00212             // Run the compiling process
    00213             CompilerResults results = icc.CompileAssemblyFromFileBatch(co, sources);
    00214
    00215             if (results.Errors.HasErrors)
    00216             {
    00217                 scriptsAreReady = false;
    00218
    00219                 foreach (CompilerError error in results.Errors)
    00220                 {
    00221                     errors = errors + error.ErrorNumber + " " + error.ErrorText + " " + error.FileName + " " + error.Line + "\n";
    00222                 }
    00223
    00224                 return null;
    00225             }
    00226             else
    00227             {
    00228                 errors = "Compilation Ok";
    00229                 scriptsAreReady = true;
    00230             }
    00231
    00232             return results.CompiledAssembly;
    00233         }
    00234
    00238         public void BuildReferences()
    00239         {
    00240             string managedDirect3DXPath = Environment.GetEnvironmentVariable("windir") + @"\Microsoft.NET\DirectX for Managed Code\1.0.2911.0\";
    00241             string managedDirect3DPath = Environment.GetEnvironmentVariable("windir") + @"\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\";
    00242
    00243             string binFolder = AppDomain.CurrentDomain.BaseDirectory;
    00244
    00245             referencedAssemblies = new string[] {"system.dll", "system.data.dll", "system.drawing.dll",
    00246                 "system.windows.forms.dll", "system.xml.dll",
    00247                 binFolder + "DXCommon.dll",
    00248                 binFolder + "DXGfxLib.dll",
    00249                 managedDirect3DPath + "Microsoft.DirectX.dll",
    00250                 managedDirect3DPath + "Microsoft.DirectX.Direct3D.dll",
    00251                 managedDirect3DXPath + "Microsoft.DirectX.Direct3DX.dll",
    00252                 managedDirect3DPath + "Microsoft.DirectX.DirectInput.dll"};
    00253         }
    00254
    00259         public string[] GetReferences()
    00260         {
    00261             return referencedAssemblies;
    00262         }
    00263
    00268         public void SetReferences(string[] references)
    00269         {
    00270             referencedAssemblies = references;
    00271         }
    00272
    00279         public ExecutableBlock GetNewExecutableBlock(string name)
    00280         {
    00281             Type desiredType = scriptsAssembly.GetType("DXGfxLib." + name);
    00282             ConstructorInfo ctor = desiredType.GetConstructor(new Type[] { });
    00283             Object[] args = new Object[] { };
    00284             Object obj = ctor.Invoke(args);
    00285
    00286             ExecutableBlock newExecutableBlock = obj as ExecutableBlock;
    00287
    00288             if (newExecutableBlock == null)
    00289             {
    00290                 throw new Exception("Type doesn't derive from ExecutableBlock this is terribly wrong!!");
    00291             }
    00292
    00293             return newExecutableBlock;
    00294         }
    00295     }
    00296 }