Leviathan  0.8.0.0
Leviathan game engine
Leviathan::GameWorld Class Reference

Represents a world that contains entities. More...

#include <GameWorld.h>

Classes

class  Implementation
 

Public Member Functions

DLLEXPORT GameWorld ()
 
DLLEXPORT ~GameWorld ()
 
DLLEXPORT int GetID () const
 Returns the unique ID of this world. More...
 
DLLEXPORT bool Init (NETWORKED_TYPE type, Ogre::Root *ogre)
 Creates resources for the world to work. More...
 
DLLEXPORT void Release ()
 Release to not use Ogre when deleting. More...
 
DLLEXPORT void MarkForClear ()
 Marks all entities to be deleted. More...
 
DLLEXPORT void ClearEntities ()
 Clears all objects from the world. More...
 
DLLEXPORT size_t GetEntityCount () const
 Returns the number of ObjectIDs this world keeps track of. More...
 
DLLEXPORT void Tick (int currenttick)
 Used to keep track of passed ticks and trigger timed triggers. More...
 
DLLEXPORT void Render (int mspassed, int tick, int timeintick)
 Runs systems required for a rendering run. Also updates camera positions. More...
 
DLLEXPORT int GetTickNumber () const
 Returns the current tick. More...
 
DLLEXPORT float GetTickProgress () const
 Returns float between 0.f and 1.f based on how far current tick has progressed. More...
 
DLLEXPORT std::tuple< int, int > GetTickAndTime () const
 Returns a tuple of the current tick number and how long it has passed since last tick. More...
 
DLLEXPORT int GetPhysicalMaterial (const std::string &name)
 Fetches the physical material ID from the material manager. More...
 
DLLEXPORT RayCastHitEntityCastRayGetFirstHit (const Float3 &from, const Float3 &to)
 Casts a ray from point along a vector and returns the first physical object it hits. More...
 
DLLEXPORT ObjectID CreateEntity ()
 Creates a new empty entity and returns its id. More...
 
DLLEXPORT void DestroyEntity (ObjectID id)
 Destroys an entity and all of its components. More...
 
DLLEXPORT void QueueDestroyEntity (ObjectID id)
 Deletes an entity during the next tick. More...
 
DLLEXPORT void SetEntitysParent (ObjectID child, ObjectID parent)
 Makes child entity be deleted when parent is deleted. More...
 
DLLEXPORT void NotifyEntityCreate (ObjectID id)
 Notifies others that we have created a new entity. More...
 
virtual DLLEXPORT void DestroyAllIn (ObjectID id)
 Removes all components from an entity. More...
 
template<class TComponent >
TComponent & GetComponent (ObjectID id)
 
virtual DLLEXPORT std::tuple< void *, bool > GetComponent (ObjectID id, COMPONENT_TYPE type)
 Gets a component of type or returns nullptr. More...
 
virtual DLLEXPORT std::tuple< void *, ComponentTypeInfo, bool > GetComponentWithType (ObjectID id, COMPONENT_TYPE type)
 Gets a component of type or returns nullptr. More...
 
template<class TComponent >
StateHolder< typename TComponent::StateT > & GetStatesFor ()
 
virtual DLLEXPORT std::tuple< void *, bool > GetStatesFor (COMPONENT_TYPE type)
 Gets a component states of type or returns nullptr. More...
 
virtual DLLEXPORT bool GetRemovedFor (COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID >> &result)
 Gets a list of destroyed components of type. More...
 
DLLEXPORT bool GetRemovedForScriptDefined (const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
 Variant of GetRemovedFor for script defined types. More...
 
virtual DLLEXPORT bool GetAddedFor (COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID, ComponentTypeInfo >> &result)
 Gets a list of created components of type. More...
 
DLLEXPORT bool GetAddedForScriptDefined (const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID, ScriptComponentHolder *>> &result)
 Variant of GetAddedFor for script defined types. More...
 
DLLEXPORT void SetCamera (ObjectID object)
 Sets the entity that acts as a camera. More...
 
DLLEXPORT Ogre::Ray CastRayFromCamera (float x, float y) const
 Casts a ray from the active camera. More...
 
Ogre::SceneManager * GetScene ()
 
DLLEXPORT Float3 GetGravityAtPosition (const Float3 &pos)
 
PhysicalWorldGetPhysicalWorld ()
 
DLLEXPORT void SetWorldPhysicsFrozenState (bool frozen)
 
DLLEXPORT RayCastHitEntityCastRayGetFirstHitProxy (const Float3 &from, const Float3 &to)
 
DLLEXPORT bool ShouldPlayerReceiveEntity (Position &atposition, Connection &connection)
 Returns true when the player matching the connection should receive updates about an entity. More...
 
DLLEXPORT bool IsConnectionInWorld (Connection &connection) const
 Returns true if a player with the given connection is receiving updates for this world. More...
 
DLLEXPORT void SetPlayerReceiveWorld (std::shared_ptr< ConnectedPlayer > ply)
 Verifies that player is receiving this world. More...
 
DLLEXPORT void SendToAllPlayers (const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
 Sends a packet to all connected players. More...
 
DLLEXPORT bool SendEntityToConnection (ObjectID obj, std::shared_ptr< Connection > connection)
 Sends an entity to a connection and sets everything up. More...
 
DLLEXPORT void HandleEntityInitialPacket (std::shared_ptr< NetworkResponse > message, ResponseEntityCreation *data)
 Creates a new entity from initial entity response. More...
 
DLLEXPORT void HandleEntityUpdatePacket (std::shared_ptr< NetworkResponse > message)
 Applies an update packet. More...
 
DLLEXPORT void HandleClockSyncPacket (RequestWorldClockSync *data)
 Handles a world clock synchronizing packet. More...
 
DLLEXPORT void HandleWorldFrozenPacket (ResponseWorldFrozen *data)
 Handles a world freeze/unfreeze packet. More...
 
DLLEXPORT void ApplyQueuedPackets ()
 Applies packets that have been received after the last call to this. More...
 
DLLEXPORT void SetFog ()
 
DLLEXPORT void SetSunlight ()
 
DLLEXPORT void RemoveSunlight ()
 
DLLEXPORT void SetLightProperties (const Ogre::ColourValue &diffuse, const Ogre::ColourValue &specular, const Ogre::Vector3 &direction, float power, const Ogre::ColourValue &upperhemisphere, const Ogre::ColourValue &lowerhemisphere, const Ogre::Vector3 &hemispheredir, float envmapscale=1.0f)
 Sets the sunlight properties. More...
 
DLLEXPORT CScriptArray * GetRemovedIDsForComponents (CScriptArray *componenttypes)
 Returns a list of ObjectIDs that have been removed from any of the specified component types. More...
 
DLLEXPORT CScriptArray * GetRemovedIDsForScriptComponents (CScriptArray *typenames)
 Returns a list of ObjectIDs that have been removed from any of the script registered component types specified by typeNames. More...
 
DLLEXPORT bool RegisterScriptComponentType (const std::string &name, asIScriptFunction *factory)
 Registers a component type from scripts. More...
 
DLLEXPORT ScriptComponentHolderGetScriptComponentHolder (const std::string &name)
 Retrieves a script registered component type holder. More...
 
DLLEXPORT bool RegisterScriptSystem (const std::string &name, asIScriptObject *system)
 Registers a new system defined in a script. Must implement the ScriptSystem interface. More...
 
DLLEXPORT asIScriptObject * GetScriptSystem (const std::string &name)
 Returns the underlying angelscript object that implements a script system. More...
 
virtual DLLEXPORT void OnUnLinkedFromWindow (Window *window, Ogre::Root *ogre)
 Used to detect that this world is in the background and should not tick. More...
 
virtual DLLEXPORT void OnLinkToWindow (Window *window, Ogre::Root *ogre)
 Called when this is added to a Window. More...
 
virtual DLLEXPORT void SetRunInBackground (bool tickinbackground)
 Configures this world to run tick even when not attached to a window. More...
 
 REFERENCE_HANDLE_UNCOUNTED_TYPE (GameWorld)
 

Protected Member Functions

virtual DLLEXPORT void RunFrameRenderSystems (int tick, int timeintick)
 Called by Render which is called from a Window if this is linked to one. More...
 
virtual DLLEXPORT void _RunTickSystems ()
 Called by Tick. More...
 
virtual DLLEXPORT void HandleAddedAndDeleted ()
 Handles added entities and components. More...
 
virtual DLLEXPORT void ClearAddedAndRemoved ()
 Clears the added components. Call after HandleAddedAndDeleted. More...
 
virtual DLLEXPORT void _ResetSystems ()
 Resets stored nodes in systems. Used together with _ResetComponents. More...
 
virtual DLLEXPORT void _ResetOrReleaseComponents ()
 Resets components in holders. Used together with _ResetSystems. More...
 
virtual DLLEXPORT void _DoSystemsInit ()
 Called in Init when systems should run their initialization logic. More...
 
virtual DLLEXPORT void _DoSystemsRelease ()
 Called in Release when systems should run their shutdown logic. More...
 
virtual DLLEXPORT void _DoSuspendSystems ()
 Called when this is put in the background and systems (the sound system) should suspend their active objects. More...
 
virtual DLLEXPORT void _DoResumeSystems ()
 Opposite of _DoSuspendSystems. More...
 

Protected Attributes

bool GraphicalMode = false
 If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped. More...
 
bool IsOnServer = false
 

Detailed Description

Represents a world that contains entities.

This is the base class from which worlds that support different components are derived from Custom worls should derive from StandardWorld which has all of the standard components supported. See the GenerateStandardWorld.rb file to figure out how to generate world classes

Definition at line 96 of file GameWorld.h.

Constructor & Destructor Documentation

◆ GameWorld()

DLLEXPORT GameWorld::GameWorld ( )

Definition at line 77 of file GameWorld.cpp.

77  :
78  pimpl(std::make_unique<Implementation>()), ID(IDFactory::GetID())
79 {
80 }
static int GetID()
Definition: IDFactory.h:17

◆ ~GameWorld()

DLLEXPORT GameWorld::~GameWorld ( )

Definition at line 82 of file GameWorld.cpp.

83 {
84  (*WorldDestroyed) = true;
85 
86  // Assert if all objects haven't been released already.
87  // We can't call virtual methods here anymore
88  // This can be hit in tests quite easily if something throws an exception
89  LEVIATHAN_ASSERT(
90  Entities.empty(), "GameWorld: Entities not empty in destructor. Was Release called?");
91 }

Member Function Documentation

◆ _DoResumeSystems()

DLLEXPORT void GameWorld::_DoResumeSystems ( )
protectedvirtual

Opposite of _DoSuspendSystems.

Definition at line 1003 of file GameWorld.cpp.

1004 {
1005  // We are responsible for script systems //
1006  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1007  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1008 
1009  iter->second->Resume();
1010  }
1011 }

◆ _DoSuspendSystems()

DLLEXPORT void GameWorld::_DoSuspendSystems ( )
protectedvirtual

Called when this is put in the background and systems (the sound system) should suspend their active objects.

Note
Only called if TickWhileInBackground is false (and won't be called if that is changed while this is in the background)

Definition at line 993 of file GameWorld.cpp.

994 {
995  // We are responsible for script systems //
996  for(auto iter = pimpl->RegisteredScriptSystems.begin();
997  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
998 
999  iter->second->Suspend();
1000  }
1001 }

◆ _DoSystemsInit()

DLLEXPORT void GameWorld::_DoSystemsInit ( )
protectedvirtual

Called in Init when systems should run their initialization logic.

Definition at line 972 of file GameWorld.cpp.

973 {
974  // Script systems are initialized as they are created
975 }

◆ _DoSystemsRelease()

DLLEXPORT void GameWorld::_DoSystemsRelease ( )
protectedvirtual

Called in Release when systems should run their shutdown logic.

Definition at line 977 of file GameWorld.cpp.

978 {
979  // This can be called after Releasing once already
980  if(!pimpl)
981  return;
982 
983  // We are responsible for script systems //
984  for(auto iter = pimpl->RegisteredScriptSystems.begin();
985  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
986 
987  iter->second->Release();
988  }
989 
990  pimpl->RegisteredScriptSystems.clear();
991 }

◆ _ResetOrReleaseComponents()

DLLEXPORT void GameWorld::_ResetOrReleaseComponents ( )
protectedvirtual

Resets components in holders. Used together with _ResetSystems.

Definition at line 619 of file GameWorld.cpp.

620 {
621  // Skip double Release
622  if(!pimpl)
623  return;
624 
625  // We are responsible for script components //
626  for(auto iter = pimpl->RegisteredScriptComponents.begin();
627  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
628 
629  iter->second->ReleaseAllComponents();
630  }
631 }

◆ _ResetSystems()

DLLEXPORT void GameWorld::_ResetSystems ( )
protectedvirtual

Resets stored nodes in systems. Used together with _ResetComponents.

Definition at line 605 of file GameWorld.cpp.

606 {
607  // Skip double Release
608  if(!pimpl)
609  return;
610 
611  // We are responsible for script systems //
612  for(auto iter = pimpl->RegisteredScriptSystems.begin();
613  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
614 
615  iter->second->Clear();
616  }
617 }

◆ _RunTickSystems()

DLLEXPORT void GameWorld::_RunTickSystems ( )
protectedvirtual

Called by Tick.

Derived worls should run their systems that need to be ran before the basic systems and then call this and finally run systems that need to be ran after the base class' systems (if any)

Definition at line 642 of file GameWorld.cpp.

643 {
644  // We are responsible for script systems //
645  for(auto iter = pimpl->RegisteredScriptSystems.begin();
646  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
647 
648  iter->second->Run();
649  }
650 }

◆ ApplyQueuedPackets()

DLLEXPORT void GameWorld::ApplyQueuedPackets ( )

Applies packets that have been received after the last call to this.

Definition at line 1241 of file GameWorld.cpp.

1242 {
1243  if(!InitialEntityPackets.empty())
1244  _ApplyInitialEntityPackets();
1245 
1246  if(!EntityUpdatePackets.empty())
1247  _ApplyEntityUpdatePackets();
1248 }

◆ CastRayFromCamera()

DLLEXPORT Ogre::Ray GameWorld::CastRayFromCamera ( float  x,
float  y 
) const

Casts a ray from the active camera.

Parameters
xNormalized x coordinate (range [0, 1])
yNormalized y coordinate (range [0, 1])
Exceptions
InvalidStateif this world has no active camera
See also
SetCamera

Definition at line 364 of file GameWorld.cpp.

365 {
366 
367  // Fail if there is no active camera //
368  if(CameraEntity == NULL_OBJECT)
369  throw InvalidState("This world has no active CameraEntity");
370 
371  if(!WorldSceneCamera)
372  throw InvalidState("This world has initialized Ogre resources");
373 
374  // Read the latest set data from the camera
375  // TODO: could jump to the actual latest position here if wanted
376  return WorldSceneCamera->getCameraToViewportRay(x, y);
377 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ CastRayGetFirstHit()

DLLEXPORT RayCastHitEntity * GameWorld::CastRayGetFirstHit ( const Float3 from,
const Float3 to 
)

Casts a ray from point along a vector and returns the first physical object it hits.

Warning
You need to call Release on the returned object once done

Definition at line 1053 of file GameWorld.cpp.

1054 {
1055  // Create a data object for the ray cast //
1056  RayCastData data(1, from, to);
1057 
1058  // Call the actual ray firing function //
1059  NewtonWorldRayCast(_PhysicalWorld->GetNewtonWorld(), &from.X, &to.X,
1060  RayCallbackDataCallbackClosest, &data, nullptr, 0);
1061 
1062  // Check the result //
1063  if(data.HitEntities.size() == 0) {
1064  // Nothing hit //
1065  return new RayCastHitEntity();
1066  }
1067 
1068  // We need to increase reference count to not to accidentally delete the result while
1069  // caller is using it
1070  data.HitEntities[0]->AddRef();
1071 
1072  // Return the only hit //
1073  return data.HitEntities[0];
1074 }
static dFloat RayCallbackDataCallbackClosest(const NewtonBody *const body, const NewtonCollision *const shapeHit, const dFloat *const hitContact, const dFloat *const hitNormal, dLong collisionID, void *const userData, dFloat intersectParam)
Definition: GameWorld.cpp:1078

◆ CastRayGetFirstHitProxy()

DLLEXPORT RayCastHitEntity * GameWorld::CastRayGetFirstHitProxy ( const Float3 from,
const Float3 to 
)

Definition at line 1095 of file GameWorld.cpp.

1097 {
1098  return CastRayGetFirstHit(from, to);
1099 }
DLLEXPORT RayCastHitEntity * CastRayGetFirstHit(const Float3 &from, const Float3 &to)
Casts a ray from point along a vector and returns the first physical object it hits.
Definition: GameWorld.cpp:1053

◆ ClearAddedAndRemoved()

DLLEXPORT void GameWorld::ClearAddedAndRemoved ( )
protectedvirtual

Clears the added components. Call after HandleAddedAndDeleted.

Definition at line 594 of file GameWorld.cpp.

595 {
596  // We are responsible for script components //
597  for(auto iter = pimpl->RegisteredScriptComponents.begin();
598  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
599 
600  iter->second->ClearAdded();
601  iter->second->ClearRemoved();
602  }
603 }

◆ ClearEntities()

DLLEXPORT void GameWorld::ClearEntities ( )

Clears all objects from the world.

Definition at line 737 of file GameWorld.cpp.

738 {
739  // Release objects //
740  Entities.clear();
741  Parents.clear();
742  // This shouldn't be used all that much so release the memory
743  Parents.shrink_to_fit();
744 
745  // Clear all nodes //
746  _ResetSystems();
747 
748  // Clears all components
749  // Runs Release on components that need it
751 
752  // Notify everybody that all entities are discarded //
753  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
754 
755  auto safe = (*iter)->GetConnection();
756 
757  if(!safe->IsValidForSend()) {
758  // Player has probably closed their connection //
759  continue;
760  }
761 
762  Logger::Get()->Write("TODO: send world clear message");
763  DEBUG_BREAK;
764  }
765 }
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
virtual DLLEXPORT void _ResetOrReleaseComponents()
Resets components in holders. Used together with _ResetSystems.
Definition: GameWorld.cpp:619
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT void _ResetSystems()
Resets stored nodes in systems. Used together with _ResetComponents.
Definition: GameWorld.cpp:605

◆ CreateEntity()

DLLEXPORT ObjectID GameWorld::CreateEntity ( )

Creates a new empty entity and returns its id.

Todo:
Make this have a per world counter

Definition at line 682 of file GameWorld.cpp.

683 {
684  auto id = static_cast<ObjectID>(IDFactory::GetID());
685 
686  Entities.push_back(id);
687 
688  return id;
689 }
int32_t ObjectID
Definition: EntityCommon.h:11
static int GetID()
Definition: IDFactory.h:17

◆ DestroyAllIn()

DLLEXPORT void GameWorld::DestroyAllIn ( ObjectID  id)
virtual

Removes all components from an entity.

Definition at line 1014 of file GameWorld.cpp.

1015 {
1016  // This can be called after Releasing once already
1017  if(!pimpl)
1018  return;
1019 
1020  // Handle script types
1021  for(auto iter = pimpl->RegisteredScriptComponents.begin();
1022  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
1023 
1024  // Just try to remove like the normal c++ components until there is a better way
1025  iter->second->ReleaseComponent(id);
1026  }
1027 }

◆ DestroyEntity()

DLLEXPORT void GameWorld::DestroyEntity ( ObjectID  id)

Destroys an entity and all of its components.

Warning
This destroyes the entity immediately. If called during a system update this will cause issues as required components may be destroyed and cached components will only be updated at the start of next tick. So use QueueDestroyEntity instead.
Todo:
Make this less expensive

Definition at line 780 of file GameWorld.cpp.

781 {
782  // Fail if ticking currently //
783  if(TickInProgress)
784  throw InvalidState(
785  "Cannot DestroyEntity while ticking. Use QueueDestroyEntity instead");
786 
787  auto end = Entities.end();
788  for(auto iter = Entities.begin(); iter != end; ++iter) {
789 
790  if(*iter == id) {
791 
792  Entities.erase(iter);
793  _DoDestroy(id);
794  return;
795  }
796  }
797 }

◆ GetAddedFor()

DLLEXPORT bool GameWorld::GetAddedFor ( COMPONENT_TYPE  type,
std::vector< std::tuple< void *, ObjectID, ComponentTypeInfo >> &  result 
)
virtual

Gets a list of created components of type.

See also
GetRemovedFor
Todo:
Find a better way than having to have the component type specified here. This is only used by script node proxy, so this has to be somewhere for it to access

Definition at line 944 of file GameWorld.cpp.

946 {
947  return false;
948 }

◆ GetAddedForScriptDefined()

DLLEXPORT bool GameWorld::GetAddedForScriptDefined ( const std::string &  name,
std::vector< std::tuple< asIScriptObject *, ObjectID, ScriptComponentHolder *>> &  result 
)

Variant of GetAddedFor for script defined types.

Definition at line 950 of file GameWorld.cpp.

952 {
953  auto iter = pimpl->RegisteredScriptComponents.find(name);
954 
955  if(iter == pimpl->RegisteredScriptComponents.end())
956  return false;
957 
958  auto& added = iter->second->GetAdded();
959 
960  result.reserve(result.size() + added.size());
961 
962  for(const auto& tuple : added) {
963 
964  result.push_back(
965  std::make_tuple(std::get<0>(tuple), std::get<1>(tuple), iter->second.get()));
966  }
967 
968  return true;
969 }

◆ GetComponent() [1/2]

template<class TComponent >
TComponent& Leviathan::GameWorld::GetComponent ( ObjectID  id)
inline

Helper for getting component of type. This is much slower than direct lookups with the actual implementation class' GetComponent_Position etc. methods

Exceptions
NotFoundif entity has no component of the wanted type

Definition at line 199 of file GameWorld.h.

200  {
201 
202  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
203 
204  if(!std::get<1>(component))
205  throw InvalidArgument("Unrecognized component type as template parameter");
206 
207  void* ptr = std::get<0>(component);
208 
209  if(!ptr)
210  throw NotFound("Component for entity with id was not found");
211 
212  return *static_cast<TComponent*>(ptr);
213  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:199

◆ GetComponent() [2/2]

DLLEXPORT std::tuple< void *, bool > GameWorld::GetComponent ( ObjectID  id,
COMPONENT_TYPE  type 
)
virtual

Gets a component of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 908 of file GameWorld.cpp.

909 {
910  return std::make_tuple(nullptr, false);
911 }

◆ GetComponentWithType()

DLLEXPORT std::tuple< void *, ComponentTypeInfo, bool > GameWorld::GetComponentWithType ( ObjectID  id,
COMPONENT_TYPE  type 
)
virtual

Gets a component of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 913 of file GameWorld.cpp.

915 {
916  return std::make_tuple(nullptr, ComponentTypeInfo(-1, -1), false);
917 }

◆ GetEntityCount()

DLLEXPORT size_t Leviathan::GameWorld::GetEntityCount ( ) const
inline

Returns the number of ObjectIDs this world keeps track of.

Note
There may actually be more entities as it is possible to create components for ids that are not created (this is not recommended but it isn't enforced)

Definition at line 125 of file GameWorld.h.

126  {
127  return Entities.size();
128  }

◆ GetGravityAtPosition()

DLLEXPORT Float3 GameWorld::GetGravityAtPosition ( const Float3 pos)

Definition at line 767 of file GameWorld.cpp.

768 {
769  // \todo take position into account //
770  // create force without mass applied //
771  return Float3(0.f, PHYSICS_BASE_GRAVITY, 0.f);
772 }
#define PHYSICS_BASE_GRAVITY
Definition: GameWorld.h:13

◆ GetID()

DLLEXPORT int Leviathan::GameWorld::GetID ( ) const
inline

Returns the unique ID of this world.

Definition at line 104 of file GameWorld.h.

105  {
106  return ID;
107  }

◆ GetPhysicalMaterial()

DLLEXPORT int GameWorld::GetPhysicalMaterial ( const std::string &  name)

Fetches the physical material ID from the material manager.

Returns
-1 if not found. The id otherwise

Definition at line 774 of file GameWorld.cpp.

775 {
777  name, _PhysicalWorld->GetNewtonWorld());
778 }
DLLEXPORT int GetMaterialIDForWorld(const std::string &name, NewtonWorld *WorldPtr)
static DLLEXPORT PhysicsMaterialManager * Get()

◆ GetPhysicalWorld()

PhysicalWorld* Leviathan::GameWorld::GetPhysicalWorld ( )
inline

Definition at line 293 of file GameWorld.h.

294  {
295  return _PhysicalWorld.get();
296  }

◆ GetRemovedFor()

DLLEXPORT bool GameWorld::GetRemovedFor ( COMPONENT_TYPE  type,
std::vector< std::tuple< void *, ObjectID >> &  result 
)
virtual

Gets a list of destroyed components of type.

Returns
True if the type is known and no further base classes need to be checked

Definition at line 924 of file GameWorld.cpp.

926 {
927  return false;
928 }

◆ GetRemovedForScriptDefined()

DLLEXPORT bool GameWorld::GetRemovedForScriptDefined ( const std::string &  name,
std::vector< std::tuple< asIScriptObject *, ObjectID >> &  result 
)

Variant of GetRemovedFor for script defined types.

Definition at line 930 of file GameWorld.cpp.

932 {
933  auto iter = pimpl->RegisteredScriptComponents.find(name);
934 
935  if(iter == pimpl->RegisteredScriptComponents.end())
936  return false;
937 
938  auto& removed = iter->second->GetRemoved();
939 
940  result.insert(std::end(result), std::begin(removed), std::end(removed));
941  return true;
942 }

◆ GetRemovedIDsForComponents()

DLLEXPORT CScriptArray * GameWorld::GetRemovedIDsForComponents ( CScriptArray *  componenttypes)

Returns a list of ObjectIDs that have been removed from any of the specified component types.

Definition at line 1303 of file GameWorld.cpp.

1304 {
1305  if(!componenttypes)
1306  return nullptr;
1307 
1308  if(componenttypes->GetElementTypeId() !=
1310 
1311  LOG_ERROR("GameWorld: GetRemovedIDsForComponents: given an array of wrong type");
1312  componenttypes->Release();
1313  return nullptr;
1314  }
1315 
1316  std::vector<std::tuple<void*, ObjectID>> result;
1317 
1318  for(asUINT i = 0; i < componenttypes->GetSize(); ++i) {
1319 
1320  uint16_t* type = static_cast<uint16_t*>(componenttypes->At(i));
1321 
1322  if(!GetRemovedFor(static_cast<COMPONENT_TYPE>(*type), result)) {
1323 
1324  LOG_WARNING("GameWorld: GetRemovedIDsForComponents: unknown component type: " +
1325  std::to_string(*type));
1326  }
1327  }
1328 
1329  componenttypes->Release();
1330 
1331  asITypeInfo* typeInfo =
1332  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1333 
1334  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1335 
1336  if(!array)
1337  return nullptr;
1338 
1339  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1340 
1341  array->SetValue(i, &std::get<1>(result[i]));
1342  }
1343 
1344  return array;
1345 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:83
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:82
static DLLEXPORT ScriptExecutor * Get()
unsigned short uint16_t
Definition: core.h:39
virtual DLLEXPORT bool GetRemovedFor(COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID >> &result)
Gets a list of destroyed components of type.
Definition: GameWorld.cpp:924

◆ GetRemovedIDsForScriptComponents()

DLLEXPORT CScriptArray * GameWorld::GetRemovedIDsForScriptComponents ( CScriptArray *  typenames)

Returns a list of ObjectIDs that have been removed from any of the script registered component types specified by typeNames.

Definition at line 1347 of file GameWorld.cpp.

1348 {
1349  if(!typenames)
1350  return nullptr;
1351 
1352  if(typenames->GetElementTypeId() !=
1354 
1355  LOG_ERROR("GameWorld: GetRemovedIDsForScriptComponents: given an array of wrong type "
1356  "(expected array<string>)");
1357  typenames->Release();
1358  return nullptr;
1359  }
1360 
1361  std::vector<std::tuple<asIScriptObject*, ObjectID>> result;
1362 
1363  for(asUINT i = 0; i < typenames->GetSize(); ++i) {
1364 
1365  std::string* type = static_cast<std::string*>(typenames->At(i));
1366 
1367  if(!GetRemovedForScriptDefined(*type, result)) {
1368 
1369  LOG_WARNING(
1370  "GameWorld: GetRemovedIDsForScriptComponents: unknown component type: " +
1371  *type);
1372  }
1373  }
1374 
1375  typenames->Release();
1376 
1377  asITypeInfo* typeInfo =
1378  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1379 
1380  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1381 
1382  if(!array)
1383  return nullptr;
1384 
1385  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1386 
1387  array->SetValue(i, &std::get<1>(result[i]));
1388  }
1389 
1390  return array;
1391 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:83
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT bool GetRemovedForScriptDefined(const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
Variant of GetRemovedFor for script defined types.
Definition: GameWorld.cpp:930
static DLLEXPORT ScriptExecutor * Get()

◆ GetScene()

Ogre::SceneManager* Leviathan::GameWorld::GetScene ( )
inline

Definition at line 285 of file GameWorld.h.

286  {
287  return WorldsScene;
288  }

◆ GetScriptComponentHolder()

DLLEXPORT ScriptComponentHolder * GameWorld::GetScriptComponentHolder ( const std::string &  name)

Retrieves a script registered component type holder.

Note
Increments refcount on return value

Definition at line 1410 of file GameWorld.cpp.

1411 {
1412  // if called after release
1413  if(!pimpl)
1414  return nullptr;
1415 
1416  auto iter = pimpl->RegisteredScriptComponents.find(name);
1417 
1418  if(iter == pimpl->RegisteredScriptComponents.end())
1419  return nullptr;
1420 
1421  iter->second->AddRef();
1422  return iter->second.get();
1423 }

◆ GetScriptSystem()

DLLEXPORT asIScriptObject * GameWorld::GetScriptSystem ( const std::string &  name)

Returns the underlying angelscript object that implements a script system.

Note
Increases refcount on returned object

Definition at line 1454 of file GameWorld.cpp.

1455 {
1456  // if called after release
1457  if(!pimpl)
1458  return nullptr;
1459 
1460  auto iter = pimpl->RegisteredScriptSystems.find(name);
1461 
1462  // Skip if already registered //
1463  if(iter == pimpl->RegisteredScriptSystems.end()) {
1464 
1465  LOG_ERROR("GameWorld: GetScriptSystemDirect: world has no system called: " + name);
1466  return nullptr;
1467  }
1468 
1469  return iter->second->GetASImplementationObject();
1470 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ GetStatesFor() [1/2]

template<class TComponent >
StateHolder<typename TComponent::StateT>& Leviathan::GameWorld::GetStatesFor ( )
inline

Helper for getting component state holder for type. This is much slower than direct lookups with the actual implementation class' GetStatesFor_Position etc. methods

Exceptions
NotFoundif entity has no component of the wanted type

Definition at line 231 of file GameWorld.h.

232  {
233 
234  std::tuple<void*, bool> stateHolder = GetStatesFor(TComponent::TYPE);
235 
236  if(!std::get<1>(stateHolder))
237  throw InvalidArgument("Unrecognized component type as template parameter for "
238  "state holder");
239 
240  void* ptr = std::get<0>(stateHolder);
241 
242  return *static_cast<StateHolder<typename TComponent::StateT>*>(ptr);
243  }
StateHolder< typename TComponent::StateT > & GetStatesFor()
Definition: GameWorld.h:231

◆ GetStatesFor() [2/2]

DLLEXPORT std::tuple< void *, bool > GameWorld::GetStatesFor ( COMPONENT_TYPE  type)
virtual

Gets a component states of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 919 of file GameWorld.cpp.

920 {
921  return std::make_tuple(nullptr, false);
922 }

◆ GetTickAndTime()

DLLEXPORT std::tuple< int, int > GameWorld::GetTickAndTime ( ) const

Returns a tuple of the current tick number and how long it has passed since last tick.

The tick number is always adjusted so that the time since last tick is < TICKSPEED

Definition at line 667 of file GameWorld.cpp.

668 {
669  int tick = TickNumber;
670  int timeSince = static_cast<int>(Engine::Get()->GetTimeSinceLastTick());
671 
672  while(timeSince >= TICKSPEED) {
673 
674  ++tick;
675  timeSince -= TICKSPEED;
676  }
677 
678  return std::make_tuple(tick, timeSince);
679 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT int64_t GetTimeSinceLastTick() const
Calculates how long has elapsed since the last tick.
Definition: Engine.cpp:1202
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:82

◆ GetTickNumber()

DLLEXPORT int GameWorld::GetTickNumber ( ) const

Returns the current tick.

Definition at line 652 of file GameWorld.cpp.

653 {
654  return TickNumber;
655 }

◆ GetTickProgress()

DLLEXPORT float GameWorld::GetTickProgress ( ) const

Returns float between 0.f and 1.f based on how far current tick has progressed.

Definition at line 657 of file GameWorld.cpp.

658 {
659  float progress = Engine::Get()->GetTimeSinceLastTick() / (float)TICKSPEED;
660 
661  if(progress < 0.f)
662  return 0.f;
663 
664  return progress < 1.f ? progress : 1.f;
665 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT int64_t GetTimeSinceLastTick() const
Calculates how long has elapsed since the last tick.
Definition: Engine.cpp:1202
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:82

◆ HandleAddedAndDeleted()

DLLEXPORT void GameWorld::HandleAddedAndDeleted ( )
protectedvirtual

Handles added entities and components.

Construct new nodes based on components values. This is split into multiple parts to support child classes using the same Component types in additional nodes

Definition at line 584 of file GameWorld.cpp.

585 {
586  // We are responsible for script systems //
587  for(auto iter = pimpl->RegisteredScriptSystems.begin();
588  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
589 
590  iter->second->CreateAndDestroyNodes();
591  }
592 }

◆ HandleClockSyncPacket()

DLLEXPORT void GameWorld::HandleClockSyncPacket ( RequestWorldClockSync *  data)

Handles a world clock synchronizing packet.

Note
This should only be allowed to be called on a client that has connected to a server

Definition at line 1250 of file GameWorld.cpp.

1251 {
1252  Logger::Get()->Info(
1253  "GameWorld: adjusting our clock: Absolute: " + Convert::ToString(data->Absolute) +
1254  ", tick: " + Convert::ToString(data->Ticks) +
1255  ", engine ms: " + Convert::ToString(data->EngineMSTweak));
1256 
1257  // Change our TickNumber to match //
1258  Engine::Get()->_AdjustTickNumber(data->Ticks, data->Absolute);
1259 
1260  if(data->EngineMSTweak)
1261  Engine::Get()->_AdjustTickClock(data->EngineMSTweak, data->Absolute);
1262 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
void _AdjustTickNumber(int tickamount, bool absolute)
Sets the tick number to a specified value.
Definition: Engine.cpp:1247
void _AdjustTickClock(int amount, bool absolute=true)
Sets the tick clock to a certain value.
Definition: Engine.cpp:1214
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:82

◆ HandleEntityInitialPacket()

DLLEXPORT void GameWorld::HandleEntityInitialPacket ( std::shared_ptr< NetworkResponse message,
ResponseEntityCreation *  data 
)

Creates a new entity from initial entity response.

Note
This should only be called on the client

Definition at line 1157 of file GameWorld.cpp.

1159 {
1160  if(!data)
1161  return;
1162 
1163  InitialEntityPackets.push_back(message);
1164 }

◆ HandleEntityUpdatePacket()

DLLEXPORT void GameWorld::HandleEntityUpdatePacket ( std::shared_ptr< NetworkResponse message)

Applies an update packet.

If the entity is not found the packet is discarded

Todo:
Cache the update data for 1 second and apply it if a matching entity is created during that time

Definition at line 1190 of file GameWorld.cpp.

1191 {
1192  if(message->GetType() == NETWORK_RESPONSE_TYPE::EntityUpdate)
1193  return;
1194 
1195  EntityUpdatePackets.push_back(message);
1196 }

◆ HandleWorldFrozenPacket()

DLLEXPORT void GameWorld::HandleWorldFrozenPacket ( ResponseWorldFrozen *  data)

Handles a world freeze/unfreeze packet.

Note
Should only be called on a client

Definition at line 1264 of file GameWorld.cpp.

1265 {
1266  Logger::Get()->Info(
1267  "GameWorld(" + Convert::ToString(ID) +
1268  "): frozen state updated, now: " + Convert::ToString<int>(data->Frozen) +
1269  ", tick: " + Convert::ToString(data->TickNumber) +
1270  " (our tick:" + Convert::ToString(TickNumber) + ")");
1271 
1272  if(data->TickNumber > TickNumber) {
1273 
1274  Logger::Get()->Write("TODO: freeze the world in the future");
1275  }
1276 
1277  // Set the state //
1278  SetWorldPhysicsFrozenState(data->Frozen);
1279 
1280  // Simulate ticks if required //
1281  if(!data->Frozen) {
1282 
1283  // Check how many ticks we are behind and simulate that number of physical updates //
1284  int tickstosimulate = TickNumber - data->TickNumber;
1285 
1286  if(tickstosimulate > 0) {
1287 
1288  Logger::Get()->Info("GameWorld: unfreezing and simulating " +
1289  Convert::ToString(tickstosimulate * TICKSPEED) +
1290  " ms worth of more physical updates");
1291 
1292  _PhysicalWorld->AdjustClock(tickstosimulate * TICKSPEED);
1293  }
1294 
1295 
1296  } else {
1297 
1298  // Snap objects back //
1299  Logger::Get()->Info("TODO: world freeze snap things back a bit");
1300  }
1301 }
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT void SetWorldPhysicsFrozenState(bool frozen)
Definition: GameWorld.cpp:1036
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

◆ Init()

DLLEXPORT bool GameWorld::Init ( NETWORKED_TYPE  type,
Ogre::Root *  ogre 
)

Creates resources for the world to work.

Postcondition
The world can be used after this

Definition at line 93 of file GameWorld.cpp.

94 {
96 
97  // Detecting non-GUI mode //
98  if(ogre) {
99 
100  if(!ogre)
101  return false;
102 
103  GraphicalMode = true;
104  // these are always required for worlds //
105  _CreateOgreResources(ogre);
106  }
107 
108  // Acquire physics engine world //
109  // This should not be required if it isn't available
110  if(NewtonManager::Get()) {
111 
112  _PhysicalWorld = NewtonManager::Get()->CreateWorld(this);
113  }
114 
115  _DoSystemsInit();
116  return true;
117 }
DLLEXPORT std::shared_ptr< PhysicalWorld > CreateWorld(GameWorld *owningworld)
static DLLEXPORT NewtonManager * Get()
Definition: NewtonManager.h:19
virtual DLLEXPORT void _DoSystemsInit()
Called in Init when systems should run their initialization logic.
Definition: GameWorld.cpp:972
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:478

◆ IsConnectionInWorld()

DLLEXPORT bool GameWorld::IsConnectionInWorld ( Connection connection) const

Returns true if a player with the given connection is receiving updates for this world.

Definition at line 386 of file GameWorld.cpp.

387 {
388 
389  for(auto& player : ReceivingPlayers) {
390 
391  if(player->GetConnection().get() == &connection) {
392 
393  return true;
394  }
395  }
396 
397  return false;
398 }

◆ MarkForClear()

DLLEXPORT void GameWorld::MarkForClear ( )

Marks all entities to be deleted.

Definition at line 1101 of file GameWorld.cpp.

1102 {
1103  ClearAllEntities = true;
1104 }

◆ NotifyEntityCreate()

DLLEXPORT void GameWorld::NotifyEntityCreate ( ObjectID  id)

Notifies others that we have created a new entity.

Note
This is called after all components are set up and it is ready to be sent to other players
Clients should also call this function
Todo:
Allow to set the world to queue objects and send them in big bunches to players

Definition at line 691 of file GameWorld.cpp.

692 {
693  if(IsOnServer) {
694 
695  // This is at least a decent place to send them,
696  Sendable* issendable = nullptr;
697 
698  try {
699  issendable = &GetComponent<Sendable>(id);
700 
701  } catch(const NotFound&) {
702 
703  // Not sendable no point in continuing //
704  return;
705  }
706 
707  LEVIATHAN_ASSERT(issendable, "GetComponent didn't throw");
708 
709  auto end = ReceivingPlayers.end();
710  for(auto iter = ReceivingPlayers.begin(); iter != end; ++iter) {
711 
712  auto safe = (*iter)->GetConnection();
713 
714  if(!safe->IsValidForSend()) {
715  // Player has probably closed their connection //
716  continue;
717  }
718 
719  // TODO: pass issendable here to avoid an extra lookup
720  if(!SendEntityToConnection(id, safe)) {
721 
722  Logger::Get()->Warning("GameWorld: CreateEntity: failed to send "
723  "object to player (" +
724  (*iter)->GetNickname() + ")");
725 
726  continue;
727  }
728  }
729 
730  } else {
731 
732  // Clients register received objects here //
733  Entities.push_back(id);
734  }
735 }
DLLEXPORT bool SendEntityToConnection(ObjectID obj, std::shared_ptr< Connection > connection)
Sends an entity to a connection and sets everything up.
Definition: GameWorld.cpp:1128
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
Entity is sendable to clients.
Definition: Components.h:98

◆ OnLinkToWindow()

DLLEXPORT void GameWorld::OnLinkToWindow ( Window window,
Ogre::Root *  ogre 
)
virtual

Called when this is added to a Window.

Note
This creates a compositor workspace that renders this world's scene to the window

Definition at line 1497 of file GameWorld.cpp.

1498 {
1499  LEVIATHAN_ASSERT(WorldsScene, "World is not initialized");
1500 
1501  if(!window)
1502  throw InvalidArgument("GameWorld attempted to be linked to a nullptr window");
1503 
1504  if(LinkedToWindow || WorldWorkspace) {
1505 
1506  throw InvalidArgument(
1507  "GameWorld attempted to be linked to a window while it is already linked");
1508  }
1509 
1510  LinkedToWindow = window;
1511 
1512  // Create the workspace for this scene //
1513  // Which will be rendered before the overlay workspace but after potential
1514  // clearing workspace
1515  WorldWorkspace = ogre->getCompositorManager2()->addWorkspace(WorldsScene,
1516  LinkedToWindow->GetOgreWindow(), WorldSceneCamera, "WorldsWorkspace", true, 0);
1517 
1518  if(!TickWhileInBackground) {
1519  _DoResumeSystems();
1520  }
1521 
1522  InBackground = false;
1523 }
DLLEXPORT Ogre::RenderWindow * GetOgreWindow() const
Definition: Window.h:159
virtual DLLEXPORT void _DoResumeSystems()
Opposite of _DoSuspendSystems.
Definition: GameWorld.cpp:1003

◆ OnUnLinkedFromWindow()

DLLEXPORT void GameWorld::OnUnLinkedFromWindow ( Window window,
Ogre::Root *  ogre 
)
virtual

Used to detect that this world is in the background and should not tick.

Note
Removes the workspace created in OnLinkToWindow

Definition at line 1472 of file GameWorld.cpp.

1473 {
1474  if(!LinkedToWindow) {
1475  LOG_WARNING(
1476  "GameWorld: unlink from window called while this wasn't linked to a window");
1477  return;
1478  }
1479 
1480  if(window != LinkedToWindow) {
1481 
1482  throw InvalidArgument("GameWorld attempted to be unlinked from window that wasn't the "
1483  "one it was linked to");
1484  }
1485 
1486  ogre->getCompositorManager2()->removeWorkspace(WorldWorkspace);
1487  WorldWorkspace = nullptr;
1488  LinkedToWindow = nullptr;
1489 
1490  if(!TickWhileInBackground) {
1492  }
1493 
1494  InBackground = true;
1495 }
virtual DLLEXPORT void _DoSuspendSystems()
Called when this is put in the background and systems (the sound system) should suspend their active ...
Definition: GameWorld.cpp:993
#define LOG_WARNING(x)
Definition: Define.h:82

◆ QueueDestroyEntity()

DLLEXPORT void GameWorld::QueueDestroyEntity ( ObjectID  id)

Deletes an entity during the next tick.

Definition at line 799 of file GameWorld.cpp.

800 {
801  Lock lock(DeleteMutex);
802  DelayedDeleteIDS.push_back(id);
803 }
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15

◆ REFERENCE_HANDLE_UNCOUNTED_TYPE()

Leviathan::GameWorld::REFERENCE_HANDLE_UNCOUNTED_TYPE ( GameWorld  )

◆ RegisterScriptComponentType()

DLLEXPORT bool GameWorld::RegisterScriptComponentType ( const std::string &  name,
asIScriptFunction *  factory 
)

Registers a component type from scripts.

Definition at line 1393 of file GameWorld.cpp.

1395 {
1396  // Skip if already registered //
1397  if(pimpl->RegisteredScriptComponents.find(name) !=
1398  pimpl->RegisteredScriptComponents.end()) {
1399  factory->Release();
1400  return false;
1401  }
1402 
1403  // ScriptComponentHolder takes care of releasing the reference
1404  pimpl->RegisteredScriptComponents[name] =
1405  ScriptComponentHolder::MakeShared<ScriptComponentHolder>(name, factory, this);
1406 
1407  return true;
1408 }

◆ RegisterScriptSystem()

DLLEXPORT bool GameWorld::RegisterScriptSystem ( const std::string &  name,
asIScriptObject *  system 
)

Registers a new system defined in a script. Must implement the ScriptSystem interface.

Definition at line 1425 of file GameWorld.cpp.

1427 {
1428  if(!system) {
1429  LOG_ERROR("GameWorld: RegisterScriptSystem: passed null object as new system");
1430  return false;
1431  }
1432 
1433  // if called after release
1434  if(!pimpl) {
1435  system->Release();
1436  return false;
1437  }
1438 
1439  // Skip if already registered //
1440  if(pimpl->RegisteredScriptSystems.find(name) != pimpl->RegisteredScriptSystems.end()) {
1441  system->Release();
1442  return false;
1443  }
1444 
1445  // Create a wrapper for it //
1446  // The wrapper handles unreferencing the handle
1447  pimpl->RegisteredScriptSystems[name] = std::make_unique<ScriptSystemWrapper>(name, system);
1448 
1449  // Might as well call Init now as other systems are almost certainly initialized as well //
1450  pimpl->RegisteredScriptSystems[name]->Init(this);
1451  return true;
1452 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ Release()

DLLEXPORT void GameWorld::Release ( )

Release to not use Ogre when deleting.

Definition at line 119 of file GameWorld.cpp.

120 {
122 
123  (*WorldDestroyed) = true;
124 
125  ReceivingPlayers.clear();
126 
127  // release objects //
128  // TODO: allow objects to know that they are about to get killed
129 
130  // As all objects are just pointers to components we can just dump the objects
131  // and once the component pools are released
132  ClearEntities();
133 
134  if(GraphicalMode) {
135  // TODO: notify our window that it no longer has a world workspace
136  LinkedToWindow = nullptr;
137 
138  // release Ogre resources //
139 
140  // Destroy the compositor //
141  Ogre::Root& ogre = Ogre::Root::getSingleton();
142 
143  // Allow releasing twice
144  if(WorldWorkspace) {
145  ogre.getCompositorManager2()->removeWorkspace(WorldWorkspace);
146  WorldWorkspace = nullptr;
147  }
148 
149  if(WorldsScene) {
150  ogre.destroySceneManager(WorldsScene);
151  WorldsScene = nullptr;
152  }
153  }
154 
155  // This should be relatively cheap if the newton threads don't deadlock while waiting
156  // for each other
157  _PhysicalWorld.reset();
158 
159  // Let go of our these resources
160  pimpl.reset();
161 }
virtual DLLEXPORT void _DoSystemsRelease()
Called in Release when systems should run their shutdown logic.
Definition: GameWorld.cpp:977
DLLEXPORT void ClearEntities()
Clears all objects from the world.
Definition: GameWorld.cpp:737
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:478

◆ RemoveSunlight()

DLLEXPORT void GameWorld::RemoveSunlight ( )

Definition at line 243 of file GameWorld.cpp.

244 {
245  if(SunLightNode) {
246  SunLightNode->detachAllObjects();
247  // might be safe to delete
248  OGRE_DELETE SunLightNode;
249  SunLightNode = nullptr;
250  }
251 }

◆ Render()

DLLEXPORT void GameWorld::Render ( int  mspassed,
int  tick,
int  timeintick 
)

Runs systems required for a rendering run. Also updates camera positions.

Todo:
Allow script systems to specify their type

Definition at line 273 of file GameWorld.cpp.

274 {
275  if(InBackground) {
276 
277  LOG_ERROR("GameWorld: Render: called while world is in the background (not attached "
278  "to a window)");
279  return;
280  }
281 
282  RunFrameRenderSystems(tick, timeintick);
283 
284  // Read camera entity and update position //
285 
286  // Skip if no camera //
287  if(CameraEntity == 0)
288  return;
289 
290  try {
291  Camera& properties = GetComponent<Camera>(CameraEntity);
292 
293  Position& position = GetComponent<Position>(CameraEntity);
294 
295  auto& states = GetStatesFor<Position>();
296 
297  // set camera position //
298  const auto interpolated =
299  StateInterpolator::Interpolate(states, CameraEntity, &position, tick, timeintick);
300 
301  if(!std::get<0>(interpolated)) {
302 
303  // No interpolated pos //
304  WorldSceneCamera->setPosition(position.Members._Position);
305  WorldSceneCamera->setOrientation(position.Members._Orientation);
306 
307  } else {
308 
309  const auto& interpolatedPos = std::get<1>(interpolated);
310  WorldSceneCamera->setPosition(interpolatedPos._Position);
311  WorldSceneCamera->setOrientation(interpolatedPos._Orientation);
312  }
313 
314  if(properties.SoundPerceiver) {
315 
317  position.Members._Position, position.Members._Orientation);
318  }
319 
320  if(properties.Marked || AppliedCameraPropertiesPtr != &properties) {
321 
322  AppliedCameraPropertiesPtr = &properties;
323 
324  WorldSceneCamera->setFOVy(Ogre::Degree(properties.FOVY));
325 
326  properties.Marked = false;
327  }
328 
329  } catch(const Exception& e) {
330 
331  LOG_ERROR("GameWorld: Render: camera update failed. Was a component removed?, "
332  "exception:");
333  e.PrintToLog();
334  CameraEntity = 0;
335  return;
336  }
337 }
#define LOG_ERROR(x)
Definition: Define.h:83
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
static std::tuple< bool, StateT > Interpolate(const StateHolder< StateT > &stateholder, ObjectID entity, ComponentT *entitycomponent, int currenttick, int timeintick)
Interpolates states for component.
Entity has position and direction it is looking at.
Definition: Components.h:45
SoundDevice * GetSoundDevice()
Definition: Engine.h:184
DLLEXPORT void SetSoundListenerPosition(const Float3 &pos, const Float4 &orientation)
Loads the file and plays the sound.
virtual DLLEXPORT void RunFrameRenderSystems(int tick, int timeintick)
Called by Render which is called from a Window if this is linked to one.
Definition: GameWorld.cpp:633
Properties that a camera entity has (will also need a Position component)
Definition: Components.h:779
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:82

◆ RunFrameRenderSystems()

DLLEXPORT void GameWorld::RunFrameRenderSystems ( int  tick,
int  timeintick 
)
protectedvirtual

Called by Render which is called from a Window if this is linked to one.

Definition at line 633 of file GameWorld.cpp.

634 {
635  // Don't have any systems, but these updates may be important for interpolation //
636  _ApplyEntityUpdatePackets();
637 
638  // TODO: if there are any impactful simulation done here it needs to be also inside a block
639  // where TickInProgress is set to true
640 }

◆ SendEntityToConnection()

DLLEXPORT bool GameWorld::SendEntityToConnection ( ObjectID  obj,
std::shared_ptr< Connection connection 
)

Sends an entity to a connection and sets everything up.

Postcondition
The connection will receive updates from the entity
Returns
True when a packet was sent false otherwise

Definition at line 1128 of file GameWorld.cpp.

1130 {
1131  // First create a packet which will be the object's data //
1132 
1133  sf::Packet packet;
1134 
1135  DEBUG_BREAK;
1136  // try {
1137  // if (!Engine::Get()->GetEntitySerializer()->CreatePacketForConnection(this, id,
1138  // GetComponent<Sendable>(id), packet, *connection))
1139  // {
1140  // return false;
1141  // }
1142  // }
1143  // catch (const NotFound&) {
1144  // return false;
1145  // }
1146 
1147  // Then gather all sorts of other stuff to make an response //
1148  return connection
1149  ->SendPacketToConnection(
1150  std::make_shared<ResponseEntityCreation>(0, id, std::move(packet)),
1152  .get() ?
1153  true :
1154  false;
1155 }

◆ SendToAllPlayers()

DLLEXPORT void GameWorld::SendToAllPlayers ( const std::shared_ptr< NetworkResponse > &  response,
RECEIVE_GUARANTEE  guarantee 
) const

Sends a packet to all connected players.

Definition at line 495 of file GameWorld.cpp.

497 {
498  // Notify everybody that an entity has been destroyed //
499  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
500 
501  auto safe = (*iter)->GetConnection();
502 
503  if(!safe->IsValidForSend()) {
504  // Player has probably closed their connection //
505  continue;
506  }
507 
508  safe->SendPacketToConnection(response, guarantee);
509  }
510 }

◆ SetCamera()

DLLEXPORT void GameWorld::SetCamera ( ObjectID  object)

Sets the entity that acts as a camera.

The entity needs atleast Position and Camera components

Exceptions
InvalidArgumentif the object is missing required components

Definition at line 339 of file GameWorld.cpp.

340 {
341  CameraEntity = object;
342 
343  AppliedCameraPropertiesPtr = nullptr;
344 
345  if(CameraEntity == NULL_OBJECT)
346  return;
347 
348  // Check components //
349  try {
350  GetComponent<Camera>(object);
351  } catch(const NotFound&) {
352 
353  throw InvalidArgument("SetCamera object is missing a needed component (Camera)");
354  }
355 
356  try {
357  GetComponent<Position>(object);
358  } catch(const NotFound&) {
359 
360  throw InvalidArgument("SetCamera object is missing a needed component (Position)");
361  }
362 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ SetEntitysParent()

DLLEXPORT void GameWorld::SetEntitysParent ( ObjectID  child,
ObjectID  parent 
)

Makes child entity be deleted when parent is deleted.

Note
Doesn't check that the entitiy ids exist

Definition at line 903 of file GameWorld.cpp.

904 {
905  Parents.push_back(std::make_tuple(parent, child));
906 }

◆ SetFog()

DLLEXPORT void GameWorld::SetFog ( )
Todo:
Fix this for Ogre 2.1

Definition at line 203 of file GameWorld.cpp.

204 {
205  WorldsScene->setFog(Ogre::FOG_LINEAR, Ogre::ColourValue(0.7f, 0.7f, 0.8f), 0, 4000, 10000);
206  WorldsScene->setFog(Ogre::FOG_NONE);
207 }

◆ SetLightProperties()

DLLEXPORT void GameWorld::SetLightProperties ( const Ogre::ColourValue &  diffuse,
const Ogre::ColourValue &  specular,
const Ogre::Vector3 &  direction,
float  power,
const Ogre::ColourValue &  upperhemisphere,
const Ogre::ColourValue &  lowerhemisphere,
const Ogre::Vector3 &  hemispheredir,
float  envmapscale = 1.0f 
)

Sets the sunlight properties.

Precondition
SetSunlight has been called

Definition at line 253 of file GameWorld.cpp.

257 {
258  if(!Sunlight || !SunLightNode) {
259 
260  LOG_ERROR("GameWorld: SetLightProperties: world doesn't have sun light set");
261  return;
262  }
263 
264  Sunlight->setDiffuseColour(diffuse);
265  Sunlight->setSpecularColour(specular);
266  Sunlight->setDirection(direction);
267  Sunlight->setPowerScale(power);
268 
269  WorldsScene->setAmbientLight(upperhemisphere, lowerhemisphere, hemispheredir, envmapscale);
270 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ SetPlayerReceiveWorld()

DLLEXPORT void GameWorld::SetPlayerReceiveWorld ( std::shared_ptr< ConnectedPlayer ply)

Verifies that player is receiving this world.

Definition at line 400 of file GameWorld.cpp.

401 {
402 
403  // Skip if already added //
404  for(auto& player : ReceivingPlayers) {
405 
406  if(player == ply) {
407 
408  return;
409  }
410  }
411 
412  Logger::Get()->Info(
413  "GameWorld: player(\"" + ply->GetNickname() + "\") is now receiving world");
414 
415  // Add them to the list of receiving players //
416  ReceivingPlayers.push_back(ply);
417 
418  if(!ply->GetConnection()->IsValidForSend()) {
419 
420  // The closing should be handled by somebody else
421  Logger::Get()->Error("GameWorld: requested to sync with a player who has closed their "
422  "connection");
423 
424  return;
425  }
426 
427  // Update the position data //
428  UpdatePlayersPositionData(*ply);
429 
430  // Start sending initial update //
431  Logger::Get()->Info(
432  "Starting to send " + Convert::ToString(Entities.size()) + " to player");
433 
434  // Now we can queue all objects for sending //
435  // TODO: make sure that all objects are sent
436  // TODO: redo this inside the world tick
437  // ThreadingManager::Get()->QueueTask(
438  // new RepeatCountedTask(std::bind<void>([](
439  // std::shared_ptr<Connection> connection,
440  // std::shared_ptr<ConnectedPlayer> processingobject, GameWorld* world,
441  // std::shared_ptr<bool> WorldInvalid)
442  // -> void
443  // {
444  // // Get the next object //
445  // RepeatCountedTask* task =
446  // dynamic_cast<RepeatCountedTask*>(TaskThread::GetThreadSpecificThreadObject()->
447  // QuickTaskAccess.get());
448 
449  // LEVIATHAN_ASSERT(task, "wrong type passed to our task");
450 
451  // size_t num = task->GetRepeatCount();
452 
453  // if(*WorldInvalid){
454 
455  // taskstopprocessingobjectsforinitialsynclabel:
456 
457  // // Stop processing //
458  // task->StopRepeating();
459  // return;
460  // }
461 
462  // // Stop if out of bounds //
463  // if(num >= world->Entities.size()){
464 
465  // goto taskstopprocessingobjectsforinitialsynclabel;
466  // }
467 
468  // // Get the object //
469  // auto tosend = world->Entities[num];
470 
471  // // Skip if shouldn't send //
472  // try{
473 
474  // auto& position = world->GetComponent<Position>(tosend);
475 
476  // if(!world->ShouldPlayerReceiveObject(position, *connection)){
477 
478  // return;
479  // }
480 
481  // } catch(const NotFound&){
482 
483  // // No position, should probably always send //
484  // }
485 
486 
487  // // Send it //
488  // world->SendObjectToConnection(guard, tosend, connection);
489 
490  // return;
491 
492  // }, ply->GetConnection(), ply, this, WorldDestroyed), Entities.size()));
493 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177

◆ SetRunInBackground()

DLLEXPORT void GameWorld::SetRunInBackground ( bool  tickinbackground)
virtual

Configures this world to run tick even when not attached to a window.

Definition at line 1525 of file GameWorld.cpp.

1526 {
1527  TickWhileInBackground = tickinbackground;
1528 }

◆ SetSunlight()

DLLEXPORT void GameWorld::SetSunlight ( )

Definition at line 209 of file GameWorld.cpp.

210 {
211  // create/update things if they are nullptr //
212  if(!Sunlight) {
213  Sunlight = WorldsScene->createLight();
214  Sunlight->setName("sunlight");
215  }
216 
217  if(!SunLightNode) {
218 
219  SunLightNode = WorldsScene->getRootSceneNode()->createChildSceneNode();
220  SunLightNode->setName("sunlight node");
221 
222  SunLightNode->attachObject(Sunlight);
223  }
224 
225  Sunlight->setType(Ogre::Light::LT_DIRECTIONAL);
226  // Sunlight->setDiffuseColour(0.98f, 1.f, 0.95f);
227  Sunlight->setDiffuseColour(1.f, 1.f, 1.f);
228  Sunlight->setSpecularColour(1.f, 1.f, 1.f);
229  // Sunlight->setDirection(Float3(-1, -1, -1).Normalize());
230  Sunlight->setDirection(Float3(0.55f, -0.3f, 0.75f).Normalize());
231  Sunlight->setPowerScale(7.0f);
232 
233  // Set scene ambient colour //
234  // TODO: Ogre samples also use this so maybe this works with PBR HLMS system
235  // WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.5f, 0.7f) * 0.1f * 0.75f,
236  // Ogre::ColourValue(0.6f, 0.45f, 0.3f) * 0.065f * 0.75f,
237  // -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
238  WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f),
239  Ogre::ColourValue(0.2f, 0.2f, 0.2f), /*Ogre::Vector3(0.1f, 1.f, 0.085f),*/
240  -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
241 }

◆ SetWorldPhysicsFrozenState()

DLLEXPORT void GameWorld::SetWorldPhysicsFrozenState ( bool  frozen)
Todo:
Synchronize this over the network

Definition at line 1036 of file GameWorld.cpp.

1037 {
1038  // Skip if set to the same //
1039  if(frozen == WorldFrozen)
1040  return;
1041 
1042  WorldFrozen = frozen;
1043 
1044  // Send it to receiving players (if we are a server) //
1045  if(ReceivingPlayers.empty())
1046  return;
1047 
1048  // Should be safe to create the packet now and send it to all the connections //
1049  SendToAllPlayers(std::make_shared<ResponseWorldFrozen>(0, ID, WorldFrozen, TickNumber),
1051 }
DLLEXPORT void SendToAllPlayers(const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
Sends a packet to all connected players.
Definition: GameWorld.cpp:495

◆ ShouldPlayerReceiveEntity()

DLLEXPORT bool GameWorld::ShouldPlayerReceiveEntity ( Position atposition,
Connection connection 
)

Returns true when the player matching the connection should receive updates about an entity.

Todo:
Implement this

Definition at line 379 of file GameWorld.cpp.

381 {
382 
383  return true;
384 }

◆ Tick()

DLLEXPORT void GameWorld::Tick ( int  currenttick)

Used to keep track of passed ticks and trigger timed triggers.

Note
This will be called (or should be) every time the engine ticks
This cannot be used for accurate time keeping for that use timers, but for events that need to happen at certain game world times this is ideal

Definition at line 512 of file GameWorld.cpp.

513 {
514  if(InBackground && !TickWhileInBackground)
515  return;
516 
517  TickNumber = currenttick;
518 
519  // Apply queued packets //
521 
522  _HandleDelayedDelete();
523 
524  // All required nodes for entities are created //
527 
528  // Remove closed player connections //
529 
530  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
531 
532  if(!(*iter)->GetConnection()->IsValidForSend()) {
533 
534  DEBUG_BREAK;
535 
536  } else {
537 
538  ++iter;
539  }
540  }
541 
542  // Simulate physics //
543  if(!WorldFrozen) {
544 
545  // TODO: a game type that is a client and server at the same time
546  // if(IsOnServer) {
547 
548  _ApplyEntityUpdatePackets();
549  if(_PhysicalWorld)
550  _PhysicalWorld->SimulateWorldFixed(TICKSPEED, 2);
551 
552  // } else {
553 
554  // Simulate direct control //
555  // }
556  }
557 
558  TickInProgress = true;
559 
560  _RunTickSystems();
561 
562  TickInProgress = false;
563 
564  // Sendable objects may need something to be done //
565 
566  if(IsOnServer) {
567 
568  // Notify new entities //
569  // DEBUG_BREAK;
570 
571  // Skip if not tick that will be stored //
572  // if(TickNumber % WORLD_OBJECT_UPDATE_CLIENTS_INTERVAL == 0){
573 
574  // _SendableSystem.Run(ComponentSendable.GetIndex(), *this);
575  // }
576 
577  } else {
578 
579  // TODO: direct control objects
580  // _ReceivedSystem.Run(ComponentReceived.GetIndex(), *this);
581  }
582 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
virtual DLLEXPORT void HandleAddedAndDeleted()
Handles added entities and components.
Definition: GameWorld.cpp:584
DLLEXPORT void ApplyQueuedPackets()
Applies packets that have been received after the last call to this.
Definition: GameWorld.cpp:1241
virtual DLLEXPORT void ClearAddedAndRemoved()
Clears the added components. Call after HandleAddedAndDeleted.
Definition: GameWorld.cpp:594
virtual DLLEXPORT void _RunTickSystems()
Called by Tick.
Definition: GameWorld.cpp:642

Member Data Documentation

◆ GraphicalMode

bool Leviathan::GameWorld::GraphicalMode = false
protected

If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.

Used on dedicated servers and other headless applications

Definition at line 478 of file GameWorld.h.

◆ IsOnServer

bool Leviathan::GameWorld::IsOnServer = false
protected

Bool flag telling whether this is a master world (on a server) or a mirroring world (client)

Definition at line 482 of file GameWorld.h.


The documentation for this class was generated from the following files: