Mantis#1591. Thank you graciously, Sempuki for a patch that:

Currently module loading is done ad-hoc. I propose creating a simple 
loader class that leverages Mono.Addins (and perhaps the new .NET 
addins when they become available in mono). Attached is a basic 
patch for review that compiles into HEAD, but doesn't yet replace 
any existing ad-hoc loaders.
0.6.0-stable
Charles Krinke 2008-06-27 02:15:57 +00:00
parent 176efe3f06
commit ca8d1d57e1
19 changed files with 244 additions and 64 deletions

View File

@ -46,6 +46,19 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
#region IApplicationPlugin Members
// TODO: required by IPlugin, but likely not at all right
string m_name = "LoadRegionsPlugin";
string m_version = "0.0";
public string Version { get { return m_version; } }
public string Name { get { return m_name; } }
public void Initialise()
{
m_log.Info("[LOADREGIONS]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException (Name);
}
public void Initialise(OpenSimBase openSim)
{
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
@ -78,7 +91,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
openSim.ModuleLoader.ClearCache();
}
public void Close()
public void Dispose()
{
}

View File

@ -54,6 +54,19 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private BaseHttpServer m_httpd;
private string requiredPassword = String.Empty;
// TODO: required by IPlugin, but likely not at all right
string m_name = "RemoteAdminPlugin";
string m_version = "0.0";
public string Version { get { return m_version; } }
public string Name { get { return m_name; } }
public void Initialise()
{
m_log.Info("[RADMIN]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException (Name);
}
public void Initialise(OpenSimBase openSim)
{
try
@ -607,7 +620,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
return response;
}
public void Close()
public void Dispose()
{
}
}

View File

@ -188,6 +188,17 @@ namespace OpenSim.ApplicationPlugins.Rest
#region methods
// TODO: required by IPlugin, but likely not at all right
string m_version = "0.0";
public string Version { get { return m_version; } }
public void Initialise()
{
m_log.Info("[RESTPLUGIN]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException (Name);
}
/// <summary>
/// This method is called by OpenSimMain immediately after loading the
/// plugin and after basic server setup, but before running any server commands.
@ -357,6 +368,11 @@ namespace OpenSim.ApplicationPlugins.Rest
_agents = null;
}
public virtual void Dispose()
{
Close();
}
/// <summary>
/// Return a failure message.
/// </summary>

View File

@ -42,5 +42,6 @@ namespace OpenSim.Data
public abstract string Name { get; }
public abstract void Initialise(string connect);
public abstract void Initialise();
public abstract void Dispose();
}
}

View File

@ -218,6 +218,8 @@ namespace OpenSim.Data.MSSQL
#region IPlugin Members
override public void Dispose() { }
/// <summary>
/// <para>Initialises asset interface</para>
/// <para>

View File

@ -39,7 +39,7 @@ namespace OpenSim.Data.MySQL
/// <summary>
/// A MySQL Interface for the Asset Server
/// </summary>
internal class MySQLAssetData : AssetDataBase, IPlugin
internal class MySQLAssetData : AssetDataBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -109,6 +109,8 @@ namespace OpenSim.Data.MySQL
}
override public void Dispose() { }
#region IAssetProvider Members
/// <summary>

View File

@ -43,7 +43,7 @@ namespace OpenSim.Data.NHibernate
/// <summary>
/// A User storage interface for the DB4o database system
/// </summary>
public class NHibernateAssetData : AssetDataBase, IDisposable
public class NHibernateAssetData : AssetDataBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -51,6 +51,8 @@ namespace OpenSim.Data.NHibernate
private ISessionFactory factory;
private ISession session;
override public void Dispose() { }
public override void Initialise()
{
Initialise("SQLiteDialect;SqliteClientDriver;URI=file:Asset.db,version=3");
@ -173,9 +175,5 @@ namespace OpenSim.Data.NHibernate
get { return "0.1"; }
}
public void Dispose()
{
}
}
}

View File

@ -56,6 +56,8 @@ namespace OpenSim.Data.SQLite
private SqliteConnection m_conn;
override public void Dispose() { }
/// <summary>
/// <list type="bullet">
/// <item>Initialises AssetData interface</item>

View File

@ -25,12 +25,24 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim.Framework
{
/// <summary>
/// Exception thrown if Initialise has been called, but failed.
/// </summary>
public class PluginNotInitialisedException : Exception
{
public PluginNotInitialisedException () : base() {}
public PluginNotInitialisedException (string msg) : base(msg) {}
public PluginNotInitialisedException (string msg, Exception e) : base(msg, e) {}
}
/// <summary>
/// This interface, describes a generic plugin
/// </summary>
public interface IPlugin
public interface IPlugin : System.IDisposable
{
/// <summary>
/// Returns the plugin version
@ -45,7 +57,7 @@ namespace OpenSim.Framework
string Name { get; }
/// <summary>
/// Initialises the plugin (artificial constructor)
/// Default-initialises the plugin
/// </summary>
void Initialise();
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Mono.Addins;
namespace OpenSim.Framework
{
public class PluginLoader <T> : IDisposable where T : IPlugin
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<T> loaded = new List<T>();
public PluginLoader (string dir)
{
AddPluginDir (dir);
}
public void AddPluginDir (string dir)
{
suppress_console_output_ (true);
AddinManager.Initialize (dir);
suppress_console_output_ (false);
}
public delegate void Initialiser (IPlugin p);
private void default_initialiser_ (IPlugin p) { p.Initialise(); }
public void Load (string extpoint)
{
Load (extpoint, default_initialiser_);
}
public void Load (string extpoint, Initialiser initialize)
{
AddinManager.Registry.Update (null);
ExtensionNodeList ns = AddinManager.GetExtensionNodes(extpoint);
foreach (TypeExtensionNode n in ns)
{
T p = (T) n.CreateInstance();
initialize (p);
Plugins.Add (p);
log.Info("[PLUGINS]: Loading plugin " + n.Path + "/" + p.Name);
}
}
public List<T> Plugins
{
get { return loaded; }
}
public void Dispose ()
{
foreach (T p in Plugins)
p.Dispose ();
}
public void ClearCache()
{
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0) occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup
if (Directory.Exists("addin-db-000"))
Directory.Delete("addin-db-000", true);
if (Directory.Exists("addin-db-001"))
Directory.Delete("addin-db-001", true);
}
private static TextWriter prev_console_;
public void suppress_console_output_ (bool save)
{
if (save)
{
prev_console_ = System.Console.Out;
System.Console.SetOut(new StreamWriter(Stream.Null));
}
else
{
if (prev_console_ != null)
System.Console.SetOut(prev_console_);
}
}
}
}

View File

@ -116,26 +116,17 @@ namespace OpenSim.Grid.GridServer
m_httpServer.AddStreamHandler(new RestStreamHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod));
}
protected void grid_plugin_initialiser_ (IPlugin plugin)
{
IGridPlugin p = plugin as IGridPlugin;
p.Initialise (this);
}
protected void LoadGridPlugins()
{
// Temporary hack to stop mono-addins scanning warnings from coming out on the console
TextWriter oldOutput = Console.Out;
Console.SetOut(new StreamWriter(Stream.Null));
AddinManager.Initialize(".");
AddinManager.Registry.Update(null);
// Returns the console.writelines back to the console's stream
Console.SetOut(oldOutput);
ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/GridServer");
foreach (TypeExtensionNode node in nodes)
{
m_log.Info("[GRID PLUGINS]: Loading OpenSim plugin " + node.Path);
IGridPlugin plugin = (IGridPlugin)node.CreateInstance();
plugin.Initialise(this);
m_plugins.Add(plugin);
}
PluginLoader<IGridPlugin> loader = new PluginLoader<IGridPlugin> (".");
loader.Load ("/OpenSim/GridServer", grid_plugin_initialiser_);
m_plugins = loader.Plugins;
}
protected virtual void SetupGridManager()

View File

@ -27,13 +27,14 @@
*/
using Mono.Addins;
using OpenSim.Framework;
[assembly : AddinRoot("OpenSim", "0.5")]
namespace OpenSim.Grid.GridServer
{
[TypeExtensionPoint("/OpenSim/GridServer")]
public interface IGridPlugin
public interface IGridPlugin : IPlugin
{
void Initialise(GridServerBase gridServer);
void Close();

View File

@ -26,15 +26,15 @@
*/
using Mono.Addins;
using OpenSim.Framework;
[assembly : AddinRoot("OpenSim", "0.5")]
namespace OpenSim
{
[TypeExtensionPoint("/OpenSim/Startup")]
public interface IApplicationPlugin
public interface IApplicationPlugin : IPlugin
{
void Initialise(OpenSimBase openSim);
void Close();
}
}

View File

@ -149,24 +149,6 @@ namespace OpenSim
{
IConfig startupConfig = configSource.Configs["Startup"];
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0) occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup
if (Directory.Exists("addin-db-000"))
Directory.Delete("addin-db-000", true);
if (Directory.Exists("addin-db-001"))
Directory.Delete("addin-db-001", true);
// This blocks the scanning warnings from outputing to the console.
TextWriter oldOutput = Console.Out;
Console.SetOut(new StreamWriter(Stream.Null));
AddinManager.Initialize(".");
AddinManager.Registry.Update(null);
// Returns the console.writelines back to the console's stream
Console.SetOut(oldOutput);
Application.iniFilePath = startupConfig.GetString("inifile", "OpenSim.ini");
m_config = new OpenSimConfigSource();
@ -347,6 +329,19 @@ namespace OpenSim
m_networkServersInfo.loadFromConfiguration(m_config.Source);
}
protected void plugin_initialiser_ (IPlugin plugin)
{
IApplicationPlugin p = plugin as IApplicationPlugin;
p.Initialise (this);
}
protected void LoadPlugins()
{
PluginLoader<IApplicationPlugin> loader = new PluginLoader<IApplicationPlugin> (".");
loader.Load ("/OpenSim/Startup", plugin_initialiser_);
m_plugins = loader.Plugins;
}
/// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary>
@ -403,14 +398,7 @@ namespace OpenSim
// Create a ModuleLoader instance
m_moduleLoader = new ModuleLoader(m_config.Source);
ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup");
foreach (TypeExtensionNode node in nodes)
{
m_log.InfoFormat("[PLUGINS]: Loading OpenSim application plugin {0}", node.Path);
IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance();
plugin.Initialise(this);
m_plugins.Add(plugin);
}
LoadPlugins();
}
protected override void Initialize()
@ -740,3 +728,4 @@ namespace OpenSim
}
}

View File

@ -74,6 +74,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
private List<IClientNetworkServer> m_clientServers;
#region IApplicationPlugin Members
// TODO: required by IPlugin, but likely not at all right
string m_name = "LoadBalancerPlugin";
string m_version = "0.0";
public string Version { get { return m_version; } }
public string Name { get { return m_name; } }
public void Initialise()
{
m_log.Info("[BALANCER]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException (Name);
}
public void Initialise(OpenSimBase openSim)
{
@ -109,7 +121,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
m_log.Info("[BALANCER] " + "Exiting Initialize()");
}
public void Close()
public void Dispose()
{
}

View File

@ -68,6 +68,18 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
private ProxyServer proxy;
#region IApplicationPlugin Members
// TODO: required by IPlugin, but likely not at all right
string m_name = "RegionProxyPlugin";
string m_version = "0.0";
public string Version { get { return m_version; } }
public string Name { get { return m_name; } }
public void Initialise()
{
m_log.Info("[PROXY]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException (Name);
}
public void Initialise(OpenSimBase openSim)
{
@ -89,7 +101,7 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
proxy = new ProxyServer(m_log);
}
public void Close()
public void Dispose()
{
}

View File

@ -95,6 +95,7 @@
<Reference name="OpenSim.Framework.Console"/>
<Reference name="Nini.dll" />
<Reference name="log4net.dll"/>
<Reference name="Mono.Addins.dll" />
<Files>
<Match pattern="*.cs" recurse="false"/>
</Files>