Files
libsst/Include/ZSimulation/ZNetworkEvent.hpp
2026-04-03 00:22:39 -05:00

165 lines
5.0 KiB
C++

/*
ZNetworkEvent.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 9/13/2015
Purpose:
Network Event abstract class. Intended to be subclassed into various subclasses that will be
serialized / deserialized and processed on both client and server.
Note that events that originate on the server will generally not have their HandleServer method
called, as the server already processed the occurrence that originated the event. Events
that originate on the client will generally be pushed to the server, have HandleServer
called on them, which will generally also cause an event to be pushed to each client, who
will then have HandleClient called when the event gets deserialized.
From the above usage pattern, we can see that clients generally push events to the server but
do not process the local occurrence (the HandleClient) until after the server has confirmed
the event happens by pushing the event back to all clients, the original sender included.
This usage pattern is not required for client authoritative events, which are processed locally
and then handed to the server to notify other attached clients.
License:
TODO
*/
#pragma once
#ifndef _ZNETWORKEVENT_HPP
#define _ZNETWORKEVENT_HPP
#include "ZSimulationDefs.hpp"
// forward decl
class ZSimulation;
/*
ZNetworkEvent class.
*/
class ZNetworkEvent {
DISABLE_COPY_AND_ASSIGN(ZNetworkEvent);
public:
nID Type; // the type of event this is
cID NetTarget; // the connection this is targeting
cID NetIgnore; // if NetTarget is set to all, this target will be ignored
bool InQueue; // flag set during a handle method to indicate this has been queued up for sending
// handler for events on client side
virtual void HandleClient(ZSimulation& server_sim) = 0;
// handler for events on server side
virtual void HandleServer(ZSimulation& client_sim) = 0;
// called by the network system to deserialize this event from binary form (after header is read)
virtual bool Deserialize(ZBinaryBufferReader& reader) = 0;
// called by the network system to serialize this event into binary form
virtual void Serialize(ZBinaryBufferWriter& writer) = 0;
// called to get the serialized size of this event (including uint8_t message type flag)
virtual size_t GetSerializedSize() = 0;
// called by subclass to serialize the header (Type, PlayerSource, and PlayerTarget)
void SerializeHeader(ZBinaryBufferWriter& writer) {
writer.WriteU32(Type);
}
// called by subclass to get serialized header size
size_t GetHeaderSize() {
return sizeof(nID);
}
protected:
// c'tor
ZNetworkEvent(nID type) : Type(type) { }
};
/*
Network Event base implementation, which attempts to automatically handle serialization and
deserialization via template POD structs.
Note the template on the game event (DS), which indicates a POD struct. This is the data
that is serialized and sent as part of the event. Wrap the struct definition in pragma
pack statements to ensure correct behavior across systems and reduce bandwidth.
*/
template <typename DS>
class ZNetworkEventBase : public ZNetworkEvent
{
DISABLE_COPY_AND_ASSIGN(ZNetworkEventBase);
public:
// the data struct for this event
DS EventData;
// called by the network system to deserialize this event from binary form (after header is read)
virtual bool Deserialize(ZBinaryBufferReader& reader) {
if (reader.CanRead(sizeof(DS))) {
reader.ReadU8Array((uint8_t*)&EventData, sizeof(DS));
return true;
} else return false;
}
// called by the network system to serialize this event into binary form
virtual void Serialize(ZBinaryBufferWriter& writer) {
SerializeHeader(writer);
writer.WriteU8Array((uint8_t*)&EventData, sizeof(DS));
}
// called to get the serialized size of this event
virtual size_t GetSerializedSize() {
return GetHeaderSize() + sizeof(DS);
}
protected:
// c'tor
ZNetworkEventBase(nID type) : ZNetworkEvent(type) { }
};
#pragma pack (push, 1)
/*
Data struct used for message events, which will simply create the
given message on the other side and pass it to the simulation.
*/
template <typename M>
struct ZMessageEventData {
mID Type;
eID Sender;
eID Target;
M MessageData;
cID Connection;
};
#pragma pack (pop)
/*
Message network event. This is used to duplicate a message on other
connected simulations. The template parameter type is the message
data definition struct. Be sure to use pragma pack to reduce network
overhead.
*/
template <typename MT>
class ZMessageEvent : public ZNetworkEventBase<ZMessageEventData<MT>> {
public:
// c'tor
ZMessageEvent(mID msg_type) : ZNetworkEventBase(0) { }
ZMessageEvent(mID msg_type, eID sender, eID target, MT payload, cID connection)
: ZNetworkEventBase(0), EventData({msg_type, sender, target, connection, payload}) { }
// subclass implementations
virtual void HandleClient(ZSimulation& server_sim) {
server_sim.SendLocalMessage(Data.Type, Data.Sender, Data.Target, Data.MessageData);
}
virtual void HandleServer(ZSimulation& client_sim) {
client_sim.SendLocalMessage(Data.Type, Data.Sender, Data.Target, Data.MessageData);
}
};
#endif