A HelloWorld Program
You can see the complete source code for this tutorial at github.com.
https://github.com/hkhandan/knorba-are/tree/master/src/demo/Hello.kap
The Header (HelloAgent.h)
To make a new agent type, you need to make a subclass of knorba::Agent (line 10). The runtime will provide you with a reference of knorba::Runtime as an interface to be used to access its feature. More importantly it provices each instance of your agents with a globall-unique identifier or GUID. Your agent constructor (line 24) should receive these information to later pass them on the the constructor of Agent class.
Agents communicate by exchanging messages. Each message type is identifed by an opcode. Think of opcode as equivalan of function/method name. OP_SAY (line 14) is the opcode we will use for the only message type used in this example. knorba::KString class provides an API to represent a sting in KnoRBA format. kfoundation::SPtr<T> template defines a static managed pointer.
Next we need someting to handle this kind of message with, should one of them received by our agent. For that we need a message handler as defined in line 29. Message hanlders have a fixed signiture and always receive kfoundation::PPtr<knorba::Message> as input argument.
In this example we will send some text to system's default ConsoleAgent to display. ConsoleProtocolClient (line 19) encapsulates all the message opcode necessary for doing that, and provides us with simple API to communicate with console, even if we don't know the proper opcode and message formats.
Since our agent is compiled into a dynamic/shared library, we need to provide a plain entry point for it. init() and instantiate() functions (lines 33 and 34) are standard functions that are called by ARE to instantiate an agent. They should be present in every agent code.
HelloAgent.cpp
As you can see in line 15, OP_SAY is defined as a dot-separated string. It is essential to do so to ensure message types do not conflict with other developers. We use a Java-line convention for naming our messages.
Line 18 would be our constructor that passed runtime interface and GUID to the Agent class's constructor. Each instance of any protocol needs atleast a pointer to an agent that uses it. That is done for our instance of ConsoleProtocolClient at line 20.
In line 22, the console server is set to the GUID of the default console agent provided by the ARE. Although, this is done automatically even if you don't explicitly write it.
Line 23 is the most important so far. It states that, everytime a message with opcode "demo.hello.say" is received, the opSayHandler() should be called to handler it.
In HelloAgent::opSayHandler(), we ask _pConsole to send "Hello World!" string to be printed. You could do it directly, if you knew the message opcode. For example, the following lines would do the same:
Ptr<KString> opPrint = new KString("knorba.console.print");
Ptr<KString> hello = new KString("Hello World!);
send(getRuntime().getConsoleGuid(), opPrint, new KString("Hello World"));
Callig quit() will terminate your agent and ARE will release the resources used by it. Your is considered finished only when all agents in your program are terminated. So if you don't call quit() your agent will be forever alive until the ARE is shutdown.
Line 33 to 42 define the standard entry points for ARE to init and instantiate your agent. The init() function is called only once per agent type and its job is to register message types used bu this agent.
Compiling and Running
Take a look at the CMakeLists.txt file to see what is needed to compiler the program. You may just go ahead and use this file directly to compile and build your program.
Otherwise you need to do a few steps manually. After compiling your agent as a shared/dynamic library, you need to create a directory called "Hello.kap" (or anything .kap). Create another directory in Hello.kap called "bin" and put your agent binary inside it. You need to provide a manifesto.xml file in Hello.kap as well. This file would look like this:
Line 2 loads the agent class. Line 3 makes a new instance of it called "bimo" (named after Beemo). And lines 4~6 would send a stimulation needed for our agent to do something, which is a message with a familiar opcode, containing nothing. This message is sent on behalf of runtime's special KernelAgent.
To run the program you need to start the kernel first by running
$[ARE-install-path]/are start
ARE is meant to be a deamon -- and eventually a part of your OS -- but for sake of easy debuggin in beta version it retains the console to print messages. So, you need to open another console to run your program.
$[ARE-install-path]/are run Hello.kap
Typing the extention is not necessary. Watch the following video to see how it workd: