Leviathan  0.8.0.0
Leviathan game engine
SyncedResource.h
Go to the documentation of this file.
1 #pragma once
2 // ------------------------------------ //
3 #include "Define.h"
4 // ------------------------------------ //
6 #include "Common/SFMLPackets.h"
7 #include "Exceptions.h"
8 
9 namespace Leviathan{
10 
16  friend SyncedVariables;
17  public:
20  DLLEXPORT SyncedResource(const std::string &uniquename);
21  DLLEXPORT virtual ~SyncedResource();
22 
23 
25  DLLEXPORT virtual void AddDataToPacket(Lock &guard, sf::Packet &packet);
26 
27  DLLEXPORT inline void AddDataToPacket(sf::Packet &packet){
28 
29  GUARD_LOCK();
30  AddDataToPacket(guard, packet);
31  }
32 
34  DLLEXPORT static std::string GetSyncedResourceNameFromPacket(sf::Packet &packet);
35 
38  DLLEXPORT virtual bool UpdateDataFromPacket(Lock &guard, sf::Packet &packet);
39 
40  DLLEXPORT inline bool UpdateDataFromPacket(sf::Packet &packet){
41 
42  GUARD_LOCK();
43  return UpdateDataFromPacket(guard, packet);
44  }
45 
48  DLLEXPORT virtual void StartSync(SyncedVariables &variablesync);
49 
54 
55  protected:
56 
58  virtual void UpdateCustomDataFromPacket(Lock &guard, sf::Packet &packet) = 0;
59 
62  virtual void SerializeCustomDataToPacket(Lock &guard, sf::Packet &packet) = 0;
63 
64 
67  DLLEXPORT virtual void UpdateOurNetworkValue(Lock &guard);
68 
72  virtual void OnValueUpdated(Lock &guard);
73 
74 
75  // Disable copy and copy constructor usage //
77  SyncedResource(const SyncedResource &other);
78  // ------------------------------------ //
79 
80  const std::string Name;
81  };
82 
83 
87  template<class DTypeName>
88  class SyncedPrimitive : public SyncedResource{
89  public:
91  using CallbackPtr = void (*)(Lock &guard, SyncedPrimitive<DTypeName>* updated);
92 
96  SyncedPrimitive(const std::string &uniquename, const DTypeName &initialvalue,
97  CallbackPtr updatecallback = NULL) :
98  SyncedResource(uniquename),
99  ValueUpdateCallback(updatecallback), OurValue(initialvalue)
100  {
101  // Now we are ready to be updated //
102  IsValid = true;
103  }
104 
106 
107  GUARD_LOCK();
108 
109  // Unhook already //
110  ReleaseParentHooks(guard);
111  // Set us as invalid after locking //
112 
113  IsValid = false;
114 
115  // Destructors will take care of the rest //
116  }
117 
121  inline void UpdateValue(const DTypeName &newvalue){
122 
123  GUARD_LOCK();
124  // Update our value //
125  OurValue = newvalue;
126 
127  UpdateOurNetworkValue(guard);
128  }
129 
131  DTypeName GetValue() const{
132  GUARD_LOCK();
133  return OurValue;
134  }
135 
140  DTypeName* GetValueDirect(){
141  return &OurValue;
142  }
143 
145  SyncedResource& operator =(const DTypeName &value){
146  UpdateValue(value);
147  return *this;
148  }
149  // ------------------ Overloaded operators for ease of use ------------------ //
150  bool operator ==(const DTypeName &value){
151  return OurValue == value;
152  }
153  bool operator !=(const DTypeName &value){
154  return OurValue != value;
155  }
156 
157  operator DTypeName(){
158  GUARD_LOCK();
159  return OurValue;
160  }
161 
162 
163  protected:
164 
165  virtual void OnValueUpdated(Lock &guard) override{
166  // Report update //
168  ValueUpdateCallback(guard, this);
169  }
170 
171  virtual void UpdateCustomDataFromPacket(Lock &guard, sf::Packet &packet) override{
172  // The object is already locked at this point //
173 
174  // Try to get our variable //
175  if(!(packet >> OurValue)){
176 
177  throw InvalidArgument("resource sync primitive packet has invalid format");
178  }
179 
180  }
181 
182  virtual void SerializeCustomDataToPacket(Lock &guard, sf::Packet &packet) override{
183  packet << OurValue;
184  }
185 
186  // ------------------------------------ //
187 
189  bool IsValid;
190 
193 
195  DTypeName OurValue;
196  };
197 
198 
199 }
200 
201 #ifdef LEAK_INTO_GLOBAL
204 #endif
205 
virtual DLLEXPORT bool UpdateDataFromPacket(Lock &guard, sf::Packet &packet)
Assigns data from a packet to this resource.
DLLEXPORT SyncedResource(const std::string &uniquename)
Constructs a base class for synced variables that requires a unique name.
Class that synchronizes some key variables with another instance.
DTypeName OurValue
The primitive object owned by this.
Template class for syncing basic types.
virtual DLLEXPORT ~SyncedResource()
void UpdateValue(const DTypeName &newvalue)
Updates the value and notifies SyncedVariables.
virtual void OnValueUpdated(Lock &guard)
virtual void UpdateCustomDataFromPacket(Lock &guard, sf::Packet &packet)=0
Should load the custom data from a packet.
virtual DLLEXPORT void AddDataToPacket(Lock &guard, sf::Packet &packet)
Serializes the name to a packet.
DTypeName GetValue() const
Gets the value with locking.
CallbackPtr ValueUpdateCallback
This is quite an important feature to store this function pointer.
virtual void UpdateCustomDataFromPacket(Lock &guard, sf::Packet &packet) override
Should load the custom data from a packet.
const std::string Name
virtual DLLEXPORT void UpdateOurNetworkValue(Lock &guard)
Notifies our SyncedVariables of an update.
SyncedResource & operator=(const DTypeName &value)
Assignment operator that acts like UpdateValue.
static DLLEXPORT std::string GetSyncedResourceNameFromPacket(sf::Packet &packet)
Gets a name from packet leaving only the variable data there.
DLLEXPORT void AddDataToPacket(sf::Packet &packet)
Specialized class for accepting all parent/child objects.
virtual DLLEXPORT void StartSync(SyncedVariables &variablesync)
Registers this resource with the SyncedVariables instance.
void ReleaseParentHooks(Lock &guard)
Release function which releases all hooks.
bool operator==(const DTypeName &value)
virtual void OnValueUpdated(Lock &guard) override
Base class for all values that are to be automatically synced between clients.
SyncedResource & operator=(const SyncedResource &other)
#define DLLEXPORT
Definition: Include.h:84
bool operator!=(const DTypeName &value)
bool IsValid
Little overhead but this is important to discard update requests after stopping.
virtual void SerializeCustomDataToPacket(Lock &guard, sf::Packet &packet) override
Should be used to add custom data to packet.
DTypeName * GetValueDirect()
Directly accesses the variable, you will need to use your own locking with complex types.
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
DLLEXPORT void NotifyUpdatedValue()
Notify that this is changed and we want a local message, too.
virtual void SerializeCustomDataToPacket(Lock &guard, sf::Packet &packet)=0
Should be used to add custom data to packet.
SyncedPrimitive(const std::string &uniquename, const DTypeName &initialvalue, CallbackPtr updatecallback=NULL)
Constructs an instance with a initial value.
#define GUARD_LOCK()
Definition: ThreadSafe.h:111
void(*)(Lock &guard, SyncedPrimitive< DTypeName > *updated) CallbackPtr
The callback type.
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18
DLLEXPORT bool UpdateDataFromPacket(sf::Packet &packet)