226 lines
5.2 KiB
C#
226 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using Decal.Adapter.Wrappers;
|
|
|
|
namespace Decal.Adapter;
|
|
|
|
/// <summary>
|
|
/// Base class used to create Decal Plugins
|
|
/// </summary>
|
|
[CLSCompliant(true)]
|
|
public abstract class PluginBase : Extension, IViewHandler
|
|
{
|
|
private PluginHost myHost;
|
|
|
|
private EventHandler myGraphicsReset;
|
|
|
|
private BindingFlags myBindingFlags;
|
|
|
|
private Dictionary<string, ViewWrapper> myViews;
|
|
|
|
/// <summary>
|
|
/// Wrapper Object to the Host.
|
|
/// Similar to IPluginSite
|
|
/// </summary>
|
|
protected PluginHost Host => myHost;
|
|
|
|
/// <summary>
|
|
/// The Default view
|
|
/// </summary>
|
|
public ViewWrapper DefaultView => myViews["Default"];
|
|
|
|
/// <summary>
|
|
/// BindingFlags for internal scanning
|
|
/// </summary>
|
|
public BindingFlags BindingFlags => myBindingFlags;
|
|
|
|
[CLSCompliant(false)]
|
|
protected event EventHandler<NetworkMessageEventArgs> ServerDispatch
|
|
{
|
|
add
|
|
{
|
|
if (base.Core.EchoFilter != null)
|
|
{
|
|
base.Core.EchoFilter.ServerDispatch += value;
|
|
}
|
|
}
|
|
remove
|
|
{
|
|
if (base.Core.EchoFilter != null)
|
|
{
|
|
base.Core.EchoFilter.ServerDispatch -= value;
|
|
}
|
|
}
|
|
}
|
|
|
|
[CLSCompliant(false)]
|
|
protected event EventHandler<NetworkMessageEventArgs> ClientDispatch
|
|
{
|
|
add
|
|
{
|
|
if (base.Core.EchoFilter != null)
|
|
{
|
|
base.Core.EchoFilter.ClientDispatch += value;
|
|
}
|
|
}
|
|
remove
|
|
{
|
|
if (base.Core.EchoFilter != null)
|
|
{
|
|
base.Core.EchoFilter.ClientDispatch -= value;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected event EventHandler GraphicsReset
|
|
{
|
|
add
|
|
{
|
|
myGraphicsReset = (EventHandler)Delegate.Combine(myGraphicsReset, value);
|
|
if (myHost != null)
|
|
{
|
|
myHost.Render.DeviceLost += value;
|
|
}
|
|
}
|
|
remove
|
|
{
|
|
myGraphicsReset = (EventHandler)Delegate.Remove(myGraphicsReset, value);
|
|
if (myHost != null)
|
|
{
|
|
myHost.Render.DeviceLost -= value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Default Constructor for the Base class. Should be called by all decendants.
|
|
/// </summary>
|
|
protected PluginBase()
|
|
: base(DecalExtensionType.Plugin)
|
|
{
|
|
myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the base class to Wire Up events.
|
|
/// </summary>
|
|
internal override void Wireup()
|
|
{
|
|
if (myGraphicsReset != null)
|
|
{
|
|
Host.Render.DeviceLost += myGraphicsReset;
|
|
}
|
|
scanBaseEvents(connect: true);
|
|
myViews = new Dictionary<string, ViewWrapper>();
|
|
PluginHost.LoadViewHandler(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the base class to Unwire events
|
|
/// </summary>
|
|
internal override void UnWire()
|
|
{
|
|
if (myGraphicsReset != null)
|
|
{
|
|
Host.Render.DeviceLost -= myGraphicsReset;
|
|
}
|
|
scanBaseEvents(connect: false);
|
|
foreach (ViewWrapper value in myViews.Values)
|
|
{
|
|
value.Dispose();
|
|
}
|
|
myViews.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used for internal wiring up of base-class variables.
|
|
/// Called by PluginProxy
|
|
/// </summary>
|
|
/// <param name="newHost">Host (pluginsite) object</param>
|
|
internal void SetHost(PluginHost newHost)
|
|
{
|
|
myHost = newHost;
|
|
}
|
|
|
|
private void scanBaseEvents(bool connect)
|
|
{
|
|
Type type = GetType();
|
|
Type type2 = base.Core.GetType();
|
|
if (!Attribute.IsDefined(type, typeof(WireUpBaseEventsAttribute)))
|
|
{
|
|
return;
|
|
}
|
|
MethodInfo[] methods = type.GetMethods(BindingFlags);
|
|
foreach (MethodInfo methodInfo in methods)
|
|
{
|
|
if (!Attribute.IsDefined(methodInfo, typeof(BaseEventAttribute)))
|
|
{
|
|
continue;
|
|
}
|
|
Attribute[] customAttributes = Attribute.GetCustomAttributes(methodInfo, typeof(BaseEventAttribute));
|
|
for (int j = 0; j < customAttributes.Length; j++)
|
|
{
|
|
BaseEventAttribute baseEventAttribute = (BaseEventAttribute)customAttributes[j];
|
|
object obj;
|
|
Type type3;
|
|
if (baseEventAttribute.FilterName == string.Empty)
|
|
{
|
|
obj = this;
|
|
type3 = type;
|
|
}
|
|
else
|
|
{
|
|
PropertyInfo property = type2.GetProperty(baseEventAttribute.FilterName, BindingFlags.Instance | BindingFlags.Public);
|
|
if (property == null)
|
|
{
|
|
continue;
|
|
}
|
|
obj = property.GetValue(base.Core, null);
|
|
type3 = obj.GetType();
|
|
}
|
|
EventInfo eventInfo = null;
|
|
while ((eventInfo = type3.GetEvent(baseEventAttribute.EventName, BindingFlags)) == null && type3 == type)
|
|
{
|
|
type3 = type2;
|
|
obj = base.Core;
|
|
}
|
|
if (!(eventInfo == null))
|
|
{
|
|
if (connect)
|
|
{
|
|
eventInfo.GetAddMethod(nonPublic: true).Invoke(obj, new object[1] { Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo.Name) });
|
|
}
|
|
else
|
|
{
|
|
eventInfo.GetRemoveMethod(nonPublic: true).Invoke(obj, new object[1] { Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo.Name) });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads a new view into the internal list (should only be called internally)
|
|
/// </summary>
|
|
/// <param name="name">view name</param>
|
|
/// <param name="resource">resource path</param>
|
|
public void LoadView(string name, string resource)
|
|
{
|
|
myViews.Add(name, Host.LoadViewResource(resource, GetType().Assembly));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a view from the internal list
|
|
/// </summary>
|
|
/// <param name="name">view name</param>
|
|
/// <returns>the specified view or null</returns>
|
|
public ViewWrapper GetView(string name)
|
|
{
|
|
if (myViews.TryGetValue(name, out var value))
|
|
{
|
|
return value;
|
|
}
|
|
return null;
|
|
}
|
|
}
|