Plugin Interface

Defines an interface for plugins to implement in order to be loadable by VRTree.

Typedefs


Function prototype for the plugin cleanup function.

This function is called by the loader, before unloading the plugin.

The plugin should implement this to remove any state added to VRTree during any other plugin functions.

Returns

0 for success (not currently used)

Example

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPCleanup()
{
  return 0; //success
}


Function prototype for getting the name of the default recipe file used by the importer.

Returns

A name of a recipe file to use as the default name (e.g. "myrecipe.vrcp")

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPDefaultRecipe()
{
  return "myRecipe.vrcp";
}
PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPExportDefaultRecipe()
{
  return "myExportRecipe.vrcp";
}

Note

Any plugin implementing import or export functionality must provide this function as VRPDefaultRecipe for importers, and VRPExportDefaultRecipe for exporters


const char *(VRTREE_APIENTRY * VRPDependsProc)(void)

Function prototype for getting the plugin dependencies.

This defines the order which plugins are loaded, ensuring that any plugins that this one depends on are loaded first.

Returns

Comma separated list of plugin names (either names reported by plugins, or their filenames without extension)

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPDepends()
{
  return "Another Plugin Name, anotherpluginfile"; // first by name, second by file
} 


int(VRTREE_APIENTRY * VRPExportProc)(const char *outFile, HNode fromRoot, HNode fromScenes, HNode fromLibs, const char *recipePath)

Function prototype for an export function.

This function is passed a path to a file and some nodes and is expected to write data from the nodes to the file. The implementation should respect the callers requests to export the specified nodes rather than the whole tree.

Parameters
outFile

absolute path to the output file (this will be the root file name in the case of multi-file output)

fromRoot

the root of the tree

fromScenes

the node in the scenes tree to start export from

fromLibs

the node in the libs tree to start export from

recipePath

absolute path to a recipe file describing advanced configuration

Returns

0 on success

Example

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPExport(const char* outFile, HNode fromRoot, HNode fromScenes, HNode fromLibs, const char* recipe)
{
  // write some nodes to outFile...
  return 0; //success
}


const char *(VRTREE_APIENTRY * VRPFFINamespaceProc)(void)

Function prototype for getting the FFI namespace/module name to use for this plugin.

This specifies the namespace to use for registered FFI functions. For a plugin with ffi namespace "MyPlugin" and a registered FFI function "foo", it will be accessible in lua as MyPlugin.foo() If the specified namespace is already in use by another loaded plugin it will be ignored. If this is blank, the namespace will be inferred from VRPName() or the module name.

Returns

Lua-safe ffi module name (letters, numbers and underscores, not beginning with a digit)

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPFFINamespace()
{
  return "MyPlugin";
} 


const char *(VRTREE_APIENTRY * VRPFormatsProc)(void)

Function prototype for getting the XML description of formats accepted by VRPImportProc.

Returns

XML document describing the accepted formats

Schema

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="filetypes">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="type" maxOccurs="unbounded" minOccurs="1">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute type="xs:string" name="ext" use="required"/>
                <xs:attribute type="xs:string" name="desc" use="required"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPFormats()
{
  return "<filetypes> \
    <type ext=\"txt\" desc=\"Text File\" /> \
  </filetypes>";
}
<filetypes>
  <type ext="txt" desc="Text File" />
</filetypes>


Function prototype for the API version functions.

Plugins should implement both VRPGetAPIVersionMajor and VRPGetAPIVersionMinor with this function signature.

Returns

Value of PLUGIN_API_VERSION_MAJOR for VRPGetAPIVersionMajor, Value of PLUGIN_API_VERSION_MINOR for VRPGetAPIVersionMinor

Example

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPGetAPIVersionMajor()
{
  return 1;
}

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPGetAPIVersionMinor()
{
  return 2;
}

Note

vrtree-linker provides VRPLUGIN_API_STDIMPL to implement these automatically


int(VRTREE_APIENTRY * VRPHasPermissionProc)(const char *permissions)

Function prototype for checking permission to do something. Plugin will be passed a check function if it exports VRPRegisterHasPermissionProc.

This mainly corresponds to VRTree permissions - the plugin may check for permissions (such as EditScript), and it may request permissions be obtained from the licensing mechanism.

Parameters
permissions

comma-separated list of permission names to request. When specifying more than one, all are required for the check to pass.

Returns

1 if the check is successful


int(VRTREE_APIENTRY * VRPImportProc)(const char *file, HNode root, HNode scenes, HNode libs, uint64_t flags, const char *recipePath)

Function prototype for an import function.

This function is passed a path to a file, and is expected to do some work with it The implementation should respect the callers requests to import onto nodes that are not the default scenes/libs nodes

Parameters
file

absolute path to the file to be imported

root

the root of the tree

scenes

the scenes root node to import assembly data into

libs

the library root node to import assets into

flags

any additional flags that should be applied to nodes

recipePath

absolute path to a recipe file describing advanced configuration

Returns

0 on success

Example

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPImport(const char* file, HNode root, HNode scenes, HNode libs, uint64_t flags, const char* recipe)
{
  // create some nodes in the tree...
  return 0; //success
}


Function prototype for the plugin init function.

This function is called by the loader, after checking the major version and performing any other registration requested by the plugin. This means that VRPInit may check permissions or write to the log, or do whatever else was registered.

Returns

0 for success, any positive integer to fail and abort the plugin init

Example

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPInit()
{
  return 0; //success
}


const char *(VRTREE_APIENTRY * VRPLockedProc)(void)

Function prototype for getting the plugin lock condition.

Returns

The lock condition.

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPLocked()
{
  return true;
}


void(VRTREE_APIENTRY * VRPLogIndentProc)(char indent)

Function prototype for the log indent function.

Some log messages need to have more complex formatting, so plugins can use this function to indent all further log messages. Plugin will be passed a log indent function to use for logging, if it exports VRPRegisterLogIndentProc.

Parameters
indent

boolean for increasing or decreasing indent. Pass 0 to decrease indent, any positive value to increase indent.


void(VRTREE_APIENTRY * VRPLogProc)(int type, const char *message)

Function prototype for the log function.

Plugin will be passed a log function to use for logging, if it exports VRPRegisterLogProc.

Parameters
type

type of message:

  • 0 = Info

  • 1 = Warning

  • 2 = Error

  • 3 = Debug

message

the text to write to the log


const char *(VRTREE_APIENTRY * VRPNameProc)(void)

Function prototype for getting the plugin full name.

Returns

The name of the plugin. Must be a valid string.

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPName()
{
  return "My Plugin";
}

Note

All plugins are required to implement this function.


void(VRTREE_APIENTRY * VRPProgressYieldProc)(int currentValue, int maxValue, const char *message)

Function prototypes for a progress yield function.

Plugin will be passed a yield function to call during long operations, if it exports the VRPRegisterProgressYieldProc function.

Parameters
currentValue

the current progress through the operation, if greater than zero will be represented by a progress bar

maxValue

the maximum progress value, if greater than zero will be represented by the end of the progress bar

message

the message to set on the progress display. If 0, the message does not change from whatever is already there.

Note

The plugin execution will be blocked by calls to yield, until the application returns control to it.


void(VRTREE_APIENTRY * VRPRegisterHasPermissionProc)(VRPHasPermissionProc)

Function prototype for registering a permission check function.

Plugin should implement this and store the pointer it is given, if it wants to do license checks


void(VRTREE_APIENTRY * VRPRegisterLogIndentProc)(VRPLogIndentProc)

Function prototype for being given a log indent function.

Plugin should implement this and store the pointer it is given, if it wishes to make use of the log indent functionality.

The indent levels should match (e.g. if you indent twice, you should unindent twice, too)

Example

static VRPLogProc s_logFunc = 0;
static VRPLogIndentProc s_logIndentFunc = 0;

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterLog(VRPLogProc proc) 
{
  s_logFunc = proc;
}

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterLogIndent(VRPLogIndentProc proc) 
{
  s_logIndentFunc = proc;
}

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPInit()
{
  if(s_logFunc && s_logIndentFunc) {
    s_logIndentFunc(1);
    s_logFunc(2, "This is an INDENTED error message\n");
    s_logIndentFunc(1);
    s_logFunc(2, "This is a 2-deep indented error message\n");
    s_logIndentFunc(0);
    s_logIndentFunc(0);
  }
}

Note

vrtree-linker provides VRPLUGIN_API_LOGIMPL to provide s_logFunc and s_logIndentFunc


Function prototype for being given a log function.

Plugin should implement this and store the pointer it is given, if it wishes to log to the application log. To write a log message, the plugin should call the provided log function directly

Example

static VRPLogProc s_logFunc = 0;

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterLog(VRPLogProc proc) 
{
  s_logFunc = proc;
}

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPInit()
{
  if(s_logFunc)
    s_logFunc(2, "This is an error message\n");
}

Note

vrtree-linker provides VRPLUGIN_API_LOGIMPL to provide s_logFunc and s_logIndentFunc


void(VRTREE_APIENTRY * VRPRegisterProgressYieldProc)(VRPProgressYieldProc)

Function prototype for registering a progress yield function.

Plugin should implement this and store the pointer it is given, if it wishes to yield to the application during long operations.

Example

static VRPProgressYieldProc s_progress = 0;

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterProgressYield(VRPProgressYieldProc proc)
{
  s_progress = proc;
}

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPImport(const char* file, HNode root, HNode scenes, HNode libs, uint64_t flags, const char* recipe)
{
  // create some nodes in the tree...
  s_progress(0, nObjects, "Importing file...");
  for(int i = 0; i < nObjects ++i) {
    doLongImport(objects[i]);
    s_progress(i, nObjects, 0);
  }
  return 0; //success
}

Note

vrtree-linker provides VRPLUGIN_API_YIELDIMPL to provide progress_yield


void(VRTREE_APIENTRY * VRPRegisterRequestPermissionProc)(VRPRequestPermissionProc)

Function prototype for registering a permission request function.

Plugin should implement this and store the pointer it is given, if it wants to do license requests


void(VRTREE_APIENTRY * VRPRegisterUserMessageProc)(VRPUserMessageProc)

Function prototype for registering a message function.

Plugin should implement this and store the pointer it is given, if it wishes to summon message boxes.

Example

//This example registers a Lua function which, when called from Lua, summons a message box
static VRPUserMessageProc s_msgProc = 0;

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterUserMessage(VRPUserMessageProc proc)
{
  s_msgProc = proc;
}

static HFFIVar msg_func(int argc, HFFIVar* argv, void*) {
  if(s_msgProc)
    s_msgProc("Hello, this is a message box");
  return 0;
}

PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPInit()
{
  //...
  // Registers msg_func as Lua function "helloMessage"
  VRFFIRegister("helloMessage", &msg_func, 0, 0);
}


void(VRTREE_APIENTRY * VRPRegisterUserQuestionCallbackProc)(VRPUserQuestionCallbackRegisterProc)

Function prototype for registering a question callback function.

Plugin should implement this and use the pointer it is given to register a callback to be called by question boxes summoned by a VRPUserQuestionProc

This is not useful without also implementing VRPRegisterUserQuestionCallbackProc


void(VRTREE_APIENTRY * VRPRegisterUserQuestionProc)(VRPUserQuestionProc)

Function prototype for registering a question function.

Plugin should implement this and store the pointer it is given, if it wishes to summon question boxes.

Example

//This example registers a Lua function which, when called from Lua, summons a question box
static VRPUserQuestionProc s_qProc = 0;
static void question_callback(int result, void* userData) {
   //result is the option the user chose
}

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterUserQuestionCallback(VRPUserQuestionCallbackProc proc)
{
  proc(&question_callback, 0); //register our callback proc.
  // we could also store proc and register different functions for different questions
}

PLUGIN_ENTRY_POINT void VRTREE_APIENTRY VRPRegisterUserQuestion(VRPUserQuestionProc proc)
{
  s_qProc = proc;
}

static HFFIVar question_func(int argc, HFFIVar* argv, void*) {
  if(s_qProc) {
    s_qProc("Is this a dialog box?"); //user input on this dialog calls question_callback
  }
  return 0;
}


PLUGIN_ENTRY_POINT int VRTREE_APIENTRY VRPInit()
{
  //...
  // Registers question_func as Lua function "askQuestion"
  VRFFIRegister("askQuestion", &question_func, 0, 0);
}


int(VRTREE_APIENTRY * VRPRequestPermissionProc)(const char *permissions, const char *cancelCaption)

Function prototype for requesting permission to do something.

Plugin will be passed a request function if it exports VRPRegisterRequestPermissionProc

Parameters
permissions

comma-separated list of permission names to request. When specifying more than one, all are required for the check to pass.

cancelCaption

optional caption to display on the cancel button of any license request dialog presented by the application to fulfil the request.

Returns

1 if the request is successful


Function prototype for getting the XML description of the settings that should be presented in a user interface.

Returns

XML document describing the settings

Schema

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="recipe">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Page" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType mixed="true">
            <xs:choice maxOccurs="unbounded" minOccurs="0">
              <xs:element name="StringEdit">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="label" use="optional"/>
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:string" name="value" use="optional"/>
                      <xs:attribute type="xs:string" name="readonly" use="optional"/>
                      <xs:attribute type="xs:string" name="desc" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="IntBox">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="label"/>
                      <xs:attribute type="xs:string" name="name"/>
                      <xs:attribute type="xs:byte" name="value"/>
                      <xs:attribute type="xs:byte" name="min"/>
                      <xs:attribute type="xs:byte" name="max"/>
                      <xs:attribute type="xs:string" name="desc"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="Selection">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="label" use="optional"/>
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:string" name="value" use="optional"/>
                      <xs:attribute type="xs:string" name="options" use="optional"/>
                      <xs:attribute type="xs:string" name="desc" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="Check">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="label" use="optional"/>
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:byte" name="value" use="optional"/>
                      <xs:attribute type="xs:string" name="desc" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="FloatBox">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="label" use="optional"/>
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:float" name="value" use="optional"/>
                      <xs:attribute type="xs:float" name="min" use="optional"/>
                      <xs:attribute type="xs:float" name="max" use="optional"/>
                      <xs:attribute type="xs:string" name="desc" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:choice>
            <xs:attribute type="xs:string" name="name" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPSettingsInterface()
{
  return "<recipe> \
    <Page name=\"Basic\"> \
      <IntBox label=\"Log Level\" name=\"loglevel\" value=\"0\" min=\"0\" max=\"4\" desc=\"Set log level\"/> \
      <Selection label=\"Unit\" name=\"vrUnit\" value=\"meters\" options=\"meters,milimeters,centimeters\" desc=\"Unit of values in the file\"/> \
    </Page> \
  </recipe>";
}
<recipe>
  <Page name="Basic">
    <IntBox label="Log Level" name="loglevel" value="0" min="0" max="4" desc="Set log level"/> 
    <Selection label="Unit" name="vrUnit" value="meters" options="meters,milimeters,centimeters" desc="Unit of values in the file"/> 
  </Page>
</recipe>


const char *(VRTREE_APIENTRY * VRPShortNameProc)(void)

Function prototype for getting the plugin short name (-import shortcut)


const char *(VRTREE_APIENTRY * VRPSignatureProc)(void)

Function prototype for getting the plugin signature (license)

Returns

The license text string provided by Virtalis

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPSignature()
{
  return "<some signature signed xml>";
}

Note

Plugins that require access to the VRTree C API must implement this function.


void(VRTREE_APIENTRY * VRPUserMessageProc)(const char *message)

Function prototype for triggering an application dialog containing a message to present directly to the user.

Plugin will be passed a message function to use if it exports VRPRegisterUserMessageProc

Parameters
message

the message to display to the user

Note

Since this is a modal dialog, execution of the calling thread may be blocked until the box is dismissed. This does not happen when running on a cluster, so blocking behaviour should not be depended on. Plugins should avoid calling this during VRPInit and VRPCleanup.


void(VRTREE_APIENTRY * VRPUserQuestionCallbackProc)(int result, void *userData)

Function prototype for a callback to call when a user chooses an option presented by a UserQuestion.

Parameters
result

the index of the option selected


void(VRTREE_APIENTRY * VRPUserQuestionCallbackRegisterProc)(VRPUserQuestionCallbackProc proc, void *userData)

Function prototype for registering a VRPUserQuestionCallbackProc as the callback for UserQuestion dialogs.

Plugin will be passed a register function if it exports VRPRegisterUserQuestionCallbackProc


int(VRTREE_APIENTRY * VRPUserQuestionProc)(const char *message)

Function prototype for triggering an application dialog containing a question to ask to the user. This also requires a registered VRPUserQuestionCallbackProc.

Plugin will be passed a question function to use if it exports VRPRegisterUserQuestionProc

Parameters
message

the message to display to the user (phrased as a question)

Returns

0 if question is submitted, 1 if there is no registered question callback to receive the user's answer

Note

Since this is a modal dialog, execution of the calling thread may be blocked until the box is dismissed. This does not happen when running on a cluster, so blocking behaviour should not be depended on. Plugins should avoid calling this during VRPInit and VRPCleanup


const char *(VRTREE_APIENTRY * VRPVersionProc)(void)

Function prototype for getting the plugin version (human readable, not API version)

Returns

The version string (e.g. "1.0.5"). Must be a valid string.

Example

PLUGIN_ENTRY_POINT const char* VRTREE_APIENTRY VRPVersion()
{
  return "1.0.3a";
}

Note

All plugins are required to implement this function.

Variables


incremented if backward compatibility is broken


incremented if new exports are added

No Results.

Getting StartedArchitectureBest PracticesHow ToAdvanced TopicsChangelogvrtree_cppCoreForeign Function InterfaceMetanodesMigrationsObserversPropertiesTreeUtilitiesAPI DefinitionsVR ExchangePluginsLua API