Creating a Plugin

From ANVEL Wiki
Jump to: navigation, search

Introduction

Plugins are dynamic libraries that register with and describe their capabilities to ANVEL. Many internal systems contained in ANVEL are plugins, including all the non-default vehicle terrain interaction (VTI) models and the OGRE 3D-based rendering system. Plugins provide functionality through a few specific interfaces. Typically, a plugin is comprised of four C++ files: a .h and a .cpp for plugin registration, and a .h and .cpp for plugin implementation.

Plugins have access to all the internals of the ANVEL simulation, allowing queries for the state of any visible object, changes to the global state, or alteration of simulation properties. This allows maximum flexibility.

Use Caution: These actions may result in harmful alterations to the simulation. For example, it is possible to destroy all vehicles or simulation states through plugins.

Users can employ plugins to expand ANVEL to simulate research interests to:

Registering a Plugin

Plugins register the following:

The thread that runs the plugin is important when developing code. If a plugin is interacting with the user interface (UI) through either the 3D rendering system or the main windowing GUI, it must be done on the main UI thread. However, commands and updates from the simulation are generally processed on the simulation thread. Utilizing the ASSERT_SIM_THREAD() macro verifies the code intended to run on the simulation thread is only run on the simulation thread and code intended to run on the UI thread is not run on the simulation thread.

Plugin Registration Code

Most plugins start with the same basic layout and a file dedicated to set-up of the internal plugin parameters for registration with ANVEL.

The following plugin example references the SamplePlugin project (located at <install_dir>\samples\PluginSample\). This plugin does not implement any functionality but serves as a skeleton for plugin registration within ANVEL.

SamplePlugin.h:

#pragma once

#include "Core/Plugin.h"
#include "Core/PluginVersioning.h"

//if we are exporting this to a dll (ie. building the plugin)
//define preprocessor user macro (e.g. ANVEL_SAMPLE_PLUGIN_EXPORT)
#if defined(_LINUX)
	#define ANVEL_SAMPLE_API 
#else
	#ifdef ANVEL_SAMPLE_PLUGIN_EXPORT
	#define ANVEL_SAMPLE_API __declspec(dllexport)
	#else
	#define ANVEL_SAMPLE_API __declspec(dllimport)
	#endif
#endif

namespace Anvel
{
	namespace Plugins
	{
		///Sample Plugin
		class ANVEL_SAMPLE_API AnvelSamplePlugin : public Plugins::Plugin
		{
		public:
			AnvelSamplePlugin();
			~AnvelSamplePlugin();

			///[Plugin interface]
			//Called to initialize anything that this plugin needs after it has been loaded
			void Initialize() override;

			//Called by plugin host when this plugin should be shutdown
			void Shutdown() override;

			//Get the name of this plugin
			String GetName() const override;

			//Our common declarations that can be used with most plugins
			ANVEL_PLUGIN_COMMON_DECL;
		private:
			//Store internal plugin data here
		};
	}
}

SamplePlugin.cpp:

#include "SamplePlugin.h"
#include "Core/Core.h"

//... Other includes here...

using namespace Anvel;
using namespace Anvel::Plugins;

//////////////////////////////////////////////////////////////////////////
// Plugin DLL Code    
//////////////////////////////////////////////////////////////////////////

static const char* kPluginName = "AnvelSamplePlugin";

//////////////////////////////////////////////////////////////////////////

AnvelSamplePlugin::AnvelSamplePlugin()
{
	//Internal Initialization here
}

//////////////////////////////////////////////////////////////////////////

AnvelSamplePlugin::~AnvelSamplePlugin()
{
	//Internal Shutdown here
}

//////////////////////////////////////////////////////////////////////////

void AnvelSamplePlugin::Initialize()
{
	//Register Factories, Data types, etc., here
}

//////////////////////////////////////////////////////////////////////////

void AnvelSamplePlugin::Shutdown()
{
	//Do plugin shutdown work here
}

//////////////////////////////////////////////////////////////////////////

String AnvelSamplePlugin::GetName() const
{
	return String(kPluginName);
}

//////////////////////////////////////////////////////////////////////////

//The implementation of our commonly used plugin functions
ANVEL_PLUGIN_COMMON_DEF( AnvelSamplePlugin );

//////////////////////////////////////////////////////////////////////////
// Plugin Export Code
//////////////////////////////////////////////////////////////////////////

AnvelSamplePlugin* pPlugin;

extern "C" ANVEL_SAMPLE_API void RegisterPlugin(Anvel::Plugins::PluginHost* host) 
{
	pPlugin = new AnvelSamplePlugin();
	host->RegisterPlugin( pPlugin );
}

extern "C" ANVEL_SAMPLE_API void UnregisterPlugin(Anvel::Plugins::PluginHost* host) 
{
	host->UnregisterPlugin(kPluginName, pPlugin);
	delete pPlugin;
}

Plugin Properties

Source: Plugin Manager
Plugin Information

Name Description Type Attributes Unit
Name Plugin name string ReadOnly
Filename File name string ReadOnly
Path string ReadOnly
Version Plugin version string ReadOnly
Restrictions Restrictions, if any string ReadOnly
Copyright Copyright, if any string ReadOnly
ANVEL Core Version ANVEL version string ReadOnly
Date Date the plugin was compiled string ReadOnly
Loaded True if loaded bool ReadOnly

See Also

Compiling ANVEL Sample Plugins

Command Plugin Sample

Sensors