Custom event and stuff

This commit is contained in:
Perttu Ahola 2014-09-17 02:18:03 +03:00
parent 47f13e5204
commit 5004d1e156
12 changed files with 180 additions and 33 deletions

View File

@ -67,6 +67,7 @@ set(SERVER_SRCS
src/server/state.cpp
src/server/rccpp.cpp
src/impl/fs.cpp
src/impl/event.cpp
)
add_executable(${SERVER_EXE_NAME} ${SERVER_SRCS})
TARGET_LINK_LIBRARIES(${SERVER_EXE_NAME}

View File

@ -23,6 +23,8 @@ module
| `-- init.lua
|-- server
| `-- init.cpp
|-- include
| `-- public.h
`-- data
`-- media.png

View File

@ -1,7 +1,7 @@
#pragma once
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <exception>
#include <cstdint>
@ -14,7 +14,7 @@ typedef unsigned char uchar;
typedef std::string ss_;
template<typename T> using sv_ = std::vector<T>;
template<typename T> using set_ = std::set<T>;
template<typename T1, typename T2> using sm_ = std::map<T1, T2>;
template<typename T1, typename T2> using sm_ = std::unordered_map<T1, T2>;
typedef const char cc_;
static inline cc_* cs(const ss_ &s){ return s.c_str(); }
template<typename T> using up_ = std::unique_ptr<T>;

29
src/impl/event.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "interface/event.h"
namespace interface {
Event::Event(const ss_ &name, const sp_<Private> &p):
type(getGlobalEventRegistry()->type(name)), p(p)
{}
struct CEventRegistry: public EventRegistry
{
sm_<ss_, Event::Type> m_types;
Event::Type m_next_type = 0;
Event::Type type(const ss_ &name)
{
auto it = m_types.find(name);
if(it != m_types.end())
return it->second;
m_types[name] = m_next_type++;
return m_next_type - 1;
}
};
EventRegistry* getGlobalEventRegistry()
{
static CEventRegistry c;
return &c;
}
}

View File

@ -5,10 +5,23 @@ namespace interface
{
struct Event
{
enum class Type {
START,
} type;
std::stringstream data;
};
}
typedef size_t Type;
struct Private {
virtual ~Private(){}
};
Type type;
sp_<Private> p;
Event(): type(0) {}
Event(const Type &type): type(type) {}
Event(const Type &type, const sp_<Private> &p): type(type), p(p) {}
Event(const ss_ &name, const sp_<Private> &p=NULL);
};
struct EventRegistry
{
virtual Event::Type type(const ss_ &name) = 0;
};
EventRegistry* getGlobalEventRegistry();
}

View File

@ -3,10 +3,13 @@
namespace interface
{
struct Module;
struct Server
{
virtual ~Server(){}
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
virtual ss_ get_modules_path() = 0;
virtual Module* get_module(const ss_ &module_name) = 0;
};
}

View File

@ -14,6 +14,7 @@ struct CState: public State, public interface::Server
{
up_<rccpp::Compiler> m_compiler;
ss_ m_modules_path;
sm_<ss_, interface::Module*> m_modules;
CState():
m_compiler(rccpp::createCompiler())
@ -31,15 +32,20 @@ struct CState: public State, public interface::Server
std::cerr<<"Loading module "<<module_name<<" from "<<path<<std::endl;
ss_ build_dst = g_server_config.rccpp_build_path +
"/" + module_name + ".so";
m_compiler->include_directories.push_back(m_modules_path);
m_compiler->build(module_name, path+"/server/init.cpp", build_dst);
m_compiler->include_directories.pop_back();
interface::Module *m = static_cast<interface::Module*>(
m_compiler->construct(module_name.c_str(), this));
m_modules[module_name] = m;
//int a = m->test_add(1, 2);
//std::cout<<"a = "<<a<<std::endl;
interface::Event event;
event.type = interface::Event::Type::START;
m->event(event);
m->event(interface::Event("core:load_modules"));
m->event(interface::Event("core:start"));
}
void load_modules(const ss_ &path)
@ -47,14 +53,20 @@ struct CState: public State, public interface::Server
m_modules_path = path;
ss_ first_module_path = path+"/__loader";
load_module("__loader", first_module_path);
/*ss_ first_module_path2 = path+"/test1";
load_module("test1", first_module_path2);*/
}
ss_ get_modules_path()
{
return m_modules_path;
}
interface::Module* get_module(const ss_ &module_name)
{
auto it = m_modules.find(module_name);
if(it == m_modules.end())
return NULL;
return it->second;
}
};
State* createState()

View File

@ -1,6 +1,11 @@
#pragma once
#include "core/types.h"
namespace interface
{
struct Module;
}
namespace server
{
struct State
@ -8,6 +13,7 @@ namespace server
virtual ~State(){}
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
virtual void load_modules(const ss_ &path) = 0;
virtual interface::Module* get_module(const ss_ &module_name) = 0;
};
State* createState();

View File

@ -2,17 +2,21 @@
#include "interface/server.h"
#include "interface/fs.h"
#include "interface/event.h"
#include <cereal/archives/binary.hpp>
//#include <cereal/archives/binary.hpp>
#include <iostream>
using interface::Event;
namespace __loader {
struct Module: public interface::Module
{
interface::Server *m_server;
Event::Type m_EventType_core_load_modules;
Module(interface::Server *server):
m_server(server)
m_server(server),
m_EventType_core_load_modules(interface::getGlobalEventRegistry()->type("core:load_modules"))
{
std::cout<<"__loader construct"<<std::endl;
}
@ -24,10 +28,8 @@ struct Module: public interface::Module
void event(const interface::Event &event)
{
switch(event.type){
case Event::Type::START:
start();
break;
if(event.type == m_EventType_core_load_modules){
load_modules();
}
}
@ -36,20 +38,25 @@ struct Module: public interface::Module
return a + b;
}
void start()
void load_modules()
{
sv_<ss_> load_list = {"test1", "test2"};
for(const ss_ &name : load_list){
m_server->load_module(name, m_server->get_modules_path()+"/"+name);
}
/*// TODO: Dependencies
auto list = interface::getGlobalFilesystem()->list_directory(m_server->get_modules_path());
for(const interface::Filesystem::Node &n : list){
if(n.name == "__loader")
continue;
m_server->load_module(n.name, m_server->get_modules_path()+"/"+n.name);
}
}*/
}
};
extern "C" {
EXPORT void* createModule___loader(interface::Server *server)
{
return (void*)(new Module(server));
EXPORT void* createModule___loader(interface::Server *server){
return (void*)(new Module(server));
}
}
}

View File

@ -0,0 +1,11 @@
#include "interface/event.h"
namespace test1
{
struct Thing: public interface::Event::Private
{
ss_ some_data;
Thing(const ss_ &some_data="default value"): some_data(some_data) {}
};
}

View File

@ -1,13 +1,21 @@
#include "interface/module.h"
#include "interface/server.h"
#include "interface/event.h"
#include "test1/include/api.h"
#include <iostream>
using interface::Event;
namespace test1 {
struct Module: public interface::Module
{
Module()
interface::Server *m_server;
Event::Type m_EventType_test1_thing;
Module(interface::Server *server):
m_server(server),
m_EventType_test1_thing(interface::getGlobalEventRegistry()->type("test1:thing"))
{
std::cout<<"test1 construct"<<std::endl;
}
@ -19,10 +27,8 @@ struct Module: public interface::Module
void event(const interface::Event &event)
{
switch(event.type){
case Event::Type::START:
start();
break;
if(event.type == m_EventType_test1_thing){
thing(static_cast<Thing*>(event.p.get()));
}
}
@ -31,14 +37,15 @@ struct Module: public interface::Module
return a + b;
}
void start()
void thing(const Thing *thing)
{
std::cout<<"test1.thing: some_data="<<thing->some_data<<std::endl;
}
};
extern "C" {
EXPORT void* createModule_test1(interface::Server *server)
{
return (void*)(new Module());
EXPORT void* createModule_test1(interface::Server *server){
return (void*)(new Module(server));
}
}
}

View File

@ -0,0 +1,56 @@
#include "interface/module.h"
#include "interface/server.h"
#include "interface/event.h"
#include "test1/include/api.h"
#include <iostream>
#include <assert.h>
using interface::Event;
namespace test2 {
struct Module: public interface::Module
{
interface::Server *m_server;
Event::Type m_EventType_core_start;
Module(interface::Server *server):
m_server(server),
m_EventType_core_start(interface::getGlobalEventRegistry()->type("core:start"))
{
std::cout<<"test2 construct"<<std::endl;
}
~Module()
{
std::cout<<"test2 destruct"<<std::endl;
}
void event(const interface::Event &event)
{
if(event.type == m_EventType_core_start){
start();
}
}
int test_add(int a, int b)
{
return a + b;
}
void start()
{
interface::Module *m = m_server->get_module("test1");
assert(m);
interface::Event event("test1:thing");
event.p.reset(new test1::Thing("Nakki"));
m->event(event);
}
};
extern "C" {
EXPORT void* createModule_test2(interface::Server *server){
return (void*)(new Module(server));
}
}
}