-
Notifications
You must be signed in to change notification settings - Fork 29
Knowledge processing machine
Content
Knowledge processing machine (KPM) - is a set of modules. Each module contains implementation of sc-agents. Also they can contains any other functions and classes, than used by sc-agents implementation.
Module - is a dynamic library. That implement specified module class. To create module you need to do next steps:
- Create directory for you module in sc-kpm. For example:
sc-kpm/nl; - Go to created directory;
- Create file
CMakeLists.txtwith content (replace nl (module name) to yours one:
CMakeLists.txt
set(SC_IOT_SRC "${SC_KPM_ROOT}/nl")
set(SOURCES
"nl.cpp"
)
set(HEADERS
"nl.hpp"
)
include_directories(${SC_IOT_SRC} ${SC_MEMORY_SRC} ${GLIB2_INCLUDE_DIRS})
add_library (nl SHARED ${SOURCES} ${HEADERS})
add_dependencies(nl sc-memory-cpp sc-kpm-common)
target_link_libraries(nl sc-memory-cpp sc-kpm-common)
sc_codegen(nl ${SC_IOT_SRC})After that you need to create two files (cpp, hpp):
nl.hpp
#pragma once
#include "sc_memory.h"
#include "cpp/sc_module.hpp"
#include "nl.generated.hpp"
class nlModule : public ScModule
{
SC_CLASS(LoadOrder(11))
SC_GENERATED_BODY()
sc_result initializeImpl();
sc_result shutdownImpl();
};nl.cpp
#include "nl.hpp"
SC_IMPLEMENT_MODULE(nlModule)
sc_result nlModule::initializeImpl()
{
return SC_RESULT_OK;
}
sc_result nlModule::shutdownImpl()
{
return SC_RESULT_OK;
}To create sc-agent implementation you need:
- create source and header file for sc-agent implementation
- add created files into
CMakeLists.txt
CMakeLists.txt
...
set(SOURCES
"nl.cpp"
"nlApiAi.cpp"
)
set(HEADERS
"nl.hpp"
"nlApiAi.hpp"
)
...nlApiAi.hpp
#pragma once
#include "wrap/kpm/sc_agent.hpp"
#include "nlApiAi.generated.hpp"
namespace nl
{
class AApiAiParseUserTextAgent : public ScAgentAction
{
SC_CLASS(Agent, CmdClass("command_process_user_text_message"))
SC_GENERATED_BODY()
};
}nlApiAi.cpp
#include "nlApiAi.hpp"
namespace nl
{
SC_AGENT_ACTION_IMPLEMENTATION(AApiAiParseUserTextAgent)
{
// implement agent logic there
return SC_RESULT_ERROR;
}
}SC_AGENT_ACTION_IMPLEMENTATION - is a macros that insert generated code an minimize work. You just insert this one (with class name as parameter), and implement it like a function. During implementation you can use such variables:
-
requestAddr-ScAddrof command (action) instance that was initiated; -
resultAddr-ScAddrof sc-structure that designate command (action) result; -
mMemoryCtx- memory context that can be used to work withScMemory.
If sc-agent finished work without any errors, then it must return SC_RESULT_OK, otherwise - one of code error SC_RESULT_ERROR_...
It's important:
- All sc-agents class names must to be started with A symbol;
- You can implement more than one
ScAgentclass in on source/header file; - Don't use any other memory contexts instead of
mMemoryCtxinScAgentimplementation; - You need always include
<you_header>.generated.hppfile into your header, if you have any metadata. This include must be a last one in a file.
This type of objects allows you to subscribe to any events in ScMemory. There are c++ classes that correspond to specified event types:
-
ScEventAddOutputEdge- emits each time, when output (outgoing) edge (from specified element) added; -
ScEventAddInputEdge- emits each time, when input (ingoing) edge (into specified element) added; -
ScEventRemoveOutputEdge- emits each time, when output (outgoing) edge (from specified element) removed; -
ScEventRemoveInputEdge- emits each time, when input (ingoing) edge (into specified element) removed; -
ScEventEraseElement- emits, when specified element removed; -
ScEventContentChanged- emits each time, when content of specified sc-link changed.
Each event constructor takes 3 parameters:
-
ctx-ScMemoryContextthat will be used to work with event; -
addr-ScAddrof element that need to be listen for a specified event; -
func- delegate to a callback function, that will be called on each event emit (bool func(ScAddr const & listenAddr, ScAddr const & edgeAddr, ScAddr const & otherAddr)). Description of parameters for this function you can see in table below (for each event type). Note: callback function will be called in another thread!
Table of description (parameters of callback function named on pictures, if there are no parameter name on picture, then it's would have an empty value):
| Class | Description |
|---|---|
| ScEventAddOutputEdge |
Callback calls each time, when any type edge edgeAddr between listenAddr and otherAddr create.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of source element
// (listen it in event)
// edgeAddr - ScAddr of added output edge
// otherAddr - target element of added edge
...
return true; // if failed, then return false
};
ScEventAddOutputEdge evt(ctx, addr, callback);
|
| ScEventAddInputEdge |
Callback calls each time, when any type edge edgeAddr between otherAddr and listenAddr create.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of target element
// (listen it in event)
// edgeAddr - ScAddr of added input edge
// otherAddr - source element of added edge
...
return true; // if failed, then return false
};
ScEventAddInputEdge evt(ctx, addr, callback);
|
| ScEventRemoveOutputEdge |
Callback calls each time, when any type edge edgeAddr between listenAddr and any element otherAddr erase.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of source element
// (listen it in event)
// edgeAddr - ScAddr of erased output edge
// otherAddr - target element of erased edge
...
return true; // if failed, then return false
};
ScEventRemoveOutputEdge evt(ctx, addr, callback);
|
| ScEventRemoveInputEdge |
Callback calls each time, when any type edge edgeAddr between any element otherAddr and listenAddr erase.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of target element
// (listen it in event)
// edgeAddr - ScAddr of erased input edge
// otherAddr - source element of erased edge
...
return true; // if failed, then return false
};
ScEventRemoveOutputEdge evt(ctx, addr, callback);
|
| ScEventEraseElement |
Callback calls when listenAddr erased.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of erased element
// (listen it in event)
// edgeAddr - empty
// otherAddr - empty
...
return true; // if failed, then return false
};
ScEventEraseElement evt(ctx, addr, callback);
|
| ScEventContentChanged |
Callback calls when content of listenAddr changed.
Example C++ code: auto const callback [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
// listenAddr - ScAddr of element that has
// content changed (listen it in event)
// edgeAddr - empty
// otherAddr - empty
...
return true; // if failed, then return false
};
ScEventContentChanged evt(ctx, addr, callback);
|
This type of objects used to wait until some event emits. It usually used, when on of an ScAgent want to wait result of another one. There are next kind of ScWait objects:
-
ScWait- lock run flow until simple event emits. You can see the list of this events in the Class propertires table (Event property); -
ScWaitCondition- lock run flow until simple event emits and specified conditional check returns true. Another words, this works like anScWait, but returns to run flow if special condition function returns true. Condition function receive 3 parameters (see ScEvent for more details about them); -
ScWaitConstruction- wait object, that wait until specified construction would be appeared in a memory. (Not implemented yet)
There are some examples of usage for specified ScWait objects:
Wait input edge into addr
ScWait<ScEventAddInputEdge> waiter(ctx, addr);
waiter.Wait();Wait input edge into addr, with condition
auto check = [](ScAddr const & listenAddr,
ScAddr const & edgeAddr,
ScAddr const & otherAddr)
{
... // check condition there
return false; // return true or false depending on condition
};
ScWaitCondition<ScEventAddInputEdge> waiter(ctx, addr, SC_WAIT_CHECK(check));
waiter.Wait();There are some preimplemented most common waiters:
-
ScWaitActionFinished- wait until specifiedcommandwill be finished. Example:
...
ScWaitActionFinished waiter(ctx, commandAddr);
waiter.Wait();
...