From: Mikko Rasa Date: Thu, 11 Jan 2024 21:53:34 +0000 (+0200) Subject: Add more kinds of remote calls X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=21d10ad56caab6f7f3fe42c4a2bf257c0cc78bb7;p=libs%2Fgame.git Add more kinds of remote calls --- diff --git a/source/game/remotecall.h b/source/game/remotecall.h index 35cfe88..e5e0fb7 100644 --- a/source/game/remotecall.h +++ b/source/game/remotecall.h @@ -10,54 +10,85 @@ namespace Msp::Game { -template -class ReplicatedCall: private Net::PacketReceiver

+template +class RemoteCallBase: protected Net::PacketReceiver

{ -public: - using Function = std::function; +protected: + using Function = std::function; -private: - Replicator *replicator = nullptr; + Replicator *replicator; Function func; + RemoteCallBase(Replicator *, Function); +}; + + +template + requires std::is_base_of_v +class RemoteEntityCallBase: protected RemoteCallBase, const P &)> +{ +protected: + using RemoteCallBase, const P &)>::RemoteCallBase; + + void prepare(Handle, P &); + void call(const P &); +}; + + +template +class ReplicatedCall: public RemoteCallBase

+{ public: - ReplicatedCall(Replicator *, Function); + ReplicatedCall(Replicator *r, RemoteCallBase

::Function f): RemoteCallBase

(r, std::move(f)) { } void operator()(P &); void operator()(unsigned, P &); private: - void receive(const P &) override; + void receive(const P &p) override { this->func(p); } }; -template - requires std::is_base_of_v -class ReplicatedEntityCall: private Net::PacketReceiver

+template +class RequestCall: public RemoteCallBase

{ public: - using Function = std::function, const P &)>; + RequestCall(Replicator *, RemoteCallBase

::Function); + + void operator()(P &); private: - Replicator *replicator = nullptr; - Function func; + void receive(const P &p) override { this->func(p); } +}; + +template +class ReplicatedEntityCall: public RemoteEntityCallBase +{ public: - ReplicatedEntityCall(Replicator *, Function); + ReplicatedEntityCall(Replicator *r, RemoteEntityCallBase::Function f): RemoteEntityCallBase(r, std::move(f)) { } - void operator()(Handle, P &); - void operator()(unsigned, Handle, P &); + void operator()(Handle, P &); + void operator()(unsigned, Handle, P &); + + void receive(const P &p) override { this->call(p); } +}; -private: - void prepare(Handle, P &); +template +class EntityRequestCall: public RemoteEntityCallBase +{ public: - void receive(const P &) override; + EntityRequestCall(Replicator *r, RemoteEntityCallBase::Function f): RemoteEntityCallBase(r, std::move(f)) { } + + void operator()(Handle, P &); + + void receive(const P &p) override { this->call(p); } }; -template -ReplicatedCall

::ReplicatedCall(Replicator *r, std::function f): +template +RemoteCallBase::RemoteCallBase(Replicator *r, Function f): replicator(r), func(std::move(f)) { @@ -65,82 +96,97 @@ ReplicatedCall

::ReplicatedCall(Replicator *r, std::function replicator->add_receiver

(*this); } + +template + requires std::is_base_of_v +void RemoteEntityCallBase::prepare(Handle entity, P &packet) +{ + Handle zygote = entity->template get_component(); + if(!zygote) + throw std::invalid_argument("ReplicatedEntityCall::operator()"); + + std::uint32_t entity_id = zygote->get_entity_id(); + if(entity_id==Zygote::NO_ID) + throw std::invalid_argument("ReplicatedEntityCall::operator()"); + + packet.entity_id = entity_id; +} + +template + requires std::is_base_of_v +void RemoteEntityCallBase::call(const P &packet) +{ + Handle entity = this->replicator->find_entity(packet.entity_id); + if(!entity) + return; // TODO report the error somehow + + Handle cast_entity = dynamic_handle_cast(entity); + if(!cast_entity) + return; + + this->func(cast_entity, packet); +} + + template void ReplicatedCall

::operator()(P &packet) { - if(replicator) - replicator->send(packet); + if(this->replicator) + this->replicator->send(packet); func(packet); } + template -void ReplicatedCall

::receive(const P &packet) +void ReplicatedCall

::operator()(unsigned target, P &packet) { - func(packet); + if(this->replicator) + this->replicator->send(target, packet); } -template - requires std::is_base_of_v -ReplicatedEntityCall::ReplicatedEntityCall(Replicator *r, Function f): - replicator(r), - func(std::move(f)) +template +void RequestCall

::operator()(P &packet) { - if(replicator) - replicator->add_receiver

(*this); + if(this->replicator && !this->replicator->is_server()) + this->replicator->send(packet); + else + this->func(packet); } + template - requires std::is_base_of_v -void ReplicatedEntityCall::operator()(Handle entity, P &packet) +void ReplicatedEntityCall::operator()(Handle entity, P &packet) { - if(replicator) + if(this->replicator) { - prepare(entity, packet); - replicator->send(entity, packet); + this->prepare(entity, packet); + this->replicator->send(entity, packet); } - func(entity, packet); + this->func(entity, packet); } template - requires std::is_base_of_v -void ReplicatedEntityCall::operator()(unsigned target, Handle entity, P &packet) +void ReplicatedEntityCall::operator()(unsigned target, Handle entity, P &packet) { - if(replicator) + if(this->replicator) { - prepare(entity, packet); - replicator->send(target, packet); + this->prepare(entity, packet); + this->replicator->send(target, packet); } } -template - requires std::is_base_of_v -void ReplicatedEntityCall::prepare(Handle entity, P &packet) -{ - Handle zygote = entity->get_component(); - if(!zygote) - throw std::invalid_argument("ReplicatedEntityCall::operator()"); - - std::uint32_t entity_id = zygote->get_entity_id(); - if(entity_id==Zygote::NO_ID) - throw std::invalid_argument("ReplicatedEntityCall::operator()"); - - packet.entity_id = entity_id; -} template - requires std::is_base_of_v -void ReplicatedEntityCall::receive(const P &packet) +void EntityRequestCall::operator()(Handle entity, P &packet) { - Handle entity = replicator->find_entity(packet.entity_id); - if(!entity) - return; // TODO report the error somehow - - Handle cast_entity = dynamic_handle_cast(entity); - if(!cast_entity) - return; - - func(cast_entity, packet); + if(this->replicator && !this->replicator->is_server()) + { + this->prepare(entity, packet); + this->replicator->send(entity, packet); + } + else + this->func(entity, packet); } } // namespace Msp::Game