Loading net/include/net/index.hpp +4 −0 Original line number Diff line number Diff line #pragma once #include <com/context.hpp> #include <net/driver.hpp> #include <net/linking_context.hpp> #include <net/object_creation_registry.hpp> namespace net { Loading @@ -16,6 +17,7 @@ namespace net { RPCSystem* rpc_system() const { return m_rpc_system; } ObjectCreationRegistry* object_creation_registry() const { return m_object_creation_registry; } ObjectSystem* object_system() const { return m_object_system; } LinkingContext* linking_context() const { return m_linking_context; } private: Index(); Loading @@ -29,6 +31,7 @@ namespace net { RPCSystem* m_rpc_system; ObjectCreationRegistry* m_object_creation_registry; ObjectSystem* m_object_system; LinkingContext* m_linking_context; }; inline Index const& index() { return Index::instance(); } Loading @@ -38,4 +41,5 @@ namespace net { inline RPCSystem* rpc_system() { return index().rpc_system(); } inline ObjectCreationRegistry* object_creation_registry() { return index().object_creation_registry(); } inline ObjectSystem* object_system() { return index().object_system(); } inline LinkingContext* linking_context() { return index().linking_context(); } } net/include/net/linking_context.hpp 0 → 100644 +29 −0 Original line number Diff line number Diff line #pragma once #include <com/library.hpp> #include <net/file.hpp> namespace net { struct LinkingContext : public com::Library { const uint32_t INVALID_ID = 0; static inline std::string self_name() { return "linking_context.lib"; } LinkingContext(); ~LinkingContext() override; net::File* get_object(uint32_t id) const; uint32_t get_id(net::File* object) const; uint32_t insert_object(net::File* object); void register_object(uint32_t id, net::File* object); void remove_object(net::File* object); uint32_t allocate_id(); private: std::unordered_map<NetworkId, net::File*> m_id_to_object; std::unordered_map<net::File*, NetworkId> m_object_to_id; uint32_t m_id_counter; }; } net/include/net/object_system.hpp +35 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace net { * Only networked objects can have replicated properties. */ template<typename T> T* create_networked(const std::string& name, ConnectionId owner = 0); T* create_networked(ConnectionId owner = 0); /** * @brief SERVER ONLY: Destroys a networked object by its NetworkId. Loading @@ -35,17 +35,23 @@ namespace net { void handle_create(utils::Deserializer& deserializer); void handle_destroy(utils::Deserializer& deserializer); // In object_system.hpp /** * @brief Finds the first object owned by the specified connection. Returns nullptr if no such object exists. */ template<typename T> T* find_owned(ConnectionId owner); private: void broadcast_create(const std::string& name, uint32_t type_id, const NetworkIdentity* identity); void build_create_packet(utils::Serializer& s, const std::string& name, uint32_t type_id, void broadcast_create(uint32_t net_id, uint32_t type_id, const NetworkIdentity* identity); void build_create_packet(utils::Serializer& s, uint32_t net_id, uint32_t type_id, const NetworkIdentity* identity); com::Folder* m_objects; }; template<typename T> T* ObjectSystem::create_networked(const std::string& name, ConnectionId owner) T* ObjectSystem::create_networked(ConnectionId owner) { if (driver()->mode() != SocketMode::SERVER) { Loading @@ -54,11 +60,33 @@ namespace net { } static_assert(std::is_base_of_v<net::File, T>, "Type must be derived from net::File"); T* obj = static_cast<T*>(object_creation_registry()->create(T::m_type_id, objects(), name)); uint32_t net_id = linking_context()->allocate_id(); T* obj = static_cast<T*>(object_creation_registry()->create(T::m_type_id, objects(), std::to_string(net_id))); obj->identity()->owner = owner; obj->identity()->id = net_id; linking_context()->register_object(net_id, obj); broadcast_create(name, T::m_type_id, obj->identity()); broadcast_create(net_id, T::m_type_id, obj->identity()); return obj; } template<typename T> T* ObjectSystem::find_owned(ConnectionId owner) { for (auto file : objects()->files()) { if (auto* net_file = dynamic_cast<net::File*>(file)) { if (net_file->identity()->owner == owner) { if (auto* casted = dynamic_cast<T*>(net_file)) { return casted; } } } } return nullptr; } } net/src/index.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ #include <net/object_system.hpp> namespace net { Index const &Index::instance() { Index const& Index::instance() { static Index const idx; return idx; } Loading @@ -16,12 +16,14 @@ namespace net { , m_rpc_system{m_root->find<RPCSystem>(RPCSystem::self_name())} , m_object_creation_registry{m_root->find<ObjectCreationRegistry>(ObjectCreationRegistry::self_name())} , m_object_system{m_root->find<ObjectSystem>(ObjectSystem::self_name())} , m_linking_context{m_root->find<LinkingContext>(LinkingContext::self_name())} { ASSUMPTION( m_driver != nullptr && m_rpc_system != nullptr && m_object_creation_registry != nullptr && m_object_system != nullptr m_object_system != nullptr && m_linking_context != nullptr ); } } net/src/linking_context.cpp 0 → 100644 +71 −0 Original line number Diff line number Diff line #include <net/linking_context.hpp> using namespace net; uint32_t LinkingContext::insert_object(net::File* object) { ASSUMPTION(object != nullptr); ASSUMPTION(!m_object_to_id.contains(object)); auto new_id = allocate_id(); register_object(new_id, object); return new_id; } void LinkingContext::register_object(uint32_t id, net::File* object) { ASSUMPTION(object != nullptr); ASSUMPTION(id != INVALID_ID); m_id_to_object[id] = object; m_object_to_id[object] = id; } void LinkingContext::remove_object(net::File* object) { ASSUMPTION(object != nullptr); auto it = m_object_to_id.find(object); if (it != m_object_to_id.end()) { auto id = it->second; m_id_to_object.erase(id); m_object_to_id.erase(it); } } uint32_t LinkingContext::allocate_id() { return ++m_id_counter; } uint32_t LinkingContext::get_id(net::File* object) const { ASSUMPTION(object != nullptr); if (auto it = m_object_to_id.find(object); it != m_object_to_id.end()) { return it->second; } return INVALID_ID; } net::File* LinkingContext::get_object(uint32_t id) const { if (auto it = m_id_to_object.find(id); it != m_id_to_object.end()) { return it->second; } return nullptr; } LinkingContext::LinkingContext() : com::Library(self_name()), m_id_counter(0) { } LinkingContext::~LinkingContext() = default; Loading
net/include/net/index.hpp +4 −0 Original line number Diff line number Diff line #pragma once #include <com/context.hpp> #include <net/driver.hpp> #include <net/linking_context.hpp> #include <net/object_creation_registry.hpp> namespace net { Loading @@ -16,6 +17,7 @@ namespace net { RPCSystem* rpc_system() const { return m_rpc_system; } ObjectCreationRegistry* object_creation_registry() const { return m_object_creation_registry; } ObjectSystem* object_system() const { return m_object_system; } LinkingContext* linking_context() const { return m_linking_context; } private: Index(); Loading @@ -29,6 +31,7 @@ namespace net { RPCSystem* m_rpc_system; ObjectCreationRegistry* m_object_creation_registry; ObjectSystem* m_object_system; LinkingContext* m_linking_context; }; inline Index const& index() { return Index::instance(); } Loading @@ -38,4 +41,5 @@ namespace net { inline RPCSystem* rpc_system() { return index().rpc_system(); } inline ObjectCreationRegistry* object_creation_registry() { return index().object_creation_registry(); } inline ObjectSystem* object_system() { return index().object_system(); } inline LinkingContext* linking_context() { return index().linking_context(); } }
net/include/net/linking_context.hpp 0 → 100644 +29 −0 Original line number Diff line number Diff line #pragma once #include <com/library.hpp> #include <net/file.hpp> namespace net { struct LinkingContext : public com::Library { const uint32_t INVALID_ID = 0; static inline std::string self_name() { return "linking_context.lib"; } LinkingContext(); ~LinkingContext() override; net::File* get_object(uint32_t id) const; uint32_t get_id(net::File* object) const; uint32_t insert_object(net::File* object); void register_object(uint32_t id, net::File* object); void remove_object(net::File* object); uint32_t allocate_id(); private: std::unordered_map<NetworkId, net::File*> m_id_to_object; std::unordered_map<net::File*, NetworkId> m_object_to_id; uint32_t m_id_counter; }; }
net/include/net/object_system.hpp +35 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace net { * Only networked objects can have replicated properties. */ template<typename T> T* create_networked(const std::string& name, ConnectionId owner = 0); T* create_networked(ConnectionId owner = 0); /** * @brief SERVER ONLY: Destroys a networked object by its NetworkId. Loading @@ -35,17 +35,23 @@ namespace net { void handle_create(utils::Deserializer& deserializer); void handle_destroy(utils::Deserializer& deserializer); // In object_system.hpp /** * @brief Finds the first object owned by the specified connection. Returns nullptr if no such object exists. */ template<typename T> T* find_owned(ConnectionId owner); private: void broadcast_create(const std::string& name, uint32_t type_id, const NetworkIdentity* identity); void build_create_packet(utils::Serializer& s, const std::string& name, uint32_t type_id, void broadcast_create(uint32_t net_id, uint32_t type_id, const NetworkIdentity* identity); void build_create_packet(utils::Serializer& s, uint32_t net_id, uint32_t type_id, const NetworkIdentity* identity); com::Folder* m_objects; }; template<typename T> T* ObjectSystem::create_networked(const std::string& name, ConnectionId owner) T* ObjectSystem::create_networked(ConnectionId owner) { if (driver()->mode() != SocketMode::SERVER) { Loading @@ -54,11 +60,33 @@ namespace net { } static_assert(std::is_base_of_v<net::File, T>, "Type must be derived from net::File"); T* obj = static_cast<T*>(object_creation_registry()->create(T::m_type_id, objects(), name)); uint32_t net_id = linking_context()->allocate_id(); T* obj = static_cast<T*>(object_creation_registry()->create(T::m_type_id, objects(), std::to_string(net_id))); obj->identity()->owner = owner; obj->identity()->id = net_id; linking_context()->register_object(net_id, obj); broadcast_create(name, T::m_type_id, obj->identity()); broadcast_create(net_id, T::m_type_id, obj->identity()); return obj; } template<typename T> T* ObjectSystem::find_owned(ConnectionId owner) { for (auto file : objects()->files()) { if (auto* net_file = dynamic_cast<net::File*>(file)) { if (net_file->identity()->owner == owner) { if (auto* casted = dynamic_cast<T*>(net_file)) { return casted; } } } } return nullptr; } }
net/src/index.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ #include <net/object_system.hpp> namespace net { Index const &Index::instance() { Index const& Index::instance() { static Index const idx; return idx; } Loading @@ -16,12 +16,14 @@ namespace net { , m_rpc_system{m_root->find<RPCSystem>(RPCSystem::self_name())} , m_object_creation_registry{m_root->find<ObjectCreationRegistry>(ObjectCreationRegistry::self_name())} , m_object_system{m_root->find<ObjectSystem>(ObjectSystem::self_name())} , m_linking_context{m_root->find<LinkingContext>(LinkingContext::self_name())} { ASSUMPTION( m_driver != nullptr && m_rpc_system != nullptr && m_object_creation_registry != nullptr && m_object_system != nullptr m_object_system != nullptr && m_linking_context != nullptr ); } }
net/src/linking_context.cpp 0 → 100644 +71 −0 Original line number Diff line number Diff line #include <net/linking_context.hpp> using namespace net; uint32_t LinkingContext::insert_object(net::File* object) { ASSUMPTION(object != nullptr); ASSUMPTION(!m_object_to_id.contains(object)); auto new_id = allocate_id(); register_object(new_id, object); return new_id; } void LinkingContext::register_object(uint32_t id, net::File* object) { ASSUMPTION(object != nullptr); ASSUMPTION(id != INVALID_ID); m_id_to_object[id] = object; m_object_to_id[object] = id; } void LinkingContext::remove_object(net::File* object) { ASSUMPTION(object != nullptr); auto it = m_object_to_id.find(object); if (it != m_object_to_id.end()) { auto id = it->second; m_id_to_object.erase(id); m_object_to_id.erase(it); } } uint32_t LinkingContext::allocate_id() { return ++m_id_counter; } uint32_t LinkingContext::get_id(net::File* object) const { ASSUMPTION(object != nullptr); if (auto it = m_object_to_id.find(object); it != m_object_to_id.end()) { return it->second; } return INVALID_ID; } net::File* LinkingContext::get_object(uint32_t id) const { if (auto it = m_id_to_object.find(id); it != m_id_to_object.end()) { return it->second; } return nullptr; } LinkingContext::LinkingContext() : com::Library(self_name()), m_id_counter(0) { } LinkingContext::~LinkingContext() = default;