From 9511a8c76370f21e839114007dcd2b25c69b009a Mon Sep 17 00:00:00 2001 From: Tedd Hansen Date: Sat, 8 Nov 2008 17:35:48 +0000 Subject: Work in progress on SECS stuff. Have been holding it off until after 0.6 release. Still messy as hell and doesn't really work yet. Will undergo dramatic changes. AND MOST IMPORTANTLY: Will be conformed to work in coop with todays DNE and XEngine, hopefully one day providing a common interface for all components. --- .../ScriptEngine/ScriptEnginePlugin.cs | 134 +++++++++++++++++++-- 1 file changed, 123 insertions(+), 11 deletions(-) (limited to 'OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs') diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs b/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs index 32c7748..f81b848 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs +++ b/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs @@ -26,29 +26,143 @@ */ using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Text; +using System.Threading; +using OpenSim.ScriptEngine.Shared; using log4net; namespace OpenSim.ApplicationPlugins.ScriptEngine { + /// + /// Loads all Script Engine Components + /// public class ScriptEnginePlugin : IApplicationPlugin { internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); internal OpenSimBase m_OpenSim; - private ComponentLoader pluginLoader; + + // Component providers are registered here wit a name (string) + // When a script engine is created the components are instanciated + public static Dictionary providers = new Dictionary(); + public static Dictionary scriptEngines = new Dictionary(); + + + public ScriptEnginePlugin() + { + // Application startup +#if DEBUG + m_log.InfoFormat("[{0}] ##################################", Name); + m_log.InfoFormat("[{0}] # Script Engine Component System #", Name); + m_log.InfoFormat("[{0}] ##################################", Name); +#else + m_log.InfoFormat("[{0}] Script Engine Component System", Name); +#endif + + // Load all modules from current directory + // We only want files named OpenSim.ScriptEngine.*.dll + Load(".", "OpenSim.ScriptEngine.*.dll"); + } public void Initialise(OpenSimBase openSim) { + // Our objective: Load component .dll's m_OpenSim = openSim; - pluginLoader = new ComponentLoader(this); + //m_OpenSim.Shutdown(); + } + + private readonly static string nameIScriptEngineComponent = typeof(IScriptEngineComponent).Name; // keep interface name in managed code + private readonly static string nameIScriptEngine = typeof(IScriptEngine).Name; // keep interface name in managed code + /// + /// Load components from directory + /// + /// + public void Load(string directory, string filter) + { + // We may want to change how this functions as currently it required unique class names for each component + + foreach (string file in Directory.GetFiles(directory, filter)) + { + //m_log.DebugFormat("[ScriptEngine]: Loading: [{0}].", file); + Assembly componentAssembly = null; + try + { + componentAssembly = Assembly.LoadFrom(file); + } catch (Exception e) + { + m_log.ErrorFormat("[{0}] Error loading: \"{1}\".", Name, file); + } + if (componentAssembly != null) + { + try + { + // Go through all types in the assembly + foreach (Type componentType in componentAssembly.GetTypes()) + { + if (componentType.IsPublic + && !componentType.IsAbstract) + { + //if (componentType.IsSubclassOf(typeof(ComponentBase))) + if (componentType.GetInterface(nameIScriptEngineComponent) != null) + { + // We have found an type which is derived from ProdiverBase, add it to provider list + m_log.InfoFormat("[{0}] Adding component: {1}", Name, componentType.Name); + lock (providers) + { + providers.Add(componentType.Name, componentType); + } + } + //if (componentType.IsSubclassOf(typeof(ScriptEngineBase))) + if (componentType.GetInterface(nameIScriptEngine) != null) + { + // We have found an type which is derived from RegionScriptEngineBase, add it to engine list + m_log.InfoFormat("[{0}] Adding script engine: {1}", Name, componentType.Name); + lock (scriptEngines) + { + scriptEngines.Add(componentType.Name, componentType); + } + } + } + } + } + catch + (ReflectionTypeLoadException re) + { + m_log.ErrorFormat("[{0}] Could not load component \"{1}\": {2}", Name, componentAssembly.FullName, re.ToString()); + int c = 0; + foreach (Exception e in re.LoaderExceptions) + { + c++; + m_log.ErrorFormat("[{0}] LoaderException {1}: {2}", Name, c, e.ToString()); + } + } + } //if + } //foreach + } + + public static IScriptEngineComponent GetComponentInstance(string name, params Object[] args) + { + if (!providers.ContainsKey(name)) + throw new Exception("ScriptEngine requested component named \"" + name + + "\" that does not exist."); - m_log.Info("[" + Name + "]: Script Engine Component System"); - m_log.Info("[" + Name + "]: Loading Script Engine Components"); - pluginLoader.Load("ScriptEngines"); - + return Activator.CreateInstance(providers[name], args) as IScriptEngineComponent; } + + private readonly static string nameIScriptEngineRegionComponent = typeof(IScriptEngineRegionComponent).Name; // keep interface name in managed code + public static IScriptEngineComponent GetComponentInstance(RegionInfoStructure info, string name, params Object[] args) + { + IScriptEngineComponent c = GetComponentInstance(name, args); + + // If module is IScriptEngineRegionComponent then it will have one instance per region and we will initialize it + if (c.GetType().GetInterface(nameIScriptEngineRegionComponent) != null) + ((IScriptEngineRegionComponent)c).Initialize(info); + + return c; + } + #region IApplicationPlugin stuff /// /// Returns the plugin version @@ -65,16 +179,13 @@ namespace OpenSim.ApplicationPlugins.ScriptEngine /// Plugin name, eg MySQL User Provider public string Name { - get { return "ScriptEngine"; } + get { return "SECS"; } } /// /// Default-initialises the plugin /// - public void Initialise() - { - //throw new NotImplementedException(); - } + public void Initialise() { } /// ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. @@ -85,5 +196,6 @@ namespace OpenSim.ApplicationPlugins.ScriptEngine //throw new NotImplementedException(); } #endregion + } } -- cgit v1.1