Host Interface added.

This commit is contained in:
Kolan Sh 2014-10-16 16:11:28 +04:00
parent cd6a7885b3
commit 9063b069e3
18 changed files with 156 additions and 52 deletions

View File

@ -0,0 +1,6 @@
SET (LibName ${PROJECT_LOWERCASE_NAME}-host-iface)
FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} HostInterface.vala)
SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0)
SET (LibExtraSources ${PROJECT_SOURCE_DIR}/src/library_constructor.c)
SET (LibInstall ON)
INCLUDE (ValaLibCommonRules)

View File

@ -0,0 +1,23 @@
/**
* GObject Models.
*/
namespace GObject {
/**
* Modules/Plugins.
*/
namespace Plugins {
/**
* Host interface.
*/
public interface IHost : Object {
}
/**
* Abstract Host.
*/
public abstract class Host : Object, IHost {
}
}
}

View File

@ -1,9 +1,13 @@
SET (LibName ${PROJECT_LOWERCASE_NAME}-loader) SET (LibName ${PROJECT_LOWERCASE_NAME}-loader)
FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} PluginLoader.vala) FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} PluginLoader.vala)
SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0) SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0)
SET (LibCustomVapis ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi) SET (LibCustomVapis ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
)
SET (LibExtraSources ${PROJECT_SOURCE_DIR}/src/library_constructor.c) SET (LibExtraSources ${PROJECT_SOURCE_DIR}/src/library_constructor.c)
SET (LibInstall ON) SET (LibInstall ON)
SET (LibLinkLibs ${PROJECT_LOWERCASE_NAME}-iface) SET (LibLinkLibs ${PROJECT_LOWERCASE_NAME}-iface ${PROJECT_LOWERCASE_NAME}-host-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaLibCommonRules) INCLUDE (ValaLibCommonRules)

View File

@ -68,8 +68,10 @@ namespace GObject {
/** /**
* Creates Plugin instance from the module. * Creates Plugin instance from the module.
*/ */
public Plugin create_instance () { public Plugin create_instance (IHost ihost) {
return Object.new (type) as Plugin; var p = Object.new (type) as Plugin;
p.host = ihost;
return p;
} }
} }

View File

@ -1,6 +1,9 @@
SET (LibName ${PROJECT_LOWERCASE_NAME}-iface) SET (LibName ${PROJECT_LOWERCASE_NAME}-iface)
FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} PluginInterface.vala) FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} PluginInterface.vala)
SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0) SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0)
SET (LibCustomVapis ${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi)
SET (LibExtraSources ${PROJECT_SOURCE_DIR}/src/library_constructor.c) SET (LibExtraSources ${PROJECT_SOURCE_DIR}/src/library_constructor.c)
SET (LibInstall ON) SET (LibInstall ON)
SET (LibLinkLibs ${PROJECT_LOWERCASE_NAME}-host-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/host-iface")
INCLUDE (ValaLibCommonRules) INCLUDE (ValaLibCommonRules)

View File

@ -18,6 +18,11 @@ namespace GObject {
* Abstract Plugin. * Abstract Plugin.
*/ */
public abstract class Plugin : Object, IPlugabble { public abstract class Plugin : Object, IPlugabble {
/**
* Host Interface.
*/
public IHost host = null;
} }
} }
} }

View File

@ -1,6 +1,10 @@
SET (LibName loader_test-iface) SET (LibName loader_test-iface)
FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} LoaderTestInterface.vala) FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} LoaderTestInterface.vala)
SET (LibCustomVapis ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi) SET (LibCustomVapis ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
)
SET (LibLinkLibs gobject-plugin-iface) SET (LibLinkLibs gobject-plugin-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaLibCommonRules) INCLUDE (ValaLibCommonRules)

View File

@ -1,15 +1,25 @@
using GObject.Plugins; using GObject.Plugins;
/**
* Loader Host Interface.
*/
public interface IHostLoaderTest : IHost {
/**
* Any Host Method.
*/
public abstract void method_host ();
}
/** /**
* Abstract plugin of type A. * Abstract plugin of type A.
*/ */
public abstract class PluginTypeA: Plugin { public abstract class PluginTypeA: Plugin {
/** /**
* Any virtual method for PluginTypeA. * Any abstract method for PluginTypeA.
*/ */
[CCode (has_target = false)] public abstract void method_a ();
public virtual void method_a () { }
} }
/** /**
@ -18,7 +28,7 @@ public abstract class PluginTypeA: Plugin {
public abstract class PluginTypeB : Plugin { public abstract class PluginTypeB : Plugin {
/** /**
* Any virtual method for PluginTypeB. * Any abstract method for PluginTypeB.
*/ */
public virtual string method_b () { return ""; } public abstract string method_b ();
} }

View File

@ -4,11 +4,18 @@ SET (BinPackages gee-0.8 gio-2.0)
SET (BinCustomVapis ${CMAKE_BINARY_DIR}/src/loader/${PROJECT_LOWERCASE_NAME}-loader-${MAJOR}.vapi SET (BinCustomVapis ${CMAKE_BINARY_DIR}/src/loader/${PROJECT_LOWERCASE_NAME}-loader-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
) )
SET (BinLinkLibs ${PROJECT_LOWERCASE_NAME}-loader ${PROJECT_LOWERCASE_NAME}-iface loader_test-iface SET (BinLinkLibs ${PROJECT_LOWERCASE_NAME}-loader
${PROJECT_LOWERCASE_NAME}-iface
${PROJECT_LOWERCASE_NAME}-host-iface
loader_test-iface
)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/loader"
"${CMAKE_BINARY_DIR}/src/plugin-iface"
"${CMAKE_BINARY_DIR}/test/loader_test-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
) )
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/loader" "${CMAKE_BINARY_DIR}/src/plugin-iface"
"${CMAKE_BINARY_DIR}/test/loader_test-iface")
INCLUDE (ValaBinCommonRules) INCLUDE (ValaBinCommonRules)
# Plugin Loading Test # Plugin Loading Test
@ -21,17 +28,26 @@ ENDMACRO (plugin_loading_test)
# Testing Plugin:[de]init() and Library unload() # Testing Plugin:[de]init() and Library unload()
plugin_loading_test (SimpleLoaderTest plugin_loading_test (SimpleLoaderTest
"Plugin Type Name = TypeA1 "List Plugins:
Plugin Type Name = TypeA2 Name = TypeA1
Plugin Type Name = TypeB1 Name = TypeA2
Plugin Type Name = TypeB2 Name = TypeB1
TypeA1 init Name = TypeB2
Creating PluginTypeA Object:
TypeA1 init \\\\(\\\\) called
Call a.method_a \\\\(\\\\) from main app:
TypeA1.method_a \\\\(\\\\) called TypeA1.method_a \\\\(\\\\) called
TypeA1 deinit Call IHostLoaderTest.method_host \\\\(\\\\) from TypeA1:
TypeB1 init LoaderTestHost.method_host \\\\(\\\\) called
Destroing PluginTypeA Object:
TypeA1 deinit \\\\(\\\\) called
Creating PluginTypeB Object:
TypeB1 init \\\\(\\\\) called
Call b.method_b \\\\(\\\\) from main app:
TypeB1.method_b \\\\(\\\\) called TypeB1.method_b \\\\(\\\\) called
TypeB1 returned string Returned String: TypeB1 returned string
TypeB1 deinit" Destroing PluginTypeB Object:
TypeB1 deinit \\\\(\\\\) called"
) )
SET_TESTS_PROPERTIES(loader_test-SimpleLoaderTest PROPERTIES ENVIRONMENT "LANG=en") SET_TESTS_PROPERTIES(loader_test-SimpleLoaderTest PROPERTIES ENVIRONMENT "LANG=en")

View File

@ -3,8 +3,16 @@ using GObject.Plugins;
static Gee.ArrayList<Module> type_a_modules = null; static Gee.ArrayList<Module> type_a_modules = null;
static Gee.ArrayList<Module> type_b_modules = null; static Gee.ArrayList<Module> type_b_modules = null;
class LoaderTestHost : Object, IHost, IHostLoaderTest {
public void method_host () {
stdout.puts ("LoaderTestHost.method_host () called\n");
}
}
int main (string [] args) { int main (string [] args) {
var h = new LoaderTestHost ();
GObject.Plugins.load_modules ( GObject.Plugins.load_modules (
Path.build_path (Path.DIR_SEPARATOR_S, File.new_for_path ( Path.build_path (Path.DIR_SEPARATOR_S, File.new_for_path (
args[0]).get_parent ().get_parent ().get_path (), "test/plugins/typeA"), args[0]).get_parent ().get_parent ().get_path (), "test/plugins/typeA"),
@ -18,23 +26,32 @@ int main (string [] args) {
); );
// Show Modules List // Show Modules List
stdout.puts ("List Plugins:\n");
foreach (var m in type_a_modules) { foreach (var m in type_a_modules) {
stdout.printf ("Plugin Type Name = " + m.get_plugin_type ().name () + "\n"); stdout.printf (" Name = " + m.get_plugin_type ().name () + "\n");
} }
foreach (var m in type_b_modules) { foreach (var m in type_b_modules) {
stdout.printf ("Plugin Type Name = " + m.get_plugin_type ().name () + "\n"); stdout.printf (" Name = " + m.get_plugin_type ().name () + "\n");
} }
// Create a new Plugin Instance by Object.new () method // Create a new Plugin Instance by Object.new () method
var a = type_a_modules[0].create_instance () as PluginTypeA; stdout.puts ("Creating PluginTypeA Object:\n ");
var a = type_a_modules[0].create_instance (h) as PluginTypeA;
stdout.puts ("Call a.method_a () from main app:\n ");
a.method_a (); a.method_a ();
a = null; // free last instance, plugin unload stdout.puts ("Destroing PluginTypeA Object:\n ");
a = null;
// Create a new Plugin Instance by Plugin Type // Create a new Plugin Instance by Plugin Type
stdout.puts ("Creating PluginTypeB Object:\n ");
var b = GLib.Object.new (Type.from_name (type_b_modules[0].get_plugin_type ().name ())) as PluginTypeB; var b = GLib.Object.new (Type.from_name (type_b_modules[0].get_plugin_type ().name ())) as PluginTypeB;
stdout.puts (b.method_b () + "\n"); b.host = h;
b = null; // free last instance, plugin unload stdout.puts ("Call b.method_b () from main app:\n ");
stdout.puts (" Returned String: " + b.method_b () + "\n");
stdout.puts ("Destroing PluginTypeB Object:\n ");
b = null;
// Unload modules
GObject.Plugins.unload_modules (type_a_modules); GObject.Plugins.unload_modules (type_a_modules);
GObject.Plugins.unload_modules (type_b_modules); GObject.Plugins.unload_modules (type_b_modules);

View File

@ -3,10 +3,13 @@ FILE (GLOB_RECURSE PluginSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} TypeA1.val
SET (PluginCustomVapis SET (PluginCustomVapis
${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
) )
SET (PluginLinkLibs gobject-plugin-iface loader_test-iface) SET (PluginLinkLibs gobject-plugin-iface loader_test-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/test/loader_test-iface") "${CMAKE_BINARY_DIR}/test/loader_test-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaPluginCommonRules) INCLUDE (ValaPluginCommonRules)
#INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName}) #INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName})

View File

@ -9,21 +9,23 @@ public class TypeA1 : PluginTypeA {
* Constructs a new ``TypeA1``. * Constructs a new ``TypeA1``.
*/ */
construct { construct {
stdout.puts ("TypeA1 init\n"); stdout.puts ("TypeA1 init () called\n");
} }
/** /**
* Destroys the ``TypeA1``. * Destroys the ``TypeA1``.
*/ */
~Test () { ~Test () {
stdout.puts ("TypeA1 deinit\n"); stdout.puts ("TypeA1 deinit () called\n");
} }
/** /**
* Any virtual method for PluginTypeA. * Any abstract method realization for PluginTypeA.
*/ */
public override void method_a () { public override void method_a () {
stdout.puts ("TypeA1.method_a () called\n"); stdout.puts ("TypeA1.method_a () called\n");
stdout.puts ("Call IHostLoaderTest.method_host () from TypeA1:\n ");
(host as IHostLoaderTest).method_host ();
} }
} }

View File

@ -3,10 +3,13 @@ FILE (GLOB_RECURSE PluginSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} TypeA2.val
SET (PluginCustomVapis SET (PluginCustomVapis
${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
) )
SET (PluginLinkLibs gobject-plugin-iface loader_test-iface) SET (PluginLinkLibs gobject-plugin-iface loader_test-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/test/loader_test-iface") "${CMAKE_BINARY_DIR}/test/loader_test-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaPluginCommonRules) INCLUDE (ValaPluginCommonRules)
#INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName}) #INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName})

View File

@ -9,18 +9,18 @@ public class TypeA2 : PluginTypeA {
* Constructs a new ``TypeA2``. * Constructs a new ``TypeA2``.
*/ */
construct { construct {
stdout.puts ("TypeA2 init\n"); stdout.puts ("TypeA2 init () called\n");
} }
/** /**
* Destroys the ``TypeA2``. * Destroys the ``TypeA2``.
*/ */
~Test () { ~Test () {
stdout.puts ("TypeA2 deinit\n"); stdout.puts ("TypeA2 deinit () called\n");
} }
/** /**
* Any virtual method for PluginTypeA. * Any abstract method realization for PluginTypeA.
*/ */
public override void method_a () { public override void method_a () {
stdout.puts ("TypeA2.method_a () called\n"); stdout.puts ("TypeA2.method_a () called\n");

View File

@ -3,10 +3,13 @@ FILE (GLOB_RECURSE PluginSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} TypeB1.val
SET (PluginCustomVapis SET (PluginCustomVapis
${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
) )
SET (PluginLinkLibs gobject-plugin-iface loader_test-iface) SET (PluginLinkLibs gobject-plugin-iface loader_test-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/test/loader_test-iface") "${CMAKE_BINARY_DIR}/test/loader_test-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaPluginCommonRules) INCLUDE (ValaPluginCommonRules)
#INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName}) #INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName})

View File

@ -9,18 +9,18 @@ public class TypeB1 : PluginTypeB {
* Constructs a new ``TypeB1``. * Constructs a new ``TypeB1``.
*/ */
construct { construct {
stdout.puts ("TypeB1 init\n"); stdout.puts ("TypeB1 init () called\n");
} }
/** /**
* Destroys the ``TypeB1``. * Destroys the ``TypeB1``.
*/ */
~Test () { ~Test () {
stdout.puts ("TypeB1 deinit\n"); stdout.puts ("TypeB1 deinit () called\n");
} }
/** /**
* Any virtual method for PluginTypeB. * Any abstract method realization for PluginTypeB.
*/ */
public override string method_b () { public override string method_b () {
stdout.puts ("TypeB1.method_b () called\n"); stdout.puts ("TypeB1.method_b () called\n");

View File

@ -3,10 +3,13 @@ FILE (GLOB_RECURSE PluginSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} TypeB2.val
SET (PluginCustomVapis SET (PluginCustomVapis
${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/src/plugin-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi ${CMAKE_BINARY_DIR}/test/loader_test-iface/loader_test-iface-${MAJOR}.vapi
${CMAKE_BINARY_DIR}/src/host-iface/${PROJECT_LOWERCASE_NAME}-host-iface-${MAJOR}.vapi
) )
SET (PluginLinkLibs gobject-plugin-iface loader_test-iface) SET (PluginLinkLibs gobject-plugin-iface loader_test-iface)
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface") INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/plugin-iface"
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/test/loader_test-iface") "${CMAKE_BINARY_DIR}/test/loader_test-iface"
"${CMAKE_BINARY_DIR}/src/host-iface"
)
INCLUDE (ValaPluginCommonRules) INCLUDE (ValaPluginCommonRules)
#INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName}) #INSTALL (TARGETS ${PluginName} DESTINATION lib/${PROJECT_LOWERCASE_NAME}-${MAJOR}/plugins/${PluginName})

View File

@ -9,18 +9,18 @@ public class TypeB2 : PluginTypeB {
* Constructs a new ``TypeB2``. * Constructs a new ``TypeB2``.
*/ */
construct { construct {
stdout.puts ("TypeB2 init\n"); stdout.puts ("TypeB2 init () called\n");
} }
/** /**
* Destroys the ``TypeB2``. * Destroys the ``TypeB2``.
*/ */
~Test () { ~Test () {
stdout.puts ("TypeB2 deinit\n"); stdout.puts ("TypeB2 deinit () called\n");
} }
/** /**
* Any virtual method for PluginTypeB. * Any abstract method realization for PluginTypeB.
*/ */
public override string method_b () { public override string method_b () {
stdout.puts ("TypeB2.method_b () called\n"); stdout.puts ("TypeB2.method_b () called\n");