NERvDN Library  0.2.0.20160420-0019
NERvLibrary - Nerve Gear Developer Network
Usage of Components

This tutorial will show you the classification of components and how to use them.

Types of Components

We can classify the components into internal and external implementations:

Internal Components

These component implementations are provided by the core of NERvGear, you can instance these component objects calling corresponding NERvGear::NERvCreateXXX() functions or calling NERvGear::NERvCreateObject() with specific component and interface IDs. It is possible to instance these components in the call of IPlugin::OnInitial() or IPlugin::OnRelease() because these components must be initialed and registered before any plug-ins is loaded.

External Components

These component implementations are provided by other plug-ins, you must instance these component objects by calling NERvGear::NERvCreateObject() with specific component and interface IDs. Trying to access these components in the call of IPlugin::OnInitial() or IPlugin::OnRelease() may be failed because the plug-in initialization order is not determined.

Instancing Components

Here's the codes that create the Window component which expose NERvGear::UI::IWindow interface implemented by NERvGear:

#include <NERvGear/interface/UI/IWindow.h>
using namespace NERvGear;
...
UI::IWindow window = NERvCreateWindow(NULL, Point(0, 0), Size(300, 200), NVG_TEXT("Hello World!"));
... // Do something on the window object.
window->Release();
...

The Window and GUI relative components are not available currently.

The following codes show you the way to find and instance a default implementation of the Data Source component:

#include <NERvGear/component/CDataSource.h>
#include <NERvGear/interface/IDataSource.h>
using namespace NERvGear;
...
IDataSource* source = NULL;
// Use 'ID_NULL' as object ID parameter to query any available objects.
NERvCreateObject(ID_CDataSource, ID_NULL, ID_IDataSource, NULL, reinterpret_cast<void**>(&source));
... // Do something on the data source object.
source->Release();
...

Using Internal Components

Data Source is the first defined, cooperative and public component. You can access varieties of data with its NERvGear::IDataSource and NERvGear::IData interfaces. NERvGear provide an internal implementation called 'NERvGear Data Collection' with some useful system and common data for this component.

Code Snippets

#include <NERvGear/object/ODataSource.h>
#include <NERvGear/interface/IData.h>
using namespace NERvGear;
...
static const size_t BUF_SIZE = 0xFF;
// Find and instance 'NERvGear Data Collection' data source component,
// returning the IDataSource interface.
IDataSource* source = NULL;
if (NVG_SUCC(NERvCreateObject(ID_CDataSource, // component ID
ID_ODataSource, // object ID
ID_IDataSource, // interface ID
NULL, reinterpret_cast<void**>(&source)))) {
IData* data = NULL;
// Find the system data in this data source.
if (NVG_SUCC(source->FindData(DATA::ID_SYS, &data))) {
// Find the account name value index in the system data.
const unsigned index = data->GetValueIndex(DATA::SYS::STR_ACCOUNT_NAME);
if (index != unsigned(NVG_ANY)) {
// Update data value.
if (NVG_SUCC(data->Update(index))) {
wchar_t buf[BUF_SIZE] = {0};
// Copy the value to our buffer.
if (data->GetValue(index, BUF_SIZE, buf)) {
// We get the account name now.
NERvLogInfo(NVG_TEXT("Plug-in Demo"),
NVG_TEXT("Account Name: %s"), buf);
}
}
}
data->Release();
} // Remember to release IData and IDataSource interfaces.
source->Release();
}

The codes above show how we can instance the 'NERvGear Data Collection' Data Source component, find the system name data and account name value, copy the value to our buffer and finally print to the std output or a log file. Like all the COM interfaces, you should release the interface handle by calling its IUnknown::Release() when you no longer need it.

See NERvGear Interfaces Reference for more details about NERvGear::IDataSource and NERvGear::IData interfaces.

Using External Components

Basically we use the same way to use external components, however there're still some differences we should pay attention to:

Since a plug-in doesn't link against other plug-in DLLs directly, we can't use the symbols exported by the plug-ins, therefore we should initialize the ID symbols manually. Define NVG_FLAG_INIT_UID flag in your source files before including any headers, then the IDs will be defined and initialized so that we will no longer get undefined reference linking error for the external UID symbols.

Also note that the headers for external resources are located in the NERvHub/*, please see API Reference for the header locations of all the external available resources.

Code Snippets

// Initialize UIDs explicitly.
#define NVG_FLAG_INIT_UID
// Include the external component object header.
#include <NERvHub/object/Demo/ODemo.h>
...
using namespace NERvGear;
...
Demo::IDemo* demo = NULL;
// Instance the 'Demo Component' implemented by 'Demo',
// returning the Demo::ID_IDemo interface.
if (NVG_SUCC(NERvCreateObject(ETC::ID_CDemo, // component ID
Demo::ID_ODemo, // object ID
Demo::ID_IDemo, // interface ID
NULL, reinterpret_cast<void**>(&demo)))) {
demo->FooBar(NVG_TEXT("Show me the demo!"));
// Remember to release Demo::IDemo interface.
demo->Release();
}

Codes above instance the 'Demo Object' implementing Demo component, then invoke the FooBar() method of Demo::IDemo interface. See Demo Object Reference for the implementation details, usages or notes.

You can also pass NERvGear::ID_NULL to the object ID parameter when you call NERvGear::NERvCreateObject(), in this way, you don't care about whom implements this component and system will find an object providing specified interface.