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 #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) public void Initialise(OpenSimBase openSim)
{ {
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised"); m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
@ -78,7 +91,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
openSim.ModuleLoader.ClearCache(); openSim.ModuleLoader.ClearCache();
} }
public void Close() public void Dispose()
{ {
} }

View File

@ -54,6 +54,19 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private BaseHttpServer m_httpd; private BaseHttpServer m_httpd;
private string requiredPassword = String.Empty; 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) public void Initialise(OpenSimBase openSim)
{ {
try try
@ -607,7 +620,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
return response; return response;
} }
public void Close() public void Dispose()
{ {
} }
} }

View File

@ -188,6 +188,17 @@ namespace OpenSim.ApplicationPlugins.Rest
#region methods #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> /// <summary>
/// This method is called by OpenSimMain immediately after loading the /// This method is called by OpenSimMain immediately after loading the
/// plugin and after basic server setup, but before running any server commands. /// plugin and after basic server setup, but before running any server commands.
@ -357,6 +368,11 @@ namespace OpenSim.ApplicationPlugins.Rest
_agents = null; _agents = null;
} }
public virtual void Dispose()
{
Close();
}
/// <summary> /// <summary>
/// Return a failure message. /// Return a failure message.
/// </summary> /// </summary>

View File

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

View File

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

View File

@ -39,7 +39,7 @@ namespace OpenSim.Data.MySQL
/// <summary> /// <summary>
/// A MySQL Interface for the Asset Server /// A MySQL Interface for the Asset Server
/// </summary> /// </summary>
internal class MySQLAssetData : AssetDataBase, IPlugin internal class MySQLAssetData : AssetDataBase
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 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 #region IAssetProvider Members
/// <summary> /// <summary>

View File

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

View File

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

View File

@ -25,12 +25,24 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
namespace OpenSim.Framework 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> /// <summary>
/// This interface, describes a generic plugin /// This interface, describes a generic plugin
/// </summary> /// </summary>
public interface IPlugin public interface IPlugin : System.IDisposable
{ {
/// <summary> /// <summary>
/// Returns the plugin version /// Returns the plugin version
@ -45,7 +57,7 @@ namespace OpenSim.Framework
string Name { get; } string Name { get; }
/// <summary> /// <summary>
/// Initialises the plugin (artificial constructor) /// Default-initialises the plugin
/// </summary> /// </summary>
void Initialise(); 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)); 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() protected void LoadGridPlugins()
{ {
// Temporary hack to stop mono-addins scanning warnings from coming out on the console PluginLoader<IGridPlugin> loader = new PluginLoader<IGridPlugin> (".");
TextWriter oldOutput = Console.Out; loader.Load ("/OpenSim/GridServer", grid_plugin_initialiser_);
Console.SetOut(new StreamWriter(Stream.Null)); m_plugins = loader.Plugins;
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);
}
} }
protected virtual void SetupGridManager() protected virtual void SetupGridManager()

View File

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

View File

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

View File

@ -149,24 +149,6 @@ namespace OpenSim
{ {
IConfig startupConfig = configSource.Configs["Startup"]; 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"); Application.iniFilePath = startupConfig.GetString("inifile", "OpenSim.ini");
m_config = new OpenSimConfigSource(); m_config = new OpenSimConfigSource();
@ -347,6 +329,19 @@ namespace OpenSim
m_networkServersInfo.loadFromConfiguration(m_config.Source); 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> /// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk. /// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary> /// </summary>
@ -403,14 +398,7 @@ namespace OpenSim
// Create a ModuleLoader instance // Create a ModuleLoader instance
m_moduleLoader = new ModuleLoader(m_config.Source); m_moduleLoader = new ModuleLoader(m_config.Source);
ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup"); LoadPlugins();
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);
}
} }
protected override void Initialize() 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; private List<IClientNetworkServer> m_clientServers;
#region IApplicationPlugin Members #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) public void Initialise(OpenSimBase openSim)
{ {
@ -109,7 +121,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
m_log.Info("[BALANCER] " + "Exiting Initialize()"); 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; private ProxyServer proxy;
#region IApplicationPlugin Members #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) public void Initialise(OpenSimBase openSim)
{ {
@ -89,7 +101,7 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
proxy = new ProxyServer(m_log); proxy = new ProxyServer(m_log);
} }
public void Close() public void Dispose()
{ {
} }

View File

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