/* Copyright 2008,2009,2010 Edwin Eefting (edwin@datux.nl)
This file is part of Synapse.
Synapse is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Synapse is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Synapse. If not, see . */
//this header file includes all the headers that are needed to compile a synapse module
//TODO: split this up in 2 header files: one for the module init stuff and another thats a real header that can be included multiple times.
#include "cmsg.h"
#include "clog.h"
#include "cmodule.h"
#include "cmessageman.h"
#include
#include
namespace synapse
{
#ifdef SYNAPSE_HAS_INIT
void init();
#endif
//basic objects that are needed to call send messages
weak_ptr module; //weak pointer, otherwise the reference count would be of by one when unloading a module.
CmessageMan * messageMan;
// Thanks to hkaiser@#boost for helping me with the automatic handler registration:
struct synapseAutoReg
{
synapseAutoReg(char const* name)
{
handlers.push_back(name);
}
static list handlers;
};
list synapseAutoReg::handlers;
//This stores the handler in a list by constructing a dummy object:
#define SYNAPSE_REGISTER(name) \
synapse::synapseAutoReg BOOST_PP_CAT(synapse_autoreg_, name)(#name); \
SYNAPSE_HANDLER(name)
//to determine compatability of module:
extern "C" int synapseVersion() {
return (SYNAPSE_API_VERSION);
};
extern "C" bool synapseInit(CmessageMan * initMessageMan, CmodulePtr initModule)
{
messageMan=initMessageMan;
module=initModule;
//when this function is called we have a core-lock, so we can register our handlers directly:
BOOST_FOREACH(string handler, synapseAutoReg::handlers)
{
((CmodulePtr)module)->setHandler(handler, handler);
}
synapseAutoReg::handlers.clear();
//this module has its own init function?
#ifdef SYNAPSE_HAS_INIT
init();
#endif
return true;
}
extern "C" void synapseCleanup()
{
//nothing to do yet..
}
//make a copy of the message (can expensive for complex message structures)
//and send a smartpointer of it to the core.
//sendPtr should be defined in each module in synapse.h
//you CANT send messages from the core with this funtion, you'll get an 'undefined reference'. :)
void Cmsg::send(int cookie)
{
lock_guard lock(messageMan->threadMutex);
messageMan->sendMessage((CmodulePtr)module,CmsgPtr(new Cmsg(*this)), cookie);
}
/*!
\fn Cmsg::returnError(string error)
*/
void Cmsg::returnError(string description)
{
if (description!="")
{
ERROR("while handling " << event << ": " << description);
Cmsg error;
error.event="module_Error";
error.dst=src;
error.src=dst;
error["event"]=event;
error["description"]=description;
error["parameters"]=*this;
error.send();
}
}
bool Cmsg::returnIfOtherThan(char * keys, ...)
{
va_list args;
va_start(args,keys);
char * key=keys;
unsigned int found=0;
do
{
if (isSet(key))
{
found++;
}
}
while ((key=va_arg(args,char *))!=NULL);
va_end(args);
if (((CvarMap)(*this)).size()>found)
{
returnError("Extra parameters found");
return true;
}
return false;
}
}