NERvDN Library  0.2.0.20160420-0019
NERvLibrary - Nerve Gear Developer Network
Writing A Minimal Plugin

This tutorial will show you how to write a minimal plug-in for SAO Utils with the just-fit and completed codes. You can also find all the details and hints after the sample codes.

The completed project is located in the samples\Plug-in Demo folder.

All Codes in A CPP File

I would like to start with one single CPP with all the source codes for a minimal completed plug-in to show you how simple it is to write a plug-in for SAO Utils.

#include <NERvGear/plugin.h>
#include <NERvGear/NERvSDK.h>
using namespace NERvGear;
class PluginDemo : public PluginImpl {
public:
// implementation of IPlugin
virtual long NVG_METHOD OnInitial()
{
NERvLogInfo(NVG_TEXT("PluginDemo"), NVG_TEXT("OnInitial()"));
return PluginImpl::OnInitial();
}
virtual long NVG_METHOD OnReady()
{
NERvLogInfo(NVG_TEXT("PluginDemo"), NVG_TEXT("Welcome to Sword Art Online!"));
return PluginImpl::OnReady();
}
virtual long NVG_METHOD OnRelease()
{
NERvLogInfo(NVG_TEXT("PluginDemo"), NVG_TEXT("OnRelease()"));
return PluginImpl::OnRelease();
}
NVG_DECLARE_PLUGIN(PluginDemo)
};
NVG_BEGIN_PLUGIN_INFO(PluginDemo)
NVG_DECLARE_PLUGIN_UID(0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78)
NVG_DECLARE_PLUGIN_TYPE(PLUGIN::BASIC)
NVG_DECLARE_PLUGIN_VERSION(1, 0, 0)
NVG_DECLARE_PLUGIN_NAME("PluginDemo")
NVG_DECLARE_PLUGIN_DESCRIP("Plug-in Demo")
NVG_DECLARE_PLUGIN_COMMENT("This is a demo plug-in.")
NVG_DECLARE_PLUGIN_AUTHOR("Joshua GPBeta")
NVG_DECLARE_PLUGIN_HOMEPAGE("www.gpbeta.com")
NVG_DECLARE_PLUGIN_EMAIL("studiocghibli@gmail.com")
NVG_END_PLUGIN_INFO(PluginDemo)
NVG_NO_COMPONENT_REGISTER(PluginDemo)
NVG_IMPLEMENT_PLUGIN(PluginDemo)

And that's ALL! Quite simple, isn't it?

Focus on Details

Headers

#include <NERvGear/plugin.h> This header file implements PluginImpl class which implements the NERvGear::IPlugin interface and complete most of the essential codes for a plug-in component.

#include <NERvGear/object.h> This header file includes many things that you need to implement a component. Actually the NERvGear/plugin.h header also requires this file because plug-in is one kind of component.

#include <NERvGear/NERvSDK.h> This header file includes almost everything(except two headers listed above and some interfaces) of the SDK in it, and it also manage the version of the APIs. You can always include this when you are confused with the API entries.

Namespaces

We recommend you to use the using-directive syntax such as using namespace NERvGear in your source files and use scope resolution operator syntax such as ::NERvGear::FooBar in your header files.

Implementing IPlugin

The NERvGear::PluginImpl class helps you with most of the codes to implement NERvGear::IPlugin interface. You can override some of the methods of NERvGear::IPlugin on demand then pass to superclass using return PluginImpl::OnXXX() at the end if your plug-in goes without any problems.

NERvGear calls these methods of NERvGear::IPlugin when:

Methods Timing Component Resources
OnInitial() On program startup or enabling a plug-in May be unavailable
OnReady() On both plug-in and program are ready Available
OnConfig() When user trying to config a plug-in Available
OnRelease() On program exit or disabling a plug-in May be unavailable

See NERvGear Interfaces Reference for more details about NERvGear::IPlugin interface.

For VS Developers

We strongly recommend developers to enable the /DEBUG linker switch even for the release builds, and if you want a method-resolved call stack when your plug-in crashes, you can use

class NVG_DLLEXPORT PluginDemo : public PluginImpl { ... };

instead of

class PluginDemo : public PluginImpl { ... };

to declare your classes.

My Plug-in Goes Wrong...

IPlugin::OnInitial() should return E_FAILED if your plug-in could not be initialized or some of the resources are not available. NERvGear will stop loading a plug-in when its OnInitial() method failed.

IPlugin::OnRelease() could return E_PENDING when your plug-in is still busying doing something or there're some reasons that your plug-in could not be terminated immediately. NERvGear will stop unloading a plug-in if its OnRelease() method failed.

Plug-in Information

We use a macro block to declare information for a plug-in, like:

NVG_BEGIN_PLUGIN_INFO(PluginDemo)
// The plug-in ID, must be distinguished from other plug-ins.
NVG_DECLARE_PLUGIN_UID(0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78)
// The plug-in type, can be a combination of the PLUGIN::TYPE enumerators.
NVG_DECLARE_PLUGIN_TYPE(PLUGIN::BASIC)
// The plug-in version with major, minor and sub-minor version
NVG_DECLARE_PLUGIN_VERSION(1, 0, 0)
NVG_DECLARE_PLUGIN_NAME("PluginDemo")
NVG_DECLARE_PLUGIN_DESCRIP("Plug-in Demo")
NVG_DECLARE_PLUGIN_COMMENT("This is a demo plug-in.")
NVG_DECLARE_PLUGIN_AUTHOR("Joshua GPBeta")
NVG_DECLARE_PLUGIN_HOMEPAGE("www.gpbeta.com")
NVG_DECLARE_PLUGIN_EMAIL("studiocghibli@gmail.com")
NVG_END_PLUGIN_INFO(PluginDemo)

Same as other components, each SAO Utils plug-in must contain this block to describe itself, but components use NVG_*_OBJECT_INFO macros to do this work.

Components Registration

A plug-in can provide or expose implementations(objects) of some components to other plug-ins by registering them explicitly in the component registeration macro block like:

NVG_BEGIN_COMPONENT_REGISTER(PluginDemo)
NVG_REGISTER_OBJECT(DemoObject1, false) // no aggregation
NVG_REGISTER_OBJECT(DemoObject2, true) // aggregation supported
NVG_END_COMPONENT_REGISTER()

Or if your plug-in does not serve any objects, just simply declare as:

NVG_NO_COMPONENT_REGISTER(PluginDemo)

See Aggregation (COM) for details about object aggregation.