Initial commit
This commit is contained in:
165
Include/ZSimulation/ZNetworkEvent.hpp
Normal file
165
Include/ZSimulation/ZNetworkEvent.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
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
|
||||
Reference in New Issue
Block a user