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/state.cpp
src/server/rccpp.cpp src/server/rccpp.cpp
src/impl/fs.cpp src/impl/fs.cpp
src/impl/event.cpp
) )
add_executable(${SERVER_EXE_NAME} ${SERVER_SRCS}) add_executable(${SERVER_EXE_NAME} ${SERVER_SRCS})
TARGET_LINK_LIBRARIES(${SERVER_EXE_NAME} TARGET_LINK_LIBRARIES(${SERVER_EXE_NAME}

View File

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

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <unordered_map>
#include <set> #include <set>
#include <exception> #include <exception>
#include <cstdint> #include <cstdint>
@ -14,7 +14,7 @@ typedef unsigned char uchar;
typedef std::string ss_; typedef std::string ss_;
template<typename T> using sv_ = std::vector<T>; template<typename T> using sv_ = std::vector<T>;
template<typename T> using set_ = std::set<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_; typedef const char cc_;
static inline cc_* cs(const ss_ &s){ return s.c_str(); } static inline cc_* cs(const ss_ &s){ return s.c_str(); }
template<typename T> using up_ = std::unique_ptr<T>; 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 struct Event
{ {
enum class Type { typedef size_t Type;
START, struct Private {
} type; virtual ~Private(){}
std::stringstream data; };
}; 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 namespace interface
{ {
struct Module;
struct Server struct Server
{ {
virtual ~Server(){} virtual ~Server(){}
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0; virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
virtual ss_ get_modules_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; up_<rccpp::Compiler> m_compiler;
ss_ m_modules_path; ss_ m_modules_path;
sm_<ss_, interface::Module*> m_modules;
CState(): CState():
m_compiler(rccpp::createCompiler()) 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; std::cerr<<"Loading module "<<module_name<<" from "<<path<<std::endl;
ss_ build_dst = g_server_config.rccpp_build_path + ss_ build_dst = g_server_config.rccpp_build_path +
"/" + module_name + ".so"; "/" + 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->build(module_name, path+"/server/init.cpp", build_dst);
m_compiler->include_directories.pop_back();
interface::Module *m = static_cast<interface::Module*>( interface::Module *m = static_cast<interface::Module*>(
m_compiler->construct(module_name.c_str(), this)); m_compiler->construct(module_name.c_str(), this));
m_modules[module_name] = m;
//int a = m->test_add(1, 2); //int a = m->test_add(1, 2);
//std::cout<<"a = "<<a<<std::endl; //std::cout<<"a = "<<a<<std::endl;
interface::Event event;
event.type = interface::Event::Type::START; m->event(interface::Event("core:load_modules"));
m->event(event);
m->event(interface::Event("core:start"));
} }
void load_modules(const ss_ &path) void load_modules(const ss_ &path)
@ -47,14 +53,20 @@ struct CState: public State, public interface::Server
m_modules_path = path; m_modules_path = path;
ss_ first_module_path = path+"/__loader"; ss_ first_module_path = path+"/__loader";
load_module("__loader", first_module_path); load_module("__loader", first_module_path);
/*ss_ first_module_path2 = path+"/test1";
load_module("test1", first_module_path2);*/
} }
ss_ get_modules_path() ss_ get_modules_path()
{ {
return m_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() State* createState()

View File

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

View File

@ -2,17 +2,21 @@
#include "interface/server.h" #include "interface/server.h"
#include "interface/fs.h" #include "interface/fs.h"
#include "interface/event.h" #include "interface/event.h"
#include <cereal/archives/binary.hpp> //#include <cereal/archives/binary.hpp>
#include <iostream> #include <iostream>
using interface::Event; using interface::Event;
namespace __loader {
struct Module: public interface::Module struct Module: public interface::Module
{ {
interface::Server *m_server; interface::Server *m_server;
Event::Type m_EventType_core_load_modules;
Module(interface::Server *server): 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; std::cout<<"__loader construct"<<std::endl;
} }
@ -24,10 +28,8 @@ struct Module: public interface::Module
void event(const interface::Event &event) void event(const interface::Event &event)
{ {
switch(event.type){ if(event.type == m_EventType_core_load_modules){
case Event::Type::START: load_modules();
start();
break;
} }
} }
@ -36,20 +38,25 @@ struct Module: public interface::Module
return a + b; 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()); auto list = interface::getGlobalFilesystem()->list_directory(m_server->get_modules_path());
for(const interface::Filesystem::Node &n : list){ for(const interface::Filesystem::Node &n : list){
if(n.name == "__loader") if(n.name == "__loader")
continue; continue;
m_server->load_module(n.name, m_server->get_modules_path()+"/"+n.name); m_server->load_module(n.name, m_server->get_modules_path()+"/"+n.name);
} }*/
} }
}; };
extern "C" { extern "C" {
EXPORT void* createModule___loader(interface::Server *server) EXPORT void* createModule___loader(interface::Server *server){
{ return (void*)(new Module(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/module.h"
#include "interface/server.h" #include "interface/server.h"
#include "interface/event.h" #include "interface/event.h"
#include "test1/include/api.h"
#include <iostream> #include <iostream>
using interface::Event; using interface::Event;
namespace test1 {
struct Module: public interface::Module 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; std::cout<<"test1 construct"<<std::endl;
} }
@ -19,10 +27,8 @@ struct Module: public interface::Module
void event(const interface::Event &event) void event(const interface::Event &event)
{ {
switch(event.type){ if(event.type == m_EventType_test1_thing){
case Event::Type::START: thing(static_cast<Thing*>(event.p.get()));
start();
break;
} }
} }
@ -31,14 +37,15 @@ struct Module: public interface::Module
return a + b; return a + b;
} }
void start() void thing(const Thing *thing)
{ {
std::cout<<"test1.thing: some_data="<<thing->some_data<<std::endl;
} }
}; };
extern "C" { extern "C" {
EXPORT void* createModule_test1(interface::Server *server) EXPORT void* createModule_test1(interface::Server *server){
{ return (void*)(new Module(server));
return (void*)(new Module()); }
} }
} }

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));
}
}
}