Direct inter-module interface
This commit is contained in:
parent
14abc20e5f
commit
780db76d91
@ -71,6 +71,7 @@ set(SERVER_SRCS
|
||||
src/impl/fs.cpp
|
||||
src/impl/event.cpp
|
||||
src/impl/tcpsocket.cpp
|
||||
src/impl/module.cpp
|
||||
)
|
||||
add_executable(${SERVER_EXE_NAME} ${SERVER_SRCS})
|
||||
TARGET_LINK_LIBRARIES(${SERVER_EXE_NAME}
|
||||
|
@ -42,5 +42,13 @@ namespace network
|
||||
|
||||
Resp_get_packet_type(const Packet::Type &type): type(type){}
|
||||
};
|
||||
|
||||
struct Direct
|
||||
{
|
||||
virtual ~Direct(){}
|
||||
virtual Packet::Type packet_type(const ss_ &name) = 0;
|
||||
virtual void send(PeerInfo::Id recipient, const Packet::Type &type,
|
||||
const ss_ &data) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "interface/server.h"
|
||||
#include "interface/event.h"
|
||||
#include "interface/tcpsocket.h"
|
||||
#include "interface/mutex.h"
|
||||
#include "network/include/api.h"
|
||||
#include <iostream>
|
||||
|
||||
@ -21,14 +22,16 @@ struct Peer
|
||||
id(id), socket(socket){}
|
||||
};
|
||||
|
||||
struct Module: public interface::Module
|
||||
struct Module: public interface::Module, public network::Direct
|
||||
{
|
||||
interface::Mutex m_interface_mutex;
|
||||
interface::Server *m_server;
|
||||
sp_<interface::TCPSocket> m_listening_socket;
|
||||
sm_<Peer::Id, Peer> m_peers;
|
||||
size_t m_next_peer_id = 1;
|
||||
|
||||
Module(interface::Server *server):
|
||||
interface::Module("network"),
|
||||
m_server(server),
|
||||
m_listening_socket(interface::createTCPSocket())
|
||||
{
|
||||
@ -37,6 +40,8 @@ struct Module: public interface::Module
|
||||
|
||||
void init()
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
std::cout<<"network init"<<std::endl;
|
||||
m_server->sub_event(this, Event::t("core:start"));
|
||||
m_server->sub_event(this, Event::t("network:send"));
|
||||
@ -51,12 +56,19 @@ struct Module: public interface::Module
|
||||
|
||||
void event(const Event::Type &type, const Event::Private *p)
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
EVENT_VOIDN("core:start", on_start)
|
||||
EVENT_TYPEN("network:send", on_send_packet, Packet)
|
||||
EVENT_TYPEN("network:listen_event", on_listen_event, interface::SocketEvent)
|
||||
EVENT_TYPEN("network:get_packet_type", on_get_packet_type, Req_get_packet_type)
|
||||
}
|
||||
|
||||
void* get_interface()
|
||||
{
|
||||
return dynamic_cast<Direct*>(this);
|
||||
}
|
||||
|
||||
void on_start()
|
||||
{
|
||||
ss_ address = "any4";
|
||||
@ -102,6 +114,20 @@ struct Module: public interface::Module
|
||||
m_server->emit_event("network:get_packet_type_resp",
|
||||
new Resp_get_packet_type(type));
|
||||
}
|
||||
|
||||
// Direct interface
|
||||
|
||||
Packet::Type packet_type(const ss_ &name)
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
}
|
||||
|
||||
void send(PeerInfo::Id recipient, const Packet::Type &type, const ss_ &data)
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
// TODO
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
13
src/impl/module.cpp
Normal file
13
src/impl/module.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "interface/module.h"
|
||||
|
||||
namespace interface {
|
||||
|
||||
void* Module::check_interface()
|
||||
{
|
||||
void *i = get_interface();
|
||||
if(!i)
|
||||
throw Exception(ss_()+"Module \""+NAME+"\" has no interface");
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
@ -8,9 +8,14 @@ namespace interface
|
||||
{
|
||||
struct Module
|
||||
{
|
||||
const char *NAME = "(unknown module)";
|
||||
Module(const char *name): NAME(name){}
|
||||
virtual ~Module(){};
|
||||
virtual void init() = 0;
|
||||
// Never call directly; this is not thread-safe
|
||||
virtual void event(const Event::Type &type, const Event::Private *p) = 0;
|
||||
virtual void* get_interface(){
|
||||
return NULL;
|
||||
}
|
||||
void* check_interface();
|
||||
};
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ namespace interface
|
||||
virtual ss_ get_builtin_modules_path() = 0;
|
||||
virtual bool has_module(const ss_ &module_name) = 0;
|
||||
|
||||
virtual interface::Module* get_module(const ss_ &module_name) = 0;
|
||||
virtual interface::Module* check_module(const ss_ &module_name) = 0;
|
||||
|
||||
virtual void sub_event(struct Module *module, const Event::Type &type) = 0;
|
||||
virtual void emit_event(Event event) = 0;
|
||||
template<typename PrivateT>
|
||||
|
@ -18,11 +18,11 @@ namespace server {
|
||||
|
||||
struct CState: public State, public interface::Server
|
||||
{
|
||||
struct ModuleWithMutex {
|
||||
interface::Mutex mutex;
|
||||
struct ModuleContainer {
|
||||
//interface::Mutex mutex;
|
||||
interface::Module *module;
|
||||
|
||||
ModuleWithMutex(interface::Module *module = NULL): module(module){}
|
||||
ModuleContainer(interface::Module *module = NULL): module(module){}
|
||||
};
|
||||
|
||||
struct SocketState {
|
||||
@ -33,13 +33,13 @@ struct CState: public State, public interface::Server
|
||||
up_<rccpp::Compiler> m_compiler;
|
||||
ss_ m_modules_path;
|
||||
|
||||
sm_<ss_, ModuleWithMutex> m_modules;
|
||||
sm_<ss_, ModuleContainer> m_modules;
|
||||
interface::Mutex m_modules_mutex;
|
||||
|
||||
sv_<Event> m_event_queue;
|
||||
interface::Mutex m_event_queue_mutex;
|
||||
|
||||
sv_<sv_<ModuleWithMutex*>> m_event_subs;
|
||||
sv_<sv_<ModuleContainer*>> m_event_subs;
|
||||
interface::Mutex m_event_subs_mutex;
|
||||
|
||||
sm_<int, SocketState> m_sockets;
|
||||
@ -61,9 +61,9 @@ struct CState: public State, public interface::Server
|
||||
{
|
||||
interface::MutexScope ms(m_modules_mutex);
|
||||
for(auto &pair : m_modules){
|
||||
ModuleWithMutex &mwm = pair.second;
|
||||
ModuleContainer &mc = pair.second;
|
||||
// Don't lock; it would only cause deadlocks
|
||||
delete mwm.module;
|
||||
delete mc.module;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,12 +80,12 @@ struct CState: public State, public interface::Server
|
||||
|
||||
interface::Module *m = static_cast<interface::Module*>(
|
||||
m_compiler->construct(module_name.c_str(), this));
|
||||
m_modules[module_name] = ModuleWithMutex(m);
|
||||
m_modules[module_name] = ModuleContainer(m);
|
||||
|
||||
{
|
||||
ModuleWithMutex &mwm = m_modules[module_name];
|
||||
interface::MutexScope ms2(mwm.mutex);
|
||||
mwm.module->init();
|
||||
ModuleContainer &mc = m_modules[module_name];
|
||||
//interface::MutexScope ms2(mc.mutex);
|
||||
mc.module->init();
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,21 +112,21 @@ struct CState: public State, public interface::Server
|
||||
return g_server_config.share_path+"/builtin";
|
||||
}
|
||||
|
||||
/*interface::Module* get_module_u(const ss_ &module_name)
|
||||
interface::Module* get_module(const ss_ &module_name)
|
||||
{
|
||||
interface::MutexScope ms(m_modules_mutex);
|
||||
auto it = m_modules.find(module_name);
|
||||
if(it == m_modules.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
return it->second.module;
|
||||
}
|
||||
|
||||
interface::Module* check_module_u(const ss_ &module_name)
|
||||
interface::Module* check_module(const ss_ &module_name)
|
||||
{
|
||||
interface::Module *m = get_module(module_name);
|
||||
if(m) return m;
|
||||
throw ModuleNotFoundException(ss_()+"Module not found: "+module_name);
|
||||
}*/
|
||||
}
|
||||
|
||||
bool has_module(const ss_ &module_name)
|
||||
{
|
||||
@ -141,31 +141,31 @@ struct CState: public State, public interface::Server
|
||||
// Lock modules so that the subscribing one isn't removed asynchronously
|
||||
interface::MutexScope ms(m_modules_mutex);
|
||||
// Make sure module is a known instance
|
||||
ModuleWithMutex *mwm0 = NULL;
|
||||
ModuleContainer *mc0 = NULL;
|
||||
ss_ module_name = "(unknown)";
|
||||
for(auto &pair : m_modules){
|
||||
ModuleWithMutex &mwm = pair.second;
|
||||
if(mwm.module == module){
|
||||
mwm0 = &mwm;
|
||||
ModuleContainer &mc = pair.second;
|
||||
if(mc.module == module){
|
||||
mc0 = &mc;
|
||||
module_name = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(mwm0 == nullptr){
|
||||
if(mc0 == nullptr){
|
||||
std::cerr<<"sub_event(): Not a known module"<<std::endl;
|
||||
return;
|
||||
}
|
||||
interface::MutexScope ms2(m_event_subs_mutex);
|
||||
if(m_event_subs.size() <= type + 1)
|
||||
m_event_subs.resize(type + 1);
|
||||
sv_<ModuleWithMutex*> &sublist = m_event_subs[type];
|
||||
if(std::find(sublist.begin(), sublist.end(), mwm0) != sublist.end()){
|
||||
sv_<ModuleContainer*> &sublist = m_event_subs[type];
|
||||
if(std::find(sublist.begin(), sublist.end(), mc0) != sublist.end()){
|
||||
std::cerr<<"sub_event(): Already on list: "<<module_name<<std::endl;
|
||||
return;
|
||||
}
|
||||
std::cerr<<"sub_event(): "<<module_name<<" subscribed to "<<type <<
|
||||
std::endl;
|
||||
sublist.push_back(mwm0);
|
||||
sublist.push_back(mc0);
|
||||
}
|
||||
|
||||
void emit_event(Event event)
|
||||
@ -179,7 +179,7 @@ struct CState: public State, public interface::Server
|
||||
{
|
||||
for(size_t loop_i = 0;; loop_i++){
|
||||
sv_<Event> event_queue_snapshot;
|
||||
sv_<sv_<ModuleWithMutex*>> event_subs_snapshot;
|
||||
sv_<sv_<ModuleContainer*>> event_subs_snapshot;
|
||||
{
|
||||
interface::MutexScope ms2(m_event_queue_mutex);
|
||||
interface::MutexScope ms3(m_event_subs_mutex);
|
||||
@ -198,16 +198,16 @@ struct CState: public State, public interface::Server
|
||||
log_d("state", "handle_events(): %zu: No subs", event.type);
|
||||
continue;
|
||||
}
|
||||
sv_<ModuleWithMutex*> &sublist = event_subs_snapshot[event.type];
|
||||
sv_<ModuleContainer*> &sublist = event_subs_snapshot[event.type];
|
||||
if(sublist.empty()){
|
||||
log_d("state", "handle_events(): %zu: No subs", event.type);
|
||||
continue;
|
||||
}
|
||||
log_d("state", "handle_events(): %zu: Handling (%zu handlers)",
|
||||
event.type, sublist.size());
|
||||
for(ModuleWithMutex *mwm : sublist){
|
||||
interface::MutexScope mwm_ms(mwm->mutex);
|
||||
mwm->module->event(event.type, event.p.get());
|
||||
for(ModuleContainer *mc : sublist){
|
||||
//interface::MutexScope mc_ms(mc->mutex);
|
||||
mc->module->event(event.type, event.p.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ 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_u(const ss_ &module_name) = 0;
|
||||
//virtual interface::Module* check_module_u(const ss_ &module_name) = 0;
|
||||
virtual interface::Module* get_module(const ss_ &module_name) = 0;
|
||||
virtual interface::Module* check_module(const ss_ &module_name) = 0;
|
||||
virtual void sub_event(struct interface::Module *module,
|
||||
const interface::Event::Type &type) = 0;
|
||||
virtual void emit_event(interface::Event event) = 0;
|
||||
|
@ -13,6 +13,7 @@ struct Module: public interface::Module
|
||||
interface::Server *m_server;
|
||||
|
||||
Module(interface::Server *server):
|
||||
interface::Module("__loader"),
|
||||
m_server(server)
|
||||
{
|
||||
std::cout<<"__loader construct"<<std::endl;
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include "interface/module.h"
|
||||
#include "interface/server.h"
|
||||
#include "interface/event.h"
|
||||
#include "interface/mutex.h"
|
||||
#include "test1/include/api.h"
|
||||
#include "network/include/api.h"
|
||||
#include <iostream>
|
||||
//#include <dlfcn.h>
|
||||
|
||||
using interface::Event;
|
||||
|
||||
@ -11,6 +13,7 @@ namespace test1 {
|
||||
|
||||
struct Module: public interface::Module
|
||||
{
|
||||
interface::Mutex m_interface_mutex;
|
||||
interface::Server *m_server;
|
||||
|
||||
Event::Type m_EventType_test1_thing;
|
||||
@ -18,6 +21,7 @@ struct Module: public interface::Module
|
||||
network::Packet::Type m_NetworkPacketType_dummy_packet = 0;
|
||||
|
||||
Module(interface::Server *server):
|
||||
interface::Module("test1"),
|
||||
m_server(server),
|
||||
m_EventType_test1_thing(Event::t("test1:thing"))
|
||||
{
|
||||
@ -26,13 +30,25 @@ struct Module: public interface::Module
|
||||
|
||||
void init()
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
std::cout<<"test1 init"<<std::endl;
|
||||
m_server->sub_event(this, Event::t("core:start"));
|
||||
m_server->sub_event(this, m_EventType_test1_thing);
|
||||
m_server->sub_event(this, Event::t("network:new_client"));
|
||||
m_server->sub_event(this, Event::t("network:get_packet_type_resp"));
|
||||
|
||||
m_server->emit_event("network:get_packet_type",
|
||||
new network::Req_get_packet_type("test1:dummy_packet"));
|
||||
/*MAGIC("network:get_packet_type",
|
||||
new network::Req_get_packet_type("test1:dummy_packet"),
|
||||
[&](const network::Resp_get_packet_type &result){
|
||||
|
||||
});*/
|
||||
//network::cfoo();
|
||||
|
||||
/*void *m = dlopen("/home/celeron55/softat/buildat/cache/rccpp_build/network.so", RTLD_NOW);
|
||||
std::cout<<"m="<<m<<std::endl;*/
|
||||
}
|
||||
|
||||
~Module()
|
||||
@ -42,12 +58,24 @@ struct Module: public interface::Module
|
||||
|
||||
void event(const Event::Type &type, const Event::Private *p)
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
EVENT_VOIDN("core:start", on_start)
|
||||
EVENT_TYPE(m_EventType_test1_thing, on_thing, Thing)
|
||||
EVENT_TYPEN("network:new_client", on_new_client, network::NewClient)
|
||||
EVENT_TYPEN("network:get_packet_type_resp", on_get_packet_type_resp,
|
||||
network::Resp_get_packet_type)
|
||||
}
|
||||
|
||||
void on_start()
|
||||
{
|
||||
interface::Module *network_module = m_server->check_module("network");
|
||||
network::Direct *network_direct =
|
||||
(network::Direct*)network_module->check_interface();
|
||||
std::cout<<"Calling network_direct::foo()"<<std::endl;
|
||||
network_direct->foo();
|
||||
}
|
||||
|
||||
void on_thing(const Thing &thing)
|
||||
{
|
||||
std::cout<<"test1.thing: some_data="<<thing.some_data<<std::endl;
|
||||
@ -57,9 +85,9 @@ struct Module: public interface::Module
|
||||
{
|
||||
std::cout<<"test1::on_new_client: id="<<new_client.info.id<<std::endl;
|
||||
|
||||
m_server->emit_event("network:send",
|
||||
new network::Packet(new_client.info.id,
|
||||
m_NetworkPacketType_dummy_packet, "dummy data"));
|
||||
auto packet = new network::Packet(new_client.info.id,
|
||||
m_NetworkPacketType_dummy_packet, "dummy data");
|
||||
m_server->emit_event("network:send", packet);
|
||||
}
|
||||
|
||||
void on_get_packet_type_resp(const network::Resp_get_packet_type &event)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "interface/module.h"
|
||||
#include "interface/server.h"
|
||||
#include "interface/event.h"
|
||||
#include "interface/mutex.h"
|
||||
#include "test1/include/api.h"
|
||||
#include <iostream>
|
||||
|
||||
@ -10,10 +11,12 @@ namespace test2 {
|
||||
|
||||
struct Module: public interface::Module
|
||||
{
|
||||
interface::Mutex m_interface_mutex;
|
||||
interface::Server *m_server;
|
||||
Event::Type m_EventType_core_start;
|
||||
|
||||
Module(interface::Server *server):
|
||||
interface::Module("test2"),
|
||||
m_server(server),
|
||||
m_EventType_core_start(Event::t("core:start"))
|
||||
{
|
||||
@ -22,6 +25,8 @@ struct Module: public interface::Module
|
||||
|
||||
void init()
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
std::cout<<"test2 init"<<std::endl;
|
||||
m_server->sub_event(this, m_EventType_core_start);
|
||||
}
|
||||
@ -33,6 +38,8 @@ struct Module: public interface::Module
|
||||
|
||||
void event(const Event::Type &type, const Event::Private *p)
|
||||
{
|
||||
interface::MutexScope ms(m_interface_mutex);
|
||||
|
||||
if(type == m_EventType_core_start){
|
||||
on_start();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user