A module is a way to organise your code.
A module can contain:
Warning
Constants are a work in progress. This needs a protocol change.
Modules are cross-language, you can define a module in C++ and use it in python or the reverse. They can be used at runtime, so you can import a module and use it without knowing it previously.
Global Namespaces
namespace qi
Classes (namespace qi)
class qi::AnyModule
Functions (class qi::AnyModule)
Members (class qi::AnyModule)
class qi::ModuleBuilder
Functions (class qi::ModuleBuilder)
Members (class qi::ModuleBuilder)
class qi::ModuleInfo
Members (class qi::ModuleInfo)
Functions (namespace qi)
Lets create a simple foo module, with a Foo class and an egg function.
Here is the content of foo.cpp:
#include <qi/session.hpp>
#include <qi/anymodule.hpp>
using namespace qi;
//the foo class takes a SessionPtr as parameter
class Foo {
public:
Foo(const SessionPtr& session)
: _session(session)
{}
void bar() {
}
private:
SessionPtr _session;
};
QI_REGISTER_OBJECT(Foo, bar);
//a simple egg function
void eggFun() {
}
void register_foo_module(qi::ModuleBuilder* mb) {
mb->advertiseMethod("egg", &eggFun);
mb->advertiseFactory<Foo, const SessionPtr&>("Foo");
}
QI_REGISTER_MODULE("foo", ®ister_foo_module);
Now let us write a CMakeLists.txt to compile it:
cmake_minimum_required(VERSION 2.8)
project(foo-module)
find_package(qibuild)
find_package(qimodule)
qi_sanitize_compile_flags(HIDDEN_SYMBOLS)
qi_create_module(foo SRC foo.cpp)
You can inspect your module content using qicli:
qicli mod foo
Let’s create a simple binary that will load the foo module, instantiate a Foo object and register it as a “Foo” service.
footest.cpp content:
#include <qi/applicationsession.hpp>
#include <qi/anymodule.hpp>
using namespace qi;
int main(int argc, char** argv) {
ApplicationSession app(argc, argv);
//connect the session
app.start();
// Register the Foo object as a service
// loadService will automatically give the session as the first parameter
// of the foo.Foo factory.
app.session()->loadService("foo.Foo");
// Then simply run the application (wait for it to end)
app.run();
}
Or the same code done by hand.
#include <qi/applicationsession.hpp>
#include <qi/anymodule.hpp>
using namespace qi;
int main(int argc, char** argv) {
ApplicationSession app(argc, argv);
//connect the session
app.start();
// Register the module on the session by hand
// import the module
AnyModule foomod = qi::import("foo");
// create a Foo object
AnyObject ao = foomod.call<AnyObject>("Foo", app.session());
// register the object on the Session with the name "Foo"
app.session()->registerService("Foo", ao);
// Then simply run the application (wait for finish)
app.run();
}
Let’s add a line in the CMakeLists.txt to create a binary:
qi_create_bin(footest footest.cpp DEPENDS QI)
To try your new Foo service you can start it as a standalone session
footest --qi-standalone
#if you would like to register it on a running session then do
footest --qi-url=tcp://<myip>:port
Finally you can use qicli info to inspect your module
qicli info Foo
Module support is language specific. For each language a module factory plug-in should be written.
The plug-in should provide a module factory function and register it using a macro. It receives a ModuleInfo
which is the module to load and must return the loaded module.
AnyModule mylangModuleFactory(const qi::ModuleInfo& moduleInfo);
QI_REGISTER_MODULE_FACTORY_PLUGIN("mylang", &mylangModuleFactory);
To find modules, the import function will start by looking at *.mod files in share/qi/module.
This file indicates which module factory to use. From this module factory, a ModuleInfo
is constructed and given to the right language factory function that should return a valid AnyModule
.
_moduleInfo
_object
_mod
ModuleBuilder
(const ModuleInfo& mi)setModuleInfo
(const ModuleInfo& mi)setModulePath
(const std::string& name)moduleInfo
()moduleName
() constmodule
()class given to the user to building a module
qi::ModuleBuilder::
_moduleInfo
¶qi::ModuleBuilder::
_object
¶qi::ModuleBuilder::
_mod
¶qi::ModuleBuilder::
ModuleBuilder
(const ModuleInfo& mi)¶qi::ModuleBuilder::
setModuleInfo
(const ModuleInfo& mi)¶qi::ModuleBuilder::
setModulePath
(const std::string& name)¶qi::ModuleBuilder::
moduleInfo
()¶qi::ModuleBuilder::
moduleName
() const
¶qi::ModuleBuilder::
module
()¶_moduleInfo
AnyModule
()AnyModule
(const ModuleInfo& moduleInfo, const qi::AnyObject& object)moduleName
() constmoduleInfo
() constA qi Module. basically an Object and a ModuleInfo
qi::import
qi::
listModules
()¶list all available modules (cross language