]> git.tdb.fi Git - libs/game.git/commitdiff
Emit events when the other side of a network connection changes stages
authorMikko Rasa <tdb@tdb.fi>
Sun, 11 Jun 2023 14:03:11 +0000 (17:03 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 11 Jun 2023 15:00:54 +0000 (18:00 +0300)
source/game/events.h
source/game/messages.h
source/game/networking.cpp
source/game/networking.h
source/game/protocol.cpp
source/game/stage.h

index c9948e0cfc64ad0cabd3d5c8b351dd769dab73c3..7636a1008c6a394a85f86dbfd8cdd3842c4d8776 100644 (file)
@@ -56,6 +56,12 @@ struct StageActivated
        Stage &stage;
 };
 
+struct ServerStageActivated
+{
+       std::string name;
+       Stage *local_stage = nullptr;
+};
+
 struct StageDeactivated
 {
        Stage &stage;
@@ -66,6 +72,16 @@ struct CameraChanged
        Handle<Camera> camera;
 };
 
+struct RemotePlayerEntered
+{
+       unsigned id;
+};
+
+struct RemotePlayerExited
+{
+       unsigned id;
+};
+
 } // namespace Events
 } // namespace Msp::Game
 
index 8efc1bda3e7f0ae24d6374951c387b52917c0000..947b0463531d786b7b21733270c6e0742d733660 100644 (file)
@@ -33,6 +33,11 @@ struct InternString
        std::string value;
 };
 
+struct StageActivated
+{
+       std::uint16_t name;
+};
+
 } // namespace Messages
 } // namespace Msp::Game
 
index 9f60968ef90e1ddc69fb4b44708b61daad92c152..ad516327b2e38a02a0d6be9f991cb1c806ab62a6 100644 (file)
@@ -2,15 +2,20 @@
 #include <msp/net/inet6.h>
 #include <msp/net/resolve.h>
 #include "director.h"
+#include "stage.h"
 
 using namespace std;
 
 namespace Msp::Game {
 
 Networking::Networking(Director &d):
-       event_source(d.get_event_bus()),
-       io_disp(d.get_io_dispatcher())
+       director(d),
+       event_source(director.get_event_bus()),
+       observer(director.get_event_bus()),
+       io_disp(director.get_io_dispatcher())
 {
+       observer.observe<Events::StageActivated>([this](const auto &e){ stage_activated(e); });
+
        strings.emplace_back();
 }
 
@@ -163,6 +168,23 @@ void Networking::incoming_connection()
 {
        unique_ptr<Net::StreamSocket> socket(server_socket->accept());
        clients.emplace_back(make_unique<ClientConnection>(*this, move(socket)));
+               
+}
+
+void Networking::stage_activated(const Events::StageActivated &event)
+{
+       if(!is_active())
+               return;
+
+       Messages::StageActivated message;
+       message.name = intern_string(event.stage.get_name());
+       if(state==SERVER)
+       {
+               for(const auto &c: clients)
+                       c->get_communicator().send(message);
+       }
+       else if(state==CONNECTED)
+               connection->get_communicator().send(message);
 }
 
 
@@ -241,6 +263,13 @@ void Networking::ServerConnection::receive(const Messages::InternString &intern)
        networking.strings[intern.id] = intern.value;
 }
 
+void Networking::ServerConnection::receive(const Messages::StageActivated &activated)
+{
+       string name = networking.get_string(activated.name);
+       Stage *local_stage = networking.director.find_stage(name);
+       networking.event_source.emit<Events::ServerStageActivated>(name, local_stage);
+}
+
 
 Networking::ClientConnection::ClientConnection(Networking &n, unique_ptr<Net::StreamSocket> s):
        Connection(n, move(s))
@@ -281,4 +310,28 @@ void Networking::ClientConnection::receive(const Messages::AddPlayerRequest &add
        networking.event_source.emit<Events::NetworkPlayerArrived>(player.id, player.name);
 }
 
+void Networking::ClientConnection::receive(const Messages::StageActivated &activated)
+{
+       const string &new_active_stage = networking.get_string(activated.name);
+       if(new_active_stage==active_stage)
+               return;
+
+       string old_active_stage = move(active_stage);
+       active_stage = new_active_stage;
+
+       if(Stage *local_active_stage = networking.director.get_active_stage())
+       {
+               bool entered = (active_stage==local_active_stage->get_name());
+               bool exited = (old_active_stage==local_active_stage->get_name());
+               for(const Player &p: networking.players)
+                       if(p.owner==this)
+                       {
+                               if(entered)
+                                       local_active_stage->get_event_source().emit<Events::RemotePlayerEntered>(p.id);
+                               else if(exited)
+                                       local_active_stage->get_event_source().emit<Events::RemotePlayerExited>(p.id);
+                       }
+       }
+}
+
 } // namespace Msp::Game
index e459bf5c645bbf8e9e9ad7e5374b6005d0cfd581..52a01c3337481dc7f5a1a7fd7159ca7edb346a4c 100644 (file)
@@ -52,7 +52,8 @@ private:
                public Net::PacketReceiver<Messages::AddPlayerResponse>,
                public Net::PacketReceiver<Messages::PlayerAdded>,
                public Net::PacketReceiver<Messages::PlayerRemoved>,
-               public Net::PacketReceiver<Messages::InternString>
+               public Net::PacketReceiver<Messages::InternString>,
+               public Net::PacketReceiver<Messages::StageActivated>
        {
        public:
                ServerConnection(Networking &, const Net::SockAddr &);
@@ -65,16 +66,22 @@ private:
                void receive(const Messages::PlayerAdded &) override;
                void receive(const Messages::PlayerRemoved &) override;
                void receive(const Messages::InternString &) override;
+               void receive(const Messages::StageActivated &) override;
        };
 
        class ClientConnection: public Connection,
-               public Net::PacketReceiver<Messages::AddPlayerRequest>
+               public Net::PacketReceiver<Messages::AddPlayerRequest>,
+               public Net::PacketReceiver<Messages::StageActivated>
        {
+       private:
+               std::string active_stage;
+
        public:
                ClientConnection(Networking &, std::unique_ptr<Net::StreamSocket>);
 
                void protocol_ready(const Net::Protocol &);
                void receive(const Messages::AddPlayerRequest &) override;
+               void receive(const Messages::StageActivated &) override;
        };
 
        struct Player
@@ -87,7 +94,9 @@ private:
 
        static constexpr unsigned ID_PENDING = 0x8000;
 
+       Director &director;
        EventSource event_source;
+       EventObserver observer;
        IO::EventDispatcher &io_disp;
        Protocol protocol;
        State state = DISABLED;
@@ -103,6 +112,7 @@ public:
 
        void start_server(unsigned);
        void connect_to_server(const std::string &);
+       bool is_active() const { return state==SERVER || state==CONNECTED; }
        bool is_server() const { return state==DISABLED || state==SERVER; }
        void disable();
        void reap_connections();
@@ -117,6 +127,8 @@ private:
        void set_state(State);
        void protocol_ready(const Net::Protocol &);
        void incoming_connection();
+
+       void stage_activated(const Events::StageActivated &);
 };
 
 
index ec345314ba7b6c3621067860160d63dfc2fa97f8..dfa8f29a691b977555d6d977d201ce9537dee52b 100644 (file)
@@ -11,6 +11,7 @@ Protocol::Protocol()
        add<AddPlayerResponse>(&AddPlayerResponse::token, &AddPlayerResponse::id);
        add<PlayerAdded>(&PlayerAdded::id, &PlayerAdded::name);
        add<InternString>(&InternString::id, &InternString::value);
+       add<StageActivated>(&StageActivated::name);
 }
 
 } // namespace Msp::Game
index b06006ba579a121eff10072ac91bc06c9a764448..76ce58e89f0390a7e9c31e964531905bb4174f23 100644 (file)
@@ -22,7 +22,8 @@ class MSPGAME_API Stage
 {
 public:
        using EventSource = Game::EventSource<Events::EntityCreated, Events::EntityDestroyed,
-               Events::ComponentCreated, Events::ComponentDestroyed, Events::CameraChanged>;
+               Events::ComponentCreated, Events::ComponentDestroyed, Events::CameraChanged,
+               Events::RemotePlayerEntered, Events::RemotePlayerExited>;
 
 private:
        std::string name;