Commit a10f5c95 authored by Filip Hauzvic's avatar Filip Hauzvic
Browse files

Network IDs, find owned net object

parent bddaf01b
Loading
Loading
Loading
Loading
+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 {
@@ -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();
@@ -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(); }
@@ -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(); }
}
+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;
    };
}
+35 −7
Original line number Diff line number Diff line
@@ -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.
@@ -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)
        {
@@ -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;
    }
}
+11 −9
Original line number Diff line number Diff line
@@ -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;
    }
@@ -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
        );
    }
}
+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