How to specify plug-ins (Pluggable Vs. Non-Pluggable)

Coden relies on properly translating functions and classes from .NET assemblies into plug-ins compatible with these host applications. To allow this translation to happen the developer needs to specify exactly which .NET assemblies are meant to be pluggable (translatable). There are two main ways to do so and this document describes exactly how.

The Coden mechanism scans an assembly and picks out publicly defined classes and functions that fit certain criteria. For example, a function taking a Vector2 typed parameter producing a Color will be assumed to be a texture generator. Or a class derived from PolygonMesh3 that has another PolygonMesh3-typed (first) parameter will be assumed to be a mesh modifier. A typical plug-in assembly, however, will most likely have more classes and functions fitting such criteria which are not meant to be pluggable. These, for example, may be utility functions.

Using Ephere.Modeling library to define pluggable entities

Once referenced, Ephere.Modeling.dll library contains Ephere.Modeling.Attributes namespace which defines a number of attributes useful for adding meta data to your plug-ins. The attribute you can use to expose your functions and classes as plug-ins is Ephere.Modeling.Attributes.PluggableAttribute. To use it simply add the Pluggable attribute to a class or function definition meant to be a plug-in. Note that you must also specify a "plugin" tag inside the Pluggable attribute.

Alternatively you may add this attribute to the whole assembly to mark all entities within it as pluggable by default. Following are the rules for using the Pluggable attribute for marking entities as pluggable:

  • Coden will scan all classes and functions in an assembly that has a global Ephere.Modeling.Attributes.PluggableAttribute

    For example:
    // Marks whole assembly as pluggable
    [assembly: Ephere.Modeling.Attributes.Pluggable( Tags = "plugin" )]
     
    public static partial class MyPlugins
    {
    	// Will be a plugin
    	public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
    	{
    		return new PolygonMesh3();
    	}
     
    	// Will be a plugin
    	public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
    	{
    		return GenerateMesh( width, height, flag );
    	}
    }

  • Coden will ignore all non-public functions and classes

    For example, if you have a private method and a public method like example below, Coden will only detect MyMeshGenerator function and will ignore GenerateMesh method:
    // Will be ignored (because it is private)
    private PolygonMesh3 GenerateMesh( float width, float height, bool flag )
    {
    	return new PolygonMesh3();
    }
     
    // Will be a plugin
    public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
    {
    	return GenerateMesh( width, height, flag );
    }
  • Coden will skip all classes and functions that have Ephere.Modeling.Attributes.IgnoredAttribute

    The following will behave just like the example above:
    // Will be ignored (ignored attribute)
    [Ignored]
    public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
    {
    	return new PolygonMesh3();
    }
     
    // Will be a plug-in (if Pluggable attribute is defined at assembly level)
    public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
    {
    	return GenerateMesh( width, height, flag );
    }
  • If Ephere.Modeling.Attributes.PluggableAttribute with a "plugin" tag is not defined at an assembly level it will only include classes and functions that have Ephere.Modeling.Attributes.PluggableAttribute with a "plugin" tag defined

    The following will behave just like the example above:
    // Will be ignored (if Pluggable attribute is not defined at assembly level)
    public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
    {
    	return new PolygonMesh3();
    }
     
    // Will be a plug-in
    [Pluggable( Tags = "plug-in" )]
    public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
    {
    	return GenerateMesh( width, height, flag );
    }

Using a meta assembly file

To specify meta information about assemblies without using Ephere.Modeling.dll assembly within them you can create an external meta assembly (.maxml extension) file and specify pluggable entities in it. This may be useful if you did not write the assembly containing pluggable methods (for example, you may create a meta assembly for a built-in .NET library like System.Math.dll) or if you cannot reference Ephere.Modeling assembly for some other reason.

Meta assemblies are XML files with .maxml extension and residing in the same directory as the binary .NET dlls used by Coden. This is typically the C:\Users\USERNAME\AppData\Local\Ephere\Library\bin directory. To create a new meta assembly which specifies pluggable types simply create a new XML file, for example, MyAssembly.maxml and follow this format:

<?xml version="1.0" encoding="utf-8" ?>
<MetaAssembly Name="Binary.Assembly.Name" xmlns="http://www.ephere.com/modeling/dependency/metaassembly.xsd">
	<Pluggable Type="MyNamespace.MyPluginClass"/>
	<Pluggable Type="MyNamespace.MyPluginFunctions" Function="PluginFunctionName"/>
</MetaAssembly>

The meta assembly above defines two plug-ins existing in Binary.Assembly.Name.dll file, present inside the same directory as the above meta assembly file. First plug-in is a class MyPluginClass located inside MyNamespace namespace. Second plugin is a function named PluginFunctionName defined inside MyPluginFunctions class located inside MyNamespace namespace.

And voila, it is that simple to specify plug-ins for Coden!