Leviathan  0.8.0.0
Leviathan game engine
Leviathan::Engine Class Reference

The main class of the Leviathan Game Engine. More...

#include <Engine.h>

+ Inheritance diagram for Leviathan::Engine:

Public Member Functions

DLLEXPORT Engine (LeviathanApplication *owner)
 
DLLEXPORT ~Engine ()
 
DLLEXPORT bool Init (AppDef *definition, NETWORKED_TYPE ntype, NetworkInterface *packethandler)
 
DLLEXPORT void Release (bool forced=false)
 
DLLEXPORT void PreRelease ()
 Sets objects ready to be released. More...
 
DLLEXPORT bool HasPreReleaseBeenDone () const
 Checks if PreRelease is done and Release can be called. More...
 
DLLEXPORT int64_t GetTimeSinceLastTick () const
 Calculates how long has elapsed since the last tick. More...
 
DLLEXPORT int GetCurrentTick () const
 Returns the number of tick that was last simulated. More...
 
DLLEXPORT void MessagePump ()
 Processes queued messages from Ogre, SDL and input. More...
 
DLLEXPORT void Tick ()
 
DLLEXPORT void RenderFrame ()
 
DLLEXPORT void PreFirstTick ()
 
DLLEXPORT int GetWindowOpenCount ()
 
DLLEXPORT void ClearTimers ()
 Clears physical timers. More...
 
DLLEXPORT void MarkQuit ()
 Marks the owning application to quit. More...
 
DLLEXPORT void Invoke (const std::function< void()> &function)
 Runs function on the main thread before the next tick. More...
 
DLLEXPORT void RunOnMainThread (const std::function< void()> &function)
 Runs the function now if on the main thread otherwise calls Invoke. More...
 
DLLEXPORT bool IsOnMainThread () const
 Returns true if called on the main thread. More...
 
DLLEXPORT void AssertIfNotMainThread () const
 Asserts if not called on the main thread. More...
 
DLLEXPORT bool PassCommandLine (int argcount, char *args[])
 
DLLEXPORT std::shared_ptr< GameWorldCreateWorld (Window *owningwindow, int worldtype)
 Creates a GameWorld for placing entities into. More...
 
DLLEXPORT void DestroyWorld (const std::shared_ptr< GameWorld > &world)
 Releases a GameWorld. More...
 
DLLEXPORT WindowOpenNewWindow ()
 Opens a new window. More...
 
DLLEXPORT WindowGetWindowEntity ()
 Returns the main window. More...
 
DLLEXPORT void ReportClosedWindow (Lock &guard, Window *windowentity)
 Removes an closed window from the engine. More...
 
DLLEXPORT void ReportClosedWindow (Window *windowentity)
 
DLLEXPORT void SaveScreenShot ()
 
GraphicsGetGraphics ()
 
EventHandlerGetEventHandler ()
 
RenderingStatisticsGetRenderingStatistics ()
 
ScriptConsoleGetScriptConsole ()
 
FileSystemGetFileSystem ()
 
AppDefGetDefinition ()
 
NewtonManagerGetNewtonManager ()
 
LeviathanApplicationGetOwningApplication ()
 
PhysicsMaterialManagerGetPhysicalMaterialManager ()
 
NetworkHandlerGetNetworkHandler ()
 
ThreadingManagerGetThreadingManager ()
 
SoundDeviceGetSoundDevice ()
 
ResourceRefreshHandlerGetResourceRefreshHandler ()
 
EntitySerializerGetEntitySerializer ()
 
RemoteConsoleGetRemoteConsole ()
 
RandomGetRandom ()
 
DLLEXPORT WindowGetWindowFromSDLID (uint32_t sdlid)
 
bool GetNoGui ()
 
void SetNoGUI ()
 
- Public Member Functions inherited from Leviathan::ThreadSafeGeneric< MutexType >
DLLEXPORT ThreadSafeGeneric ()
 
DLLEXPORT ~ThreadSafeGeneric ()
 
FORCE_INLINE void VerifyLock (RecursiveLock &guard) const
 
FORCE_INLINE void VerifyLock (Lock &lockit) const
 

Static Public Member Functions

static DLLEXPORT EngineGetEngine ()
 
static DLLEXPORT EngineGet ()
 

Protected Member Functions

void PostLoad ()
 
DLLEXPORT void ExecuteCommandLine ()
 
void _NotifyThreadsRegisterOgre ()
 
void _AdjustTickClock (int amount, bool absolute=true)
 Sets the tick clock to a certain value. More...
 
void _AdjustTickNumber (int tickamount, bool absolute)
 Sets the tick number to a specified value. More...
 
DLLEXPORT void ProcessInvokes ()
 Handles InvokeQueue. More...
 
bool _ReceiveConsoleInput (const std::string &command)
 Console input comes through this. More...
 
void _RunQueuedConsoleCommands ()
 Runs all commands in QueuedConsoleCommands. More...
 
bool ParseSingleCommand (StringIterator &itr, int &argindex, const int argcount, char *args[])
 Helper for PassCommandLine. More...
 

Protected Attributes

AppDefDefine = nullptr
 
RenderingStatisticsRenderTimer = nullptr
 
GraphicsGraph = nullptr
 
WindowGraphicalEntity1 = nullptr
 
std::vector< Window * > AdditionalGraphicalEntities
 
SoundDeviceSound = nullptr
 
DataStoreMainstore = nullptr
 
EventHandlerMainEvents = nullptr
 
ScriptExecutorMainScript = nullptr
 
ScriptConsoleMainConsole = nullptr
 
FileSystemMainFileHandler = nullptr
 
RandomMainRandom = nullptr
 
OutOfMemoryHandlerOutOMemory = nullptr
 
NewtonManager_NewtonManager = nullptr
 
PhysicsMaterialManagerPhysMaterials = nullptr
 
NetworkHandler_NetworkHandler = nullptr
 
ThreadingManager_ThreadingManager = nullptr
 
RemoteConsole_RemoteConsole = nullptr
 
ResourceRefreshHandler_ResourceRefreshHandler = nullptr
 
std::unique_ptr< ConsoleInput_ConsoleInput
 
std::unique_ptr< EntitySerializer_EntitySerializer
 
IDFactoryIDDefaultInstance = nullptr
 
LeviathanApplicationOwner = nullptr
 
std::vector< std::shared_ptr< GameWorld > > GameWorlds
 List of current worlds. More...
 
std::mutex GameWorldsLock
 Mutex that is locked when changing the worlds. More...
 
std::mutex NetworkHandlerLock
 Mutex that is locked while NetworkHandler is used. More...
 
int64_t LastTickTime
 
int TimePassed = 0
 
int FrameLimit = 0
 
int TickCount = 0
 
int TickTime = 0
 
int FrameCount = 0
 
bool PreReleaseDone = false
 Set when PreRelease is called and Tick has happened. More...
 
bool PreReleaseWaiting = false
 
bool NoGui = false
 
bool NoLeap = false
 
bool NoSTDInput = false
 
bool IsClient = false
 Set to true when initialized as a client. More...
 
bool PreReleaseCompleted = false
 
RecursiveMutex InvokeLock
 
std::list< std::function< void()> > InvokeQueue
 
std::vector< std::unique_ptr< std::string > > PassedCommands
 
std::vector< std::unique_ptr< std::string > > QueuedConsoleCommands
 Stores console commands that came from the command line. More...
 
- Protected Attributes inherited from Leviathan::ThreadSafeGeneric< MutexType >
MutexType ObjectsLock
 

Static Protected Attributes

static DLLEXPORT Engineinstance = nullptr
 

Detailed Description

The main class of the Leviathan Game Engine.

Allocates a lot of classes and performs almost all startup operations.

Note
Should be thread safe, but might not actually be

Definition at line 24 of file Engine.h.

Constructor & Destructor Documentation

◆ Engine()

DLLEXPORT Engine::Engine ( LeviathanApplication owner)

Definition at line 59 of file Engine.cpp.

59  : Owner(owner)
60 {
61  // This makes sure that uninitialized engine will have at least some last frame time //
63 
64  instance = this;
65 }
static DLLEXPORT int64_t GetTimeMs64()
int64_t LastTickTime
Definition: Engine.h:312
static DLLEXPORT Engine * instance
Definition: Engine.h:351
LeviathanApplication * Owner
Definition: Engine.h:300

◆ ~Engine()

DLLEXPORT Engine::~Engine ( )

Definition at line 67 of file Engine.cpp.

68 {
69  // Reset the instance ptr //
70  instance = nullptr;
71 
72  _ConsoleInput.reset();
73 }
std::unique_ptr< ConsoleInput > _ConsoleInput
Definition: Engine.h:291
static DLLEXPORT Engine * instance
Definition: Engine.h:351

Member Function Documentation

◆ _AdjustTickClock()

void Engine::_AdjustTickClock ( int  amount,
bool  absolute = true 
)
protected

Sets the tick clock to a certain value.

Note
Should only be used to match the server's clock
Parameters
amountThe amount of time in milliseconds to set or change
absoluteWhen true sets the time until a tick to amount otherwise changes the remaining time by amount

Definition at line 1214 of file Engine.cpp.

1215 {
1216 
1217  GUARD_LOCK();
1218 
1219  if(!absolute) {
1220 
1221  Logger::Get()->Info("Engine: adjusted tick timer by " + Convert::ToString(amount));
1222 
1223  LastTickTime += amount;
1224  return;
1225  }
1226 
1227  // Calculate the time in the current last tick //
1228  int64_t templasttick = LastTickTime;
1229 
1230  int64_t curtime = Time::GetTimeMs64();
1231 
1232  while(curtime - templasttick >= TICKSPEED) {
1233 
1234  templasttick += TICKSPEED;
1235  }
1236 
1237  // Check how far off we are from the target //
1238  int64_t intolasttick = curtime - templasttick;
1239 
1240  int changeamount = amount - static_cast<int>(intolasttick);
1241 
1242  Logger::Get()->Info("Engine: changing tick counter by " + Convert::ToString(changeamount));
1243 
1244  LastTickTime += changeamount;
1245 }
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
static DLLEXPORT int64_t GetTimeMs64()
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
int64_t LastTickTime
Definition: Engine.h:312
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ _AdjustTickNumber()

void Engine::_AdjustTickNumber ( int  tickamount,
bool  absolute 
)
protected

Sets the tick number to a specified value.

Note
Should only be called on the client as this may break some simulations

Definition at line 1247 of file Engine.cpp.

1248 {
1249 
1250  GUARD_LOCK();
1251 
1252  if(!absolute) {
1253 
1254  TickCount += tickamount;
1255 
1256  Logger::Get()->Info("Engine: adjusted tick by " + Convert::ToString(tickamount) +
1257  ", tick is now " + Convert::ToString(TickCount));
1258 
1259  return;
1260  }
1261 
1262  TickCount = tickamount;
1263 
1264  Logger::Get()->Info("Engine: tick set to " + Convert::ToString(TickCount));
1265 }
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
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ _NotifyThreadsRegisterOgre()

void Engine::_NotifyThreadsRegisterOgre ( )
protected

Function called by first instance of Window class after creating a window to not error when registering threads to work with Ogre

Definition at line 1193 of file Engine.cpp.

1194 {
1195  if(NoGui)
1196  return;
1197 
1198  // Register threads to use graphical objects //
1200 }
DLLEXPORT void MakeThreadsWorkWithOgre()
Makes the threads work with Ogre.
ThreadingManager * _ThreadingManager
Definition: Engine.h:287

◆ _ReceiveConsoleInput()

bool Engine::_ReceiveConsoleInput ( const std::string &  command)
protected

Console input comes through this.

Definition at line 1528 of file Engine.cpp.

1529 {
1530 
1531  Invoke([=]() {
1532 
1533  if(MainConsole) {
1534 
1535  MainConsole->RunConsoleCommand(command);
1536 
1537  } else {
1538 
1539  LOG_WARNING("No console handler attached, cannot run command");
1540  }
1541  });
1542 
1543  // Listening thread quits if PreReleaseWaiting is true
1544  return PreReleaseWaiting;
1545 }
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1112
ScriptConsole * MainConsole
Definition: Engine.h:280
bool PreReleaseWaiting
Definition: Engine.h:325
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT int RunConsoleCommand(std::string cmd)
Definition: Console.cpp:52

◆ _RunQueuedConsoleCommands()

void Engine::_RunQueuedConsoleCommands ( )
protected

Runs all commands in QueuedConsoleCommands.

Definition at line 1503 of file Engine.cpp.

1504 {
1505 
1506  if(QueuedConsoleCommands.empty())
1507  return;
1508 
1509  if(!MainConsole) {
1510 
1511  LOG_FATAL("Engine: MainConsole has not been created before running command line "
1512  "passed commands");
1513  return;
1514  }
1515 
1516  LOG_INFO("Engine: Running PostStartup command line. Commands: " +
1518 
1519  for(auto& command : QueuedConsoleCommands) {
1520 
1521  LOG_INFO("Engine: Running \"" + *command + "\"");
1522  MainConsole->RunConsoleCommand(*command);
1523  }
1524 
1525  QueuedConsoleCommands.clear();
1526 }
#define LOG_INFO(x)
Definition: Define.h:81
#define LOG_FATAL(x)
Definition: Define.h:85
ScriptConsole * MainConsole
Definition: Engine.h:280
DLLEXPORT int RunConsoleCommand(std::string cmd)
Definition: Console.cpp:52
static std::string ToString(const T &val)
Definition: Convert.h:72
std::vector< std::unique_ptr< std::string > > QueuedConsoleCommands
Stores console commands that came from the command line.
Definition: Engine.h:349

◆ AssertIfNotMainThread()

DLLEXPORT void Leviathan::Engine::AssertIfNotMainThread ( ) const
inline

Asserts if not called on the main thread.

Definition at line 93 of file Engine.h.

94  {
95  LEVIATHAN_ASSERT(
96  IsOnMainThread(), "Function not called on main thread (AssertIfNotMainThread)");
97  }
DLLEXPORT bool IsOnMainThread() const
Returns true if called on the main thread.
Definition: Engine.cpp:87

◆ ClearTimers()

DLLEXPORT void Engine::ClearTimers ( )

Clears physical timers.

Definition at line 1185 of file Engine.cpp.

1186 {
1187  Lock lock(GameWorldsLock);
1188 
1189  for(auto iter = GameWorlds.begin(); iter != GameWorlds.end(); ++iter) {
1190  }
1191 }
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15

◆ CreateWorld()

DLLEXPORT std::shared_ptr< GameWorld > Engine::CreateWorld ( Window owningwindow,
int  worldtype 
)

Creates a GameWorld for placing entities into.

Note
To actually move the world camera you need to use Leviathan::ObjectLoader::LoadCamera to create a camera entity

Definition at line 1147 of file Engine.cpp.

1148 {
1149  auto tmp = GameWorldFactory::Get()->CreateNewWorld(worldtype);
1150 
1151  tmp->Init(_NetworkHandler->GetNetworkType(), NoGui ? nullptr : Graph->GetOgreRoot());
1152 
1153  if(owningwindow)
1154  owningwindow->LinkObjects(tmp);
1155 
1156  Lock lock(GameWorldsLock);
1157 
1158  GameWorlds.push_back(tmp);
1159  return GameWorlds.back();
1160 }
DLLEXPORT Ogre::Root * GetOgreRoot()
Definition: Graphics.h:30
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
virtual DLLEXPORT std::shared_ptr< GameWorld > CreateNewWorld(int worldtype)
Creates a new world that can be used.
static DLLEXPORT GameWorldFactory * Get()
DLLEXPORT void LinkObjects(std::shared_ptr< GameWorld > world)
This function also updates the camera aspect ratio.
Definition: Window.cpp:261
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
NETWORKED_TYPE GetNetworkType() const
Gets the type of network this program uses.
Graphics * Graph
Definition: Engine.h:271
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15

◆ DestroyWorld()

DLLEXPORT void Engine::DestroyWorld ( const std::shared_ptr< GameWorld > &  world)

Releases a GameWorld.

Parameters
worldThe world to destroy.
Postcondition
The World will have been released and removed from Engine's internal list and when all other holders of the pointer release it will be deleted

Definition at line 1162 of file Engine.cpp.

1163 {
1164 
1165  if(!world)
1166  return;
1167 
1168  // Release the world first //
1169  world->Release();
1170 
1171  // Then delete it //
1172  Lock lock(GameWorldsLock);
1173 
1174  auto end = GameWorlds.end();
1175  for(auto iter = GameWorlds.begin(); iter != end; ++iter) {
1176 
1177  if((*iter).get() == world.get()) {
1178 
1179  GameWorlds.erase(iter);
1180  return;
1181  }
1182  }
1183 }
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15

◆ ExecuteCommandLine()

DLLEXPORT void Engine::ExecuteCommandLine ( )
protected

Runs the normal commands passed by the PassCommandLine function // Ran automatically after Init

Definition at line 1415 of file Engine.cpp.

1416 {
1417 
1418  StringIterator itr;
1419 
1420  // Iterate over the commands and process them //
1421  for(size_t i = 0; i < PassedCommands.size(); i++) {
1422 
1423  itr.ReInit(PassedCommands[i].get());
1424  // Skip the preceding '-'s //
1425  itr.SkipCharacters('-');
1426 
1427  // Get the command //
1428  auto firstpart = itr.GetUntilNextCharacterOrAll<string>(':');
1429 
1430  // Execute the wanted command //
1431  if(StringOperations::CompareInsensitive<string>(*firstpart, "RemoteConsole")) {
1432 
1433  // Get the next command //
1434  auto commandpart = itr.GetUntilNextCharacterOrAll<string>(L':');
1435 
1436  if(*commandpart == "CloseIfNone") {
1437  // Set the command //
1439  Logger::Get()->Info("Engine will close when no active/waiting remote console "
1440  "sessions");
1441 
1442  } else if(*commandpart == "OpenTo") {
1443  // Get the to part //
1444  auto topart = itr.GetStringInQuotes<string>(QUOTETYPE_BOTH);
1445 
1446  int token = 0;
1447 
1448  auto numberpart = itr.GetNextNumber<string>(DECIMALSEPARATORTYPE_NONE);
1449 
1450  if(numberpart->size() == 0) {
1451 
1452  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1453  "no token number provided");
1454  continue;
1455  }
1456  // Convert to a real number. Maybe we could see if the token is
1457  // complex enough here, but that isn't necessary
1458  token = Convert::StringTo<int>(*numberpart);
1459 
1460  if(token == 0) {
1461  // Invalid number? //
1462  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1463  "couldn't parse token number, " +
1464  *numberpart);
1465  continue;
1466  }
1467 
1468  // Create a connection (or potentially use an existing one) //
1469  shared_ptr<Connection> tmpconnection =
1471 
1472  // Tell remote console to open a command to it //
1473  if(tmpconnection) {
1474 
1475  _RemoteConsole->OfferConnectionTo(tmpconnection, "AutoOpen", token);
1476 
1477  } else {
1478  // Something funky happened... //
1479  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1480  "couldn't open connection to " +
1481  *topart + ", couldn't resolve address");
1482  }
1483 
1484  } else {
1485  // Unknown command //
1486  Logger::Get()->Warning("Engine: ExecuteCommandLine: unknown RemoteConsole "
1487  "command: " +
1488  *commandpart +
1489  ", whole argument: " + *PassedCommands[i]);
1490  }
1491  }
1492  }
1493 
1494 
1495  PassedCommands.clear();
1496 
1497  // Now we can set some things that require command line arguments //
1498  // _RemoteConsole might be NULL //
1499  if(_RemoteConsole)
1501 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
DLLEXPORT void ReInit(std::unique_ptr< StringDataIterator > &&iterator)
Changes the current iterator to the new iterator and goes to the beginning.
std::unique_ptr< RStrType > GetStringInQuotes(QUOTETYPE quotes, int specialflags=0)
Gets the next string in quotes.
std::vector< std::unique_ptr< std::string > > PassedCommands
Definition: Engine.h:346
std::unique_ptr< RStrType > GetUntilNextCharacterOrAll(int charactertolookfor, int specialflags=0)
Gets characters until a character or all remaining characters.
DLLEXPORT void SetCloseIfNoRemoteConsole(bool state)
Sets the remote console to close the game if there are no connections.
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
Iterator class for getting parts of a string.
DLLEXPORT std::shared_ptr< Connection > OpenConnectionTo(const std::string &targetaddress)
Opens a new connection to the provided address.
void SkipCharacters(int chartoskip, int additionalflag=0, int specialflags=0)
Skips until chartoskip doesn&#39;t match the current character.
RemoteConsole * _RemoteConsole
Definition: Engine.h:288
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
std::unique_ptr< RStrType > GetNextNumber(DECIMALSEPARATORTYPE decimal, int specialflags=0)
Gets the next number.
DLLEXPORT void OfferConnectionTo(std::shared_ptr< Connection > connectiontouse, const std::string &connectionname, int token)
Does everything needed to allow the client on the connection to connect to us.
void SetAllowClose()
Called by Engine after command line has been processed.

◆ Get()

DLLEXPORT Engine * Engine::Get ( )
static

Definition at line 82 of file Engine.cpp.

83 {
84  return instance;
85 }
static DLLEXPORT Engine * instance
Definition: Engine.h:351

◆ GetCurrentTick()

DLLEXPORT int Engine::GetCurrentTick ( ) const

Returns the number of tick that was last simulated.

Definition at line 1208 of file Engine.cpp.

1209 {
1210 
1211  return TickCount;
1212 }

◆ GetDefinition()

AppDef* Leviathan::Engine::GetDefinition ( )
inline

Definition at line 160 of file Engine.h.

161  {
162  return Define;
163  }
AppDef * Define
Definition: Engine.h:268

◆ GetEngine()

Engine * Engine::GetEngine ( )
static

Definition at line 77 of file Engine.cpp.

78 {
79  return instance;
80 }
static DLLEXPORT Engine * instance
Definition: Engine.h:351

◆ GetEntitySerializer()

EntitySerializer* Leviathan::Engine::GetEntitySerializer ( )
inline

Definition at line 192 of file Engine.h.

193  {
194  return _EntitySerializer.get();
195  }
std::unique_ptr< EntitySerializer > _EntitySerializer
Definition: Engine.h:292

◆ GetEventHandler()

EventHandler* Leviathan::Engine::GetEventHandler ( )
inline

Definition at line 144 of file Engine.h.

145  {
146  return MainEvents;
147  }
EventHandler * MainEvents
Definition: Engine.h:278

◆ GetFileSystem()

FileSystem* Leviathan::Engine::GetFileSystem ( )
inline

Definition at line 156 of file Engine.h.

157  {
158  return MainFileHandler;
159  }
FileSystem * MainFileHandler
Definition: Engine.h:281

◆ GetGraphics()

Graphics* Leviathan::Engine::GetGraphics ( )
inline

Definition at line 140 of file Engine.h.

141  {
142  return Graph;
143  }
Graphics * Graph
Definition: Engine.h:271

◆ GetNetworkHandler()

NetworkHandler* Leviathan::Engine::GetNetworkHandler ( )
inline

Definition at line 176 of file Engine.h.

177  {
178  return _NetworkHandler;
179  }
NetworkHandler * _NetworkHandler
Definition: Engine.h:286

◆ GetNewtonManager()

NewtonManager* Leviathan::Engine::GetNewtonManager ( )
inline

Definition at line 164 of file Engine.h.

165  {
166  return _NewtonManager;
167  }
NewtonManager * _NewtonManager
Definition: Engine.h:284

◆ GetNoGui()

bool Leviathan::Engine::GetNoGui ( )
inline

Definition at line 214 of file Engine.h.

215  {
216  return NoGui;
217  }

◆ GetOwningApplication()

LeviathanApplication* Leviathan::Engine::GetOwningApplication ( )
inline

Definition at line 168 of file Engine.h.

169  {
170  return Owner;
171  }
LeviathanApplication * Owner
Definition: Engine.h:300

◆ GetPhysicalMaterialManager()

PhysicsMaterialManager* Leviathan::Engine::GetPhysicalMaterialManager ( )
inline

Definition at line 172 of file Engine.h.

173  {
174  return PhysMaterials;
175  }
PhysicsMaterialManager * PhysMaterials
Definition: Engine.h:285

◆ GetRandom()

Random* Leviathan::Engine::GetRandom ( )
inline

Definition at line 200 of file Engine.h.

201  {
202  return MainRandom;
203  }
Random * MainRandom
Definition: Engine.h:282

◆ GetRemoteConsole()

RemoteConsole* Leviathan::Engine::GetRemoteConsole ( )
inline

Definition at line 196 of file Engine.h.

197  {
198  return _RemoteConsole;
199  }
RemoteConsole * _RemoteConsole
Definition: Engine.h:288

◆ GetRenderingStatistics()

RenderingStatistics* Leviathan::Engine::GetRenderingStatistics ( )
inline

Definition at line 148 of file Engine.h.

149  {
150  return RenderTimer;
151  }
RenderingStatistics * RenderTimer
Definition: Engine.h:270

◆ GetResourceRefreshHandler()

ResourceRefreshHandler* Leviathan::Engine::GetResourceRefreshHandler ( )
inline

Definition at line 188 of file Engine.h.

189  {
191  }
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:289

◆ GetScriptConsole()

ScriptConsole* Leviathan::Engine::GetScriptConsole ( )
inline

Definition at line 152 of file Engine.h.

153  {
154  return MainConsole;
155  }
ScriptConsole * MainConsole
Definition: Engine.h:280

◆ GetSoundDevice()

SoundDevice* Leviathan::Engine::GetSoundDevice ( )
inline

Definition at line 184 of file Engine.h.

185  {
186  return Sound;
187  }
SoundDevice * Sound
Definition: Engine.h:276

◆ GetThreadingManager()

ThreadingManager* Leviathan::Engine::GetThreadingManager ( )
inline

Definition at line 180 of file Engine.h.

181  {
182  return _ThreadingManager;
183  }
ThreadingManager * _ThreadingManager
Definition: Engine.h:287

◆ GetTimeSinceLastTick()

DLLEXPORT int64_t Leviathan::Engine::GetTimeSinceLastTick ( ) const

Calculates how long has elapsed since the last tick.

Returns
The time in milliseconds

Definition at line 1202 of file Engine.cpp.

1203 {
1204 
1205  return Time::GetTimeMs64() - LastTickTime;
1206 }
static DLLEXPORT int64_t GetTimeMs64()
int64_t LastTickTime
Definition: Engine.h:312

◆ GetWindowEntity()

DLLEXPORT Window* Leviathan::Engine::GetWindowEntity ( )
inline

Returns the main window.

Definition at line 124 of file Engine.h.

125  {
126  return GraphicalEntity1;
127  };
Window * GraphicalEntity1
Definition: Engine.h:273

◆ GetWindowFromSDLID()

DLLEXPORT Window * Engine::GetWindowFromSDLID ( uint32_t  sdlid)

Definition at line 824 of file Engine.cpp.

825 {
826  if(GraphicalEntity1 && GraphicalEntity1->GetSDLID() == sdlid) {
827  return GraphicalEntity1;
828  }
829 
830  for(auto iter = AdditionalGraphicalEntities.begin();
831  iter != AdditionalGraphicalEntities.end(); ++iter) {
832  if((*iter)->GetSDLID() == sdlid) {
833 
834  return *iter;
835  }
836  }
837 
838  return nullptr;
839 }
Window * GraphicalEntity1
Definition: Engine.h:273
DLLEXPORT uint32_t GetSDLID() const
Passes initial mouse position to gui.
Definition: Window.cpp:581
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274

◆ GetWindowOpenCount()

DLLEXPORT int Engine::GetWindowOpenCount ( )

Definition at line 1030 of file Engine.cpp.

1031 {
1032  int openwindows = 0;
1033 
1034  // If we are in text only mode always return 1 //
1035  if(NoGui)
1036  return 1;
1037 
1038  GUARD_LOCK();
1039 
1040  // TODO: should there be an IsOpen method?
1041  if(GraphicalEntity1)
1042  openwindows++;
1043 
1044  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1045 
1047  openwindows++;
1048  }
1049 
1050  return openwindows;
1051 }
Window * GraphicalEntity1
Definition: Engine.h:273
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274

◆ HasPreReleaseBeenDone()

DLLEXPORT bool Leviathan::Engine::HasPreReleaseBeenDone ( ) const
inline

Checks if PreRelease is done and Release can be called.

Precondition
PreRelease is called

Definition at line 47 of file Engine.h.

48  {
49  return PreReleaseDone;
50  }
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:321

◆ Init()

DLLEXPORT bool Engine::Init ( AppDef definition,
NETWORKED_TYPE  ntype,
NetworkInterface packethandler 
)

Definition at line 92 of file Engine.cpp.

94 {
95  GUARD_LOCK();
96 
98 
99  // Get the time, for monitoring how long loading takes //
100  auto InitStartTime = Time::GetTimeMs64();
101 
102  // Store parameters //
103  Define = definition;
104 
105  IsClient = ntype == NETWORKED_TYPE::Client;
106 
107  // Create all the things //
108 
110 
112 
113  // Create threading facilities //
115  if(!_ThreadingManager->Init()) {
116 
117  Logger::Get()->Error("Engine: Init: cannot start threading");
118  return false;
119  }
120 
121  // Create the randomizer //
122  MainRandom = new Random((int)InitStartTime);
124 
125  // Console might be the first thing we want //
126  if(!NoSTDInput) {
127 
128  _ConsoleInput = std::make_unique<ConsoleInput>();
129 
130  if(!_ConsoleInput->Init(
131  std::bind(&Engine::_ReceiveConsoleInput, this, std::placeholders::_1),
132  NoGui ? true : false)) {
133  Logger::Get()->Error("Engine: Init: failed to read stdin, perhaps pass --nocin");
134  return false;
135  }
136  }
137 
138  if(NoGui) {
139 
140  // Tell window title //
141  Logger::Get()->Write(
142  "// ----------- " + Define->GetWindowDetails().Title + " ----------- //");
143  }
144 
145 
146  // We could immediately receive a remote console request so this should be
147  // ready when networking is started
149 
150  // We want to send a request to the master server as soon as possible //
151  {
152  Lock lock(NetworkHandlerLock);
153 
154  _NetworkHandler = new NetworkHandler(ntype, packethandler);
155 
157  }
158 
159  // These should be fine to be threaded //
160 
161  // File change listener //
163  if(!_ResourceRefreshHandler->Init()) {
164 
165  Logger::Get()->Error("Engine: Init: cannot start resource monitor");
166  return false;
167  }
168 
169  // Data storage //
170  Mainstore = new DataStore(true);
171  if(!Mainstore) {
172 
173  Logger::Get()->Error("Engine: Init: failed to create main data store");
174  return false;
175  }
176 
177  // Search data folder for files //
178  MainFileHandler = new FileSystem();
179  if(!MainFileHandler) {
180 
181  Logger::Get()->Error("Engine: Init: failed to create FileSystem");
182  return false;
183  }
184 
185  if(!MainFileHandler->Init(Logger::Get())) {
186 
187  Logger::Get()->Error("Engine: Init: failed to init FileSystem");
188  return false;
189  }
190 
191  // File parsing //
193 
194  // Main program wide event dispatcher //
195  MainEvents = new EventHandler();
196  if(!MainEvents) {
197 
198  Logger::Get()->Error("Engine: Init: failed to create MainEvents");
199  return false;
200  }
201 
202  if(!MainEvents->Init()) {
203 
204  Logger::Get()->Error("Engine: Init: failed to init MainEvents");
205  return false;
206  }
207 
208  // Check is threading properly started //
209  if(!_ThreadingManager->CheckInit()) {
210 
211  Logger::Get()->Error("Engine: Init: threading start failed");
212  return false;
213  }
214 
215  // create script interface before renderer //
216  std::promise<bool> ScriptInterfaceResult;
217 
218  // Ref is OK to use since this task finishes before this function //
219  _ThreadingManager->QueueTask(std::make_shared<QueuedTask>(std::bind<void>(
220  [](std::promise<bool>& returnvalue, Engine* engine) -> void {
221  try {
222  engine->MainScript = new ScriptExecutor();
223  } catch(const Exception&) {
224 
225  Logger::Get()->Error("Engine: Init: failed to create ScriptInterface");
226  returnvalue.set_value(false);
227  return;
228  }
229 
230  // create console after script engine //
231  engine->MainConsole = new ScriptConsole();
232  if(!engine->MainConsole) {
233 
234  Logger::Get()->Error("Engine: Init: failed to create ScriptConsole");
235  returnvalue.set_value(false);
236  return;
237  }
238 
239  if(!engine->MainConsole->Init(engine->MainScript)) {
240 
241  Logger::Get()->Error("Engine: Init: failed to initialize Console, "
242  "continuing anyway");
243  }
244 
245  returnvalue.set_value(true);
246  },
247  std::ref(ScriptInterfaceResult), this)));
248 
249  // create newton manager before any newton resources are needed //
250  std::promise<bool> NewtonManagerResult;
251 
252  // Ref is OK to use since this task finishes before this function //
253  _ThreadingManager->QueueTask(std::make_shared<QueuedTask>(std::bind<void>(
254  [](std::promise<bool>& returnvalue, Engine* engine) -> void {
255 
256  engine->_NewtonManager = new NewtonManager();
257  if(!engine->_NewtonManager) {
258 
259  Logger::Get()->Error("Engine: Init: failed to create NewtonManager");
260  returnvalue.set_value(false);
261  return;
262  }
263 
264  // next force application to load physical surface materials //
265  engine->PhysMaterials = new PhysicsMaterialManager(engine->_NewtonManager);
266  if(!engine->PhysMaterials) {
267 
268  Logger::Get()->Error("Engine: Init: failed to create PhysicsMaterialManager");
269  returnvalue.set_value(false);
270  return;
271  }
272 
274 
275  returnvalue.set_value(true);
276  },
277  std::ref(NewtonManagerResult), this)));
278 
279  // Create the default serializer //
280  _EntitySerializer = std::make_unique<EntitySerializer>();
281  if(!_EntitySerializer) {
282 
283  Logger::Get()->Error("Engine: Init: failed to instantiate entity serializer");
284  return false;
285  }
286 
287  // Check if we don't want a window //
288  if(NoGui) {
289 
290  Logger::Get()->Info("Engine: Init: starting in console mode "
291  "(won't allocate graphical objects) ");
292 
293  if(!_ConsoleInput->IsAttachedToConsole()) {
294 
295  Logger::Get()->Error(
296  "Engine: Init: in nogui mode and no input terminal connected, "
297  "quitting");
298  return false;
299  }
300 
301  } else {
302 
303  ObjectFileProcessor::LoadValueFromNamedVars<int>(
304  Define->GetValues(), "MaxFPS", FrameLimit, 120, Logger::Get(), "Graphics: Init:");
305 
306  Graph = new Graphics();
307  }
308 
309  // We need to wait for all current tasks to finish //
311 
312  // Check return values //
313  if(!ScriptInterfaceResult.get_future().get() || !NewtonManagerResult.get_future().get()) {
314 
315  Logger::Get()->Error("Engine: Init: one or more queued tasks failed");
316  return false;
317  }
318 
319  // We can queue some more tasks //
320  // create leap controller //
321 #ifdef LEVIATHAN_USES_LEAP
322 
323  // Disable leap if in non-gui mode //
324  if(NoGui)
325  NoLeap = true;
326 
327  std::thread leapinitthread;
328  if(!NoLeap) {
329 
330  Logger::Get()->Info("Engine: will try to create Leap motion connection");
331 
332  // Seems that std::threads are joinable when constructed with default constructor
333  leapinitthread = std::thread(std::bind<void>(
334  [](Engine* engine) -> void {
335 
336  engine->LeapData = new LeapManager(engine);
337  if(!engine->LeapData) {
338  Logger::Get()->Error("Engine: Init: failed to create LeapManager");
339  return;
340  }
341  // try here just in case //
342  try {
343  if(!engine->LeapData->Init()) {
344 
345  Logger::Get()->Info(
346  "Engine: Init: No Leap controller found, not using one");
347  }
348  } catch(...) {
349  // threw something //
350  Logger::Get()->Error(
351  "Engine: Init: Leap threw something, even without leap "
352  "this shouldn't happen; continuing anyway");
353  }
354 
355  },
356  this));
357  }
358 #endif
359 
360 
361  // sound device //
362  std::promise<bool> SoundDeviceResult;
363  // Ref is OK to use since this task finishes before this function //
364  _ThreadingManager->QueueTask(std::make_shared<QueuedTask>(std::bind<void>(
365  [](std::promise<bool>& returnvalue, Engine* engine) -> void {
366 
367  if(!engine->NoGui) {
368  engine->Sound = new SoundDevice();
369 
370  if(!engine->Sound) {
371  Logger::Get()->Error("Engine: Init: failed to create Sound");
372  returnvalue.set_value(false);
373  return;
374  }
375 
376  if(!engine->Sound->Init()) {
377 
378  Logger::Get()->Error(
379  "Engine: Init: failed to init SoundDevice. Continuing anyway");
380  }
381  }
382 
383  if(!engine->NoGui) {
384  // measuring //
385  engine->RenderTimer = new RenderingStatistics();
386  if(!engine->RenderTimer) {
387  Logger::Get()->Error("Engine: Init: failed to create RenderingStatistics");
388 
389  returnvalue.set_value(false);
390  return;
391  }
392  }
393 
394  returnvalue.set_value(true);
395  },
396  std::ref(SoundDeviceResult), this)));
397 
398  if(!NoGui) {
399  if(!Graph) {
400 
401  Logger::Get()->Error("Engine: Init: failed to create instance of Graphics");
402  return false;
403  }
404 
405  // call init //
406  if(!Graph->Init(definition)) {
407  Logger::Get()->Error("Failed to init Engine, Init graphics failed! Aborting");
408  return false;
409  }
410 
411  // create window //
412  GraphicalEntity1 = new Window(Graph, definition);
413  }
414 
415  if(!SoundDeviceResult.get_future().get()) {
416 
417  Logger::Get()->Error("Engine: Init: sound device queued tasks failed");
418  return false;
419  }
420 
421 #ifdef LEVIATHAN_USES_LEAP
422  // We can probably assume here that leap creation has stalled if the thread is running //
423  if(!NoLeap) {
424 
425  auto start = WantedClockType::now();
426 
427  while(leapinitthread.joinable()) {
428 
429  auto elapsed = WantedClockType::now() - start;
430 
431  if(elapsed > std::chrono::milliseconds(150)) {
432 
433  Logger::Get()->Warning("LeapController creation would have stalled the game!");
434  Logger::Get()->Write("TODO: allow increasing wait period");
435  leapinitthread.detach();
436  break;
437  }
438 
439  std::this_thread::sleep_for(std::chrono::milliseconds(5));
440  }
441  }
442 #endif
443 
444  PostLoad();
445 
446  Logger::Get()->Info(
447  "Engine init took " + Convert::ToString(Time::GetTimeMs64() - InitStartTime) + " ms");
448 
449  return true;
450 }
ScriptExecutor * MainScript
Definition: Engine.h:279
virtual DLLEXPORT bool Init()
Sets up the work queue.
DLLEXPORT bool Init(AppDef *appdef)
Definition: Graphics.cpp:72
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT bool Init(bool simulatesound=false, bool noconsolelog=false)
Definition: SoundDevice.cpp:23
RenderingStatistics * RenderTimer
Definition: Engine.h:270
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
DLLEXPORT void QueueTask(std::shared_ptr< QueuedTask > task)
Adds a task to the queue.
AppDef * Define
Definition: Engine.h:268
Random number generator based on Mersenne Twister.
Definition: Random.h:15
DataStore * Mainstore
Definition: Engine.h:277
Allows object to register for events that can be fired from anywhere.
Definition: EventHandler.h:12
constexpr auto THREAD_MAGIC
Definition: Engine.cpp:57
DLLEXPORT MasterServerInformation & GetMasterServerInfo()
Definition: AppDefine.h:97
IDFactory * IDDefaultInstance
Definition: Engine.h:299
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
ScriptConsole * MainConsole
Definition: Engine.h:280
Class for indexing and searching game data directory.
Definition: FileSystem.h:66
OutOfMemoryHandler * OutOMemory
Definition: Engine.h:283
Handles ScriptModule creation and AngelScript code execution.
DLLEXPORT void WaitForAllTasksToFinish()
Blocks until all queued tasks are finished.
bool _ReceiveConsoleInput(const std::string &command)
Console input comes through this.
Definition: Engine.cpp:1528
Window * GraphicalEntity1
Definition: Engine.h:273
DLLEXPORT bool Init(AppDef *definition, NETWORKED_TYPE ntype, NetworkInterface *packethandler)
Definition: Engine.cpp:92
std::unique_ptr< ConsoleInput > _ConsoleInput
Definition: Engine.h:291
DLLEXPORT WindowDataDetails & GetWindowDetails()
Definition: AppDefine.h:93
The main class of the Leviathan Game Engine.
Definition: Engine.h:24
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
virtual DLLEXPORT void RegisterApplicationPhysicalMaterials(PhysicsMaterialManager *manager)
static thread_local int MainThreadMagic
Used to detect when accessed from main thread.
Definition: Engine.cpp:56
static DLLEXPORT int64_t GetTimeMs64()
DLLEXPORT bool Init()
DLLEXPORT bool Init(ScriptExecutor *MainScript)
Definition: Console.cpp:32
DLLEXPORT void SetAsMain()
Definition: Random.cpp:131
PhysicsMaterialManager * PhysMaterials
Definition: Engine.h:285
DLLEXPORT NamedVars * GetValues()
Definition: AppDefine.cpp:40
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
Manages delayed execution of functions through use of QueuedTask and subclasses.
Allows various resource loaders to get notified when the file on disk changes.
ThreadingManager * _ThreadingManager
Definition: Engine.h:287
DLLEXPORT bool Init(LErrorReporter *errorreport)
Runs the indexing and sorting.
Definition: FileSystem.cpp:96
RemoteConsole * _RemoteConsole
Definition: Engine.h:288
static DLLEXPORT void Initialize()
SoundDevice * Sound
Definition: Engine.h:276
static std::string ToString(const T &val)
Definition: Convert.h:72
virtual DLLEXPORT bool CheckInit()
Checks has Init worked.
std::mutex NetworkHandlerLock
Mutex that is locked while NetworkHandler is used.
Definition: Engine.h:309
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:289
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
FileSystem * MainFileHandler
Definition: Engine.h:281
NewtonManager * _NewtonManager
Definition: Engine.h:284
Random * MainRandom
Definition: Engine.h:282
std::unique_ptr< EntitySerializer > _EntitySerializer
Definition: Engine.h:292
Class used to handle remote server commands and receiving messages.
Definition: RemoteConsole.h:45
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
Graphics * Graph
Definition: Engine.h:271
Handles everything related to connections.
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15
bool IsClient
Set to true when initialized as a client.
Definition: Engine.h:335
virtual DLLEXPORT bool Init(const MasterServerInformation &info)
EventHandler * MainEvents
Definition: Engine.h:278
LeviathanApplication * Owner
Definition: Engine.h:300

◆ Invoke()

DLLEXPORT void Engine::Invoke ( const std::function< void()> &  function)

Runs function on the main thread before the next tick.

This is provided to be able to

Note
This maybe called after preshutdown has started before final tick. This means that some objects may no longer be valid so check the result of any Get functions called in the invoke

Definition at line 1112 of file Engine.cpp.

1113 {
1114 
1115  RecursiveLock lock(InvokeLock);
1116  InvokeQueue.push_back(function);
1117 }
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:16
std::list< std::function< void()> > InvokeQueue
Definition: Engine.h:343
RecursiveMutex InvokeLock
Definition: Engine.h:342

◆ IsOnMainThread()

DLLEXPORT bool Engine::IsOnMainThread ( ) const

Returns true if called on the main thread.

Definition at line 87 of file Engine.cpp.

88 {
89  return MainThreadMagic == THREAD_MAGIC;
90 }
constexpr auto THREAD_MAGIC
Definition: Engine.cpp:57
static thread_local int MainThreadMagic
Used to detect when accessed from main thread.
Definition: Engine.cpp:56

◆ MarkQuit()

DLLEXPORT void Engine::MarkQuit ( )

Marks the owning application to quit.

Definition at line 1105 of file Engine.cpp.

1106 {
1107 
1108  if(Owner)
1109  Owner->MarkAsClosing();
1110 }
DLLEXPORT void MarkAsClosing()
Thread safely marks the game to close sometime.
LeviathanApplication * Owner
Definition: Engine.h:300

◆ MessagePump()

DLLEXPORT void Engine::MessagePump ( )

Processes queued messages from Ogre, SDL and input.

Definition at line 642 of file Engine.cpp.

643 {
644 
645  Ogre::WindowEventUtilities::messagePump();
646 
647  // CEF events (Also on windows as multi_threaded_message_loop makes rendering harder)
649 
650  SDL_Event event;
651  while(SDL_PollEvent(&event)) {
652 
653  switch(event.type) {
654  case SDL_QUIT:
655  LOG_INFO("SDL_QUIT received, marked as closing");
656  MarkQuit();
657  break;
658 
659  case SDL_KEYDOWN: {
660  Window* win = GetWindowFromSDLID(event.key.windowID);
661 
662  if(win) {
663 
664  // LOG_WRITE("SDL_KEYDOWN: " + Convert::ToString(event.key.keysym.sym));
665  win->InjectKeyDown(event);
666  }
667 
668  break;
669  }
670  case SDL_KEYUP: {
671  Window* win = GetWindowFromSDLID(event.key.windowID);
672 
673  if(win) {
674 
675  // LOG_WRITE("SDL_KEYUP: " + Convert::ToString(event.key.keysym.sym));
676  win->InjectKeyUp(event);
677  }
678 
679  break;
680  }
681  case SDL_TEXTINPUT: {
682  Window* win = GetWindowFromSDLID(event.text.windowID);
683 
684  if(win) {
685 
686  const auto text = std::string(event.text.text);
687 
688  // LOG_WRITE("TextInput: " + text);
689 
690  std::vector<uint32_t> codepoints;
691 
693  std::begin(text), std::end(text), std::back_inserter(codepoints));
694 
695  // LOG_WRITE("Codepoints(" + Convert::ToString(codepoints.size()) + "): ");
696  // for(auto codepoint : codepoints)
697  // LOG_WRITE(" " + Convert::ToString(codepoint));
698  for(auto codepoint : codepoints) {
699 
700  win->InjectCodePoint(event);
701  }
702  }
703 
704  break;
705  }
706  // TODO: implement this
707  // case SDL_TEXTEDITING: (https://wiki.libsdl.org/Tutorials/TextInput)
708  case SDL_MOUSEBUTTONDOWN: {
709  Window* win = GetWindowFromSDLID(event.button.windowID);
710 
711  if(win)
712  win->InjectMouseButtonDown(event);
713 
714  break;
715  }
716 
717  case SDL_MOUSEBUTTONUP: {
718  Window* win = GetWindowFromSDLID(event.button.windowID);
719 
720  if(win)
721  win->InjectMouseButtonUp(event);
722 
723  break;
724  }
725 
726  case SDL_MOUSEMOTION: {
727  Window* win = GetWindowFromSDLID(event.motion.windowID);
728 
729  if(win)
730  win->InjectMouseMove(event);
731 
732  break;
733  }
734 
735  case SDL_MOUSEWHEEL: {
736  Window* win = GetWindowFromSDLID(event.motion.windowID);
737 
738  if(win)
739  win->InjectMouseWheel(event);
740 
741  break;
742  }
743 
744  case SDL_WINDOWEVENT: {
745  switch(event.window.event) {
746 
747  case SDL_WINDOWEVENT_RESIZED: {
748  Window* win = GetWindowFromSDLID(event.window.windowID);
749 
750  if(win) {
751 
752  int32_t width, height;
753  win->GetSize(width, height);
754 
755  LOG_INFO("SDL window resize: " + Convert::ToString(width) + "x" +
756  Convert::ToString(height));
757 
758  win->OnResize(width, height);
759  }
760 
761  break;
762  }
763  case SDL_WINDOWEVENT_CLOSE: {
764  LOG_INFO("SDL window close");
765 
766  Window* win = GetWindowFromSDLID(event.window.windowID);
767 
768  GUARD_LOCK();
769 
770  // Detect closed windows //
771  if(win == GraphicalEntity1) {
772  // Window closed //
774  }
775 
776  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
777  if(AdditionalGraphicalEntities[i] == win) {
778 
780  break;
781  }
782  }
783 
784  break;
785  }
786  case SDL_WINDOWEVENT_FOCUS_GAINED: {
787  Window* win = GetWindowFromSDLID(event.window.windowID);
788 
789  if(win)
790  win->OnFocusChange(true);
791 
792  break;
793  }
794  case SDL_WINDOWEVENT_FOCUS_LOST: {
795  Window* win = GetWindowFromSDLID(event.window.windowID);
796 
797  if(win)
798  win->OnFocusChange(false);
799 
800  break;
801  }
802  }
803  }
804  }
805  }
806 
807  // CEF needs to be let handle the keyboard events now to make sure that they can be
808  // dispatched to further on listeners
810 
811  // Reset input states //
812  if(GraphicalEntity1) {
813 
814  // TODO: fix initial mouse position being incorrect
816  }
817 
818  for(auto iter = AdditionalGraphicalEntities.begin();
819  iter != AdditionalGraphicalEntities.end(); ++iter) {
820  (*iter)->InputEnd();
821  }
822 }
DLLEXPORT void MarkQuit()
Marks the owning application to quit.
Definition: Engine.cpp:1105
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:571
u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, u32bit_iterator result)
Definition: checked.h:258
#define LOG_INFO(x)
Definition: Define.h:81
DLLEXPORT void OnFocusChange(bool focused)
Definition: Window.cpp:326
DLLEXPORT void InjectMouseButtonUp(const SDL_Event &event)
Definition: Window.cpp:985
DLLEXPORT void ReportClosedWindow(Lock &guard, Window *windowentity)
Removes an closed window from the engine.
Definition: Engine.cpp:1080
DLLEXPORT void OnResize(int width, int height)
Definition: Window.cpp:313
DLLEXPORT void InjectKeyDown(const SDL_Event &event)
Definition: Window.cpp:1026
Window * GraphicalEntity1
Definition: Engine.h:273
DLLEXPORT void InjectMouseMove(const SDL_Event &event)
Definition: Window.cpp:904
DLLEXPORT void InputEnd()
Translates a client space coordinate to screen coordinate.
Definition: Window.cpp:733
DLLEXPORT void InjectKeyUp(const SDL_Event &event)
Definition: Window.cpp:1058
DLLEXPORT Window * GetWindowFromSDLID(uint32_t sdlid)
Definition: Engine.cpp:824
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT void InjectMouseButtonDown(const SDL_Event &event)
Definition: Window.cpp:960
DLLEXPORT void InjectCodePoint(const SDL_Event &event)
Injects text.
Definition: Window.cpp:1010
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
DLLEXPORT void InjectMouseWheel(const SDL_Event &event)
Definition: Window.cpp:930
static DLLEXPORT void DoCEFMessageLoopWork()
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274

◆ OpenNewWindow()

DLLEXPORT Window * Engine::OpenNewWindow ( )

Opens a new window.

Note
The window may become broken if the main window is closed
Todo:
Allow changing the parameters

Definition at line 1053 of file Engine.cpp.

1054 {
1055 
1056  AppDef winparams;
1057 
1058  winparams.SetWindowDetails(WindowDataDetails("My Second window", 1280, 720, "no",
1060  // Opens on same display as the other window
1061  // TODO: open on next display
1063  // no gamma
1064  false,
1065 #ifdef _WIN32
1066  NULL,
1067 #endif
1068  NULL));
1069 
1070 
1071  auto newwindow = std::make_unique<Window>(Graph, &winparams);
1072 
1073  GUARD_LOCK();
1074 
1075  AdditionalGraphicalEntities.push_back(newwindow.get());
1076 
1077  return newwindow.release();
1078 }
AppDef * Define
Definition: Engine.h:268
DLLEXPORT WindowDataDetails & GetWindowDetails()
Definition: AppDefine.h:93
DLLEXPORT AppDef & SetWindowDetails(const WindowDataDetails &det)
Definition: AppDefine.h:75
Graphics * Graph
Definition: Engine.h:271
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274

◆ ParseSingleCommand()

bool Engine::ParseSingleCommand ( StringIterator itr,
int &  argindex,
const int  argcount,
char *  args[] 
)
protected

Helper for PassCommandLine.

Definition at line 1277 of file Engine.cpp.

1279 {
1280 
1281  // Split all flags and check for some flags that might be set //
1282  unique_ptr<string> splitval;
1283 
1284  while((splitval = itr.GetNextCharacterSequence<string>(
1287  if(*splitval == "--nogui") {
1288  NoGui = true;
1289  Logger::Get()->Info("Engine starting in non-GUI mode");
1290  continue;
1291  }
1292  if(*splitval == "--noleap") {
1293  NoLeap = true;
1294 
1295 #ifdef LEVIATHAN_USES_LEAP
1296  Logger::Get()->Info("Engine starting with LeapMotion disabled");
1297 #endif
1298  continue;
1299  }
1300  if(*splitval == "--nocin") {
1301 
1302  NoSTDInput = true;
1303  Logger::Get()->Info("Engine not listening for terminal commands");
1304  continue;
1305  }
1306  if(*splitval == "--nonothing") {
1307  // Shouldn't try to open the console on windows //
1308  DEBUG_BREAK;
1309  }
1310  if(*splitval == "--crash") {
1311 
1312  Logger::Get()->Info("Engine testing crash handling");
1313  // TODO: write a file that disables crash handling
1314  // Make the log say something useful //
1315  Logger::Get()->Save();
1316 
1317  // Test crashing //
1318  TestCrash(12);
1319 
1320  continue;
1321  }
1322  if(*splitval == "--cmd" || *splitval == "cmd") {
1323 
1324  if(itr.GetCharacter() == '=')
1325  itr.MoveToNext();
1326 
1328 
1329 
1330 
1331  if(!cmd || cmd->empty()) {
1332 
1333  if(argindex + 1 < argcount) {
1334 
1335  // Next argument is the command //
1336  ++argindex;
1337  cmd = std::make_unique<std::string>(args[argindex]);
1338 
1339  } else {
1340 
1341  LOG_ERROR("Engine: command line parsing failed, no command "
1342  "after '--cmd'");
1343  continue;
1344  }
1345  }
1346 
1347  if(StringOperations::IsCharacterQuote(cmd->at(0))) {
1348 
1349  StringIterator itr2(cmd.get());
1350 
1351  auto withoutquotes = itr2.GetStringInQuotes<std::string>(QUOTETYPE_BOTH);
1352 
1353  if(withoutquotes) {
1354 
1355  QueuedConsoleCommands.push_back(std::move(withoutquotes));
1356 
1357  } else {
1358 
1359  LOG_WARNING("Engine: command line '--cmd' command in quotes is empty");
1360  }
1361 
1362  } else {
1363 
1364  // cmd is the final command
1365  QueuedConsoleCommands.push_back(std::move(cmd));
1366  }
1367 
1368  continue;
1369  }
1370 
1371  // Add (if not processed already) //
1372  PassedCommands.push_back(std::move(splitval));
1373  }
1374 
1375  return true;
1376 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
#define LOG_ERROR(x)
Definition: Define.h:83
bool MoveToNext()
Skips the current character and moves to the next.
std::unique_ptr< RStrType > GetStringInQuotes(QUOTETYPE quotes, int specialflags=0)
Gets the next string in quotes.
std::vector< std::unique_ptr< std::string > > PassedCommands
Definition: Engine.h:346
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT void Save()
Definition: Logger.cpp:203
static bool IsCharacterQuote(CharType character)
int GetCharacter(size_t forward=0)
Gets the character in the position current + forward.
Iterator class for getting parts of a string.
std::vector< std::unique_ptr< std::string > > QueuedConsoleCommands
Stores console commands that came from the command line.
Definition: Engine.h:349
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
int TestCrash(int writenum)
Definition: Engine.cpp:1267
std::unique_ptr< RStrType > GetNextCharacterSequence(int stopcaseflags, int specialflags=0)
Gets the next sequence of characters according to stopcaseflags.

◆ PassCommandLine()

DLLEXPORT bool Engine::PassCommandLine ( int  argcount,
char *  args[] 
)

Passes the commands and preprocesses them

Also interprets commands like –nogui

Returns
False if invalid command line and the game should quit instantly

Definition at line 1378 of file Engine.cpp.

1379 {
1380  if(argcount < 1)
1381  return true;
1382 
1383  LOG_INFO("Engine: Command line: " + (args[0] ? std::string(args[0]) : std::string()));
1384 
1385  for(int i = 1; i < argcount; ++i) {
1386 
1387  LOG_WRITE("\t> " + (args[i] ? std::string(args[i]) : std::string()));
1388  }
1389 
1390  int argindex = 0;
1391 
1392  while(argindex < argcount) {
1393 
1394  if(!args[argindex]) {
1395  ++argindex;
1396  continue;
1397  }
1398 
1399  StringIterator itr(args[argindex]);
1400 
1401  while(!itr.IsOutOfBounds()) {
1402 
1403  if(!ParseSingleCommand(itr, argindex, argcount, args)) {
1404 
1405  return false;
1406  }
1407  }
1408 
1409  ++argindex;
1410  }
1411 
1412  return true;
1413 }
#define LOG_INFO(x)
Definition: Define.h:81
Iterator class for getting parts of a string.
#define LOG_WRITE(x)
Definition: Define.h:84
bool ParseSingleCommand(StringIterator &itr, int &argindex, const int argcount, char *args[])
Helper for PassCommandLine.
Definition: Engine.cpp:1277

◆ PostLoad()

void Engine::PostLoad ( )
protected

Definition at line 452 of file Engine.cpp.

453 {
454  // increase start count //
455  int startcounts = 0;
456 
457  if(Mainstore->GetValueAndConvertTo<int>("StartCount", startcounts)) {
458  // increase //
459  Mainstore->SetValue("StartCount", new VariableBlock(new IntBlock(startcounts + 1)));
460  } else {
461 
462  Mainstore->AddVar(
463  std::make_shared<NamedVariableList>("StartCount", new VariableBlock(1)));
464 
465  // set as persistent //
466  Mainstore->SetPersistance("StartCount", true);
467  }
468 
469  // Check if we are attached to a terminal //
470 
471  ClearTimers();
472 
473  // get time //
475 
477 
478  // Run startup command line //
480 }
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1185
Non-template class for working with all types of DataBlocks.
Definition: DataBlock.h:425
DataStore * Mainstore
Definition: Engine.h:277
void _RunQueuedConsoleCommands()
Runs all commands in QueuedConsoleCommands.
Definition: Engine.cpp:1503
DLLEXPORT bool GetValueAndConvertTo(const std::string &name, T &receiver) const
Definition: DataStore.h:80
static DLLEXPORT int64_t GetTimeMs64()
DLLEXPORT bool SetValue(const std::string &name, const VariableBlock &value1)
Definition: DataStore.cpp:153
DataBlock< int > IntBlock
Definition: DataBlock.h:382
DLLEXPORT void SetPersistance(unsigned int index, bool toset)
Definition: DataStore.cpp:128
int64_t LastTickTime
Definition: Engine.h:312
DLLEXPORT void ExecuteCommandLine()
Definition: Engine.cpp:1415
DLLEXPORT void AddVar(std::shared_ptr< NamedVariableList > values)
Definition: DataStore.cpp:194

◆ PreFirstTick()

DLLEXPORT void Engine::PreFirstTick ( )

Definition at line 945 of file Engine.cpp.

946 {
947 
948  GUARD_LOCK();
949 
952 
953  ClearTimers();
954 
955  Logger::Get()->Info("Engine: PreFirstTick: everything fine to start running");
956 }
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1185
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
DLLEXPORT void NotifyQueuerThread()
Notifies the queuer thread to check task setting.
ThreadingManager * _ThreadingManager
Definition: Engine.h:287
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ PreRelease()

DLLEXPORT void Engine::PreRelease ( )

Sets objects ready to be released.

Note
The Tick function must be called after this but before Release

Definition at line 482 of file Engine.cpp.

483 {
484  GUARD_LOCK();
486  return;
487 
488  PreReleaseWaiting = true;
489  // This will stay true until the end of times //
490  PreReleaseCompleted = true;
491 
492  // Stop command handling first //
493  if(_ConsoleInput) {
494 
495  _ConsoleInput->Release(false);
496  Logger::Get()->Info("Successfully stopped command handling");
497  }
498 
499  // Automatically destroy input sources //
501 
502  // Then kill the network //
503  {
504  Lock lock(NetworkHandlerLock);
505 
507  }
508 
509  // Let the game release it's resources //
511 
512  // Close remote console //
514 
515  // Close all connections //
516  {
517  Lock lock(NetworkHandlerLock);
518 
520  }
521 
523 
524  // Set worlds to empty //
525  {
526  Lock lock(GameWorldsLock);
527 
528  for(auto iter = GameWorlds.begin(); iter != GameWorlds.end(); ++iter) {
529  // Set all objects to release //
530  (*iter)->MarkForClear();
531  }
532  }
533 
534  // Set tasks to a proper state //
537 
538  Logger::Get()->Info("Engine: prerelease done, waiting for a tick");
539 }
DLLEXPORT void SetDiscardConditionalTasks(bool discard)
Sets the task queuer to discard all conditional tasks.
virtual DLLEXPORT void EnginePreShutdown()
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
NetworkInterface * GetInterface()
Returns interface object. Type depends on AppType.
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
std::unique_ptr< ConsoleInput > _ConsoleInput
Definition: Engine.h:291
bool PreReleaseWaiting
Definition: Engine.h:325
virtual DLLEXPORT void CloseDown()=0
Called when the program is closing.
ThreadingManager * _ThreadingManager
Definition: Engine.h:287
#define SAFE_RELEASEDEL(x)
Definition: Define.h:115
RemoteConsole * _RemoteConsole
Definition: Engine.h:288
std::mutex NetworkHandlerLock
Mutex that is locked while NetworkHandler is used.
Definition: Engine.h:309
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:289
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void SetDisallowRepeatingTasks(bool disallow)
Disallows repeating tasks to occur again.
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
bool PreReleaseCompleted
Definition: Engine.h:338
#define SAFE_DELETE(x)
Definition: Define.h:116
DLLEXPORT void ReleaseInputHandler()
Destroys the networked input handler and all input objects.
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15
LeviathanApplication * Owner
Definition: Engine.h:300

◆ ProcessInvokes()

DLLEXPORT void Engine::ProcessInvokes ( )
protected

Handles InvokeQueue.

Definition at line 1119 of file Engine.cpp.

1120 {
1121 
1122  RecursiveLock lock(InvokeLock);
1123 
1124  while(!InvokeQueue.empty()) {
1125 
1126  const auto& func = InvokeQueue.front();
1127 
1128  // Recursive mutex allows the invoke to call extra invokes
1129  func();
1130 
1131  InvokeQueue.pop_front();
1132  }
1133 }
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:16
std::list< std::function< void()> > InvokeQueue
Definition: Engine.h:343
RecursiveMutex InvokeLock
Definition: Engine.h:342

◆ Release()

void Engine::Release ( bool  forced = false)
Todo:
Add a thread that monitors if the thing gets stuck on a task

Definition at line 541 of file Engine.cpp.

542 {
543  GUARD_LOCK();
544 
545  if(!forced)
546  LEVIATHAN_ASSERT(PreReleaseDone, "PreReleaseDone must be done before actual release!");
547 
548  // Force garbase collection //
549  if(MainScript)
551 
552  // Make windows clear their stored objects //
553  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
554 
555  AdditionalGraphicalEntities[i]->UnlinkAll();
556  }
557 
558  // Finally the main window //
559  if(GraphicalEntity1) {
560 
562  }
563 
564  // Destroy worlds //
565  {
566  Lock lock(GameWorldsLock);
567 
568  while(GameWorlds.size()) {
569 
570  GameWorlds[0]->Release();
571  GameWorlds.erase(GameWorlds.begin());
572  }
573  }
574 
575  if(_NetworkHandler)
577 
578  // Wait for tasks to finish //
579  if(!forced)
581 
582  // Destroy windows //
583  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
584 
586  }
587 
589 
591 
592  // Release newton //
595 
596 #ifdef LEVIATHAN_USES_LEAP
597  SAFE_RELEASEDEL(LeapData);
598 #endif
599 
600  // Console needs to be released before script release //
602 
604 
605  // Save at this point (just in case it crashes before exiting) //
606  Logger::Get()->Save();
607 
608 
610 
611  _EntitySerializer.reset();
612 
615 
616  // If graphics aren't unregistered crashing will occur //
618 
619  // Stop threads //
621 
623 
625  // delete randomizer last, for obvious reasons //
627 
630 
631  // clears all running timers that might have accidentally been left running //
633 
634  // safe to delete this here //
636 
638 
639  Logger::Get()->Write("Goodbye cruel world!");
640 }
ScriptExecutor * MainScript
Definition: Engine.h:279
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT void ShutdownCache()
Destroys the network cache permanently.
RenderingStatistics * RenderTimer
Definition: Engine.h:270
DataStore * Mainstore
Definition: Engine.h:277
IDFactory * IDDefaultInstance
Definition: Engine.h:299
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
ScriptConsole * MainConsole
Definition: Engine.h:280
OutOfMemoryHandler * OutOMemory
Definition: Engine.h:283
DLLEXPORT void WaitForAllTasksToFinish()
Blocks until all queued tasks are finished.
DLLEXPORT void CollectGarbage()
Does a full garbage collection cycle.
static DLLEXPORT void ClearTimers()
Window * GraphicalEntity1
Definition: Engine.h:273
DLLEXPORT void Save()
Definition: Logger.cpp:203
PhysicsMaterialManager * PhysMaterials
Definition: Engine.h:285
ThreadingManager * _ThreadingManager
Definition: Engine.h:287
#define SAFE_RELEASEDEL(x)
Definition: Define.h:115
SoundDevice * Sound
Definition: Engine.h:276
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void UnlinkAll()
Definition: Window.cpp:279
FileSystem * MainFileHandler
Definition: Engine.h:281
NewtonManager * _NewtonManager
Definition: Engine.h:284
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
Random * MainRandom
Definition: Engine.h:282
std::unique_ptr< EntitySerializer > _EntitySerializer
Definition: Engine.h:292
DLLEXPORT void UnregisterGraphics()
Must be called if MakeThreadsWorkWithOgre has been called, BEFORE releasing graphics.
#define SAFE_DELETE(x)
Definition: Define.h:116
Graphics * Graph
Definition: Engine.h:271
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:321
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274
EventHandler * MainEvents
Definition: Engine.h:278

◆ RenderFrame()

void Engine::RenderFrame ( )

Definition at line 958 of file Engine.cpp.

959 {
960  // We want to totally ignore this if we are in text mode //
961  if(NoGui)
962  return;
963 
964  int SinceLastFrame = -1;
965  GUARD_LOCK();
966 
967  // limit check //
968  if(!RenderTimer->CanRenderNow(FrameLimit, SinceLastFrame)) {
969 
970  // fps would go too high //
971  return;
972  }
973 
974  // since last frame is in microseconds 10^-6 convert to milliseconds //
975  // SinceLastTickTime is always more than 1000 (always 1 ms or more) //
976  SinceLastFrame /= 1000;
977  FrameCount++;
978 
979  // advanced statistic start monitoring //
981 
983  new Event(EVENT_TYPE_FRAME_BEGIN, new IntegerEventData(SinceLastFrame)));
984 
985  // Calculate parameters for GameWorld frame rendering systems //
986  int64_t timeintick = Time::GetTimeMs64() - LastTickTime;
987  int moreticks = 0;
988 
989  while(timeintick > TICKSPEED) {
990 
991  timeintick -= TICKSPEED;
992  moreticks++;
993  }
994 
995  bool shouldrender = false;
996 
997  // Render //
998  if(GraphicalEntity1 && GraphicalEntity1->Render(SinceLastFrame, TickCount + moreticks,
999  static_cast<int>(timeintick)))
1000  shouldrender = true;
1001 
1002  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1003 
1004  if(AdditionalGraphicalEntities[i]->Render(
1005  SinceLastFrame, TickCount + moreticks, static_cast<int>(timeintick)))
1006  shouldrender = true;
1007  }
1008 
1009  guard.unlock();
1010  if(shouldrender)
1011  Graph->Frame();
1012 
1013  guard.lock();
1015 
1016  // advanced statistics frame has ended //
1018 }
Class that represents a statically defined event.
Definition: Event.h:128
RenderingStatistics * RenderTimer
Definition: Engine.h:270
Window * GraphicalEntity1
Definition: Engine.h:273
Data for EVENT_TYPE_ENGINE_TICK and all others that have only int data.
Definition: Event.h:114
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT bool Render(int mspassed, int tick, int timeintick)
This function uses the LinkObjects function objects.
Definition: Window.cpp:290
static DLLEXPORT int64_t GetTimeMs64()
DLLEXPORT void CallEvent(Event *event)
int64_t LastTickTime
Definition: Engine.h:312
DLLEXPORT bool CanRenderNow(int maxfps, int &TimeSinceLastFrame)
Graphics * Graph
Definition: Engine.h:271
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
DLLEXPORT bool Frame()
Definition: Graphics.cpp:419
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274
EventHandler * MainEvents
Definition: Engine.h:278

◆ ReportClosedWindow() [1/2]

DLLEXPORT void Engine::ReportClosedWindow ( Lock guard,
Window windowentity 
)

Removes an closed window from the engine.

Definition at line 1080 of file Engine.cpp.

1081 {
1082  windowentity->UnlinkAll();
1083 
1084  if(GraphicalEntity1 == windowentity) {
1085 
1087  return;
1088  }
1089 
1090  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1091 
1092  if(AdditionalGraphicalEntities[i] == windowentity) {
1093 
1096 
1097  return;
1098  }
1099  }
1100 
1101  // Didn't find the target //
1102  Logger::Get()->Error("Engine: couldn't find closing Window");
1103 }
Window * GraphicalEntity1
Definition: Engine.h:273
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void UnlinkAll()
Definition: Window.cpp:279
#define SAFE_DELETE(x)
Definition: Define.h:116
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274

◆ ReportClosedWindow() [2/2]

DLLEXPORT void Leviathan::Engine::ReportClosedWindow ( Window windowentity)
inline

Definition at line 132 of file Engine.h.

133  {
134  GUARD_LOCK();
135  ReportClosedWindow(guard, windowentity);
136  }
DLLEXPORT void ReportClosedWindow(Lock &guard, Window *windowentity)
Removes an closed window from the engine.
Definition: Engine.cpp:1080
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ RunOnMainThread()

DLLEXPORT void Engine::RunOnMainThread ( const std::function< void()> &  function)

Runs the function now if on the main thread otherwise calls Invoke.

Definition at line 1135 of file Engine.cpp.

1136 {
1137  if(!IsOnMainThread()) {
1138 
1139  Invoke(function);
1140 
1141  } else {
1142 
1143  function();
1144  }
1145 }
DLLEXPORT bool IsOnMainThread() const
Returns true if called on the main thread.
Definition: Engine.cpp:87
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1112

◆ SaveScreenShot()

DLLEXPORT void Engine::SaveScreenShot ( )

Definition at line 1020 of file Engine.cpp.

1021 {
1022  LEVIATHAN_ASSERT(!NoGui, "really shouldn't try to screenshot in text-only mode");
1023  GUARD_LOCK();
1024 
1025  const string fileprefix = MainFileHandler->GetDataFolder() + "Screenshots/Captured_frame_";
1026 
1027  GraphicalEntity1->SaveScreenShot(fileprefix);
1028 }
static DLLEXPORT std::string GetDataFolder()
Definition: FileSystem.cpp:203
Window * GraphicalEntity1
Definition: Engine.h:273
DLLEXPORT void SaveScreenShot(const std::string &filename)
Definition: Window.cpp:617
FileSystem * MainFileHandler
Definition: Engine.h:281
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ SetNoGUI()

void Leviathan::Engine::SetNoGUI ( )
inline

Definition at line 220 of file Engine.h.

221  {
222 
223  NoGui = true;
224  }

◆ Tick()

void Engine::Tick ( )

Definition at line 841 of file Engine.cpp.

842 {
843  // Always try to update networking //
844  {
845  Lock lock(NetworkHandlerLock);
846 
847  if(_NetworkHandler)
849  }
850 
851  // And handle invokes //
852  ProcessInvokes();
853 
854  GUARD_LOCK();
855 
856  if(PreReleaseWaiting) {
857 
858  PreReleaseWaiting = false;
859  PreReleaseDone = true;
860 
861  Logger::Get()->Info("Engine: performing final release tick");
862 
863 
864 
865  // Call last tick event //
866 
867  return;
868  }
869 
870  // Get the passed time since the last update //
871  auto CurTime = Time::GetTimeMs64();
872  TimePassed = (int)(CurTime - LastTickTime);
873 
874 
875  if((TimePassed < TICKSPEED)) {
876  // It's not tick time yet //
877  return;
878  }
879 
880 
882  TickCount++;
883 
884  // Update input //
885 #ifdef LEVIATHAN_USES_LEAP
886  if(LeapData)
887  LeapData->OnTick(TimePassed);
888 #endif
889 
890  if(!NoGui) {
891  // sound tick //
892  if(Sound)
894 
895  // update windows //
896  if(GraphicalEntity1)
898 
899  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
900 
902  }
903  }
904 
905 
906  // Update worlds //
907  {
908  Lock lock(GameWorldsLock);
909 
910  // This will also update physics //
911  auto end = GameWorlds.end();
912  for(auto iter = GameWorlds.begin(); iter != end; ++iter) {
913 
914  (*iter)->Tick(TickCount);
915  }
916  }
917 
918 
919  // Some dark magic here //
920  if(TickCount % 25 == 0) {
921  // update values
924 
925  if(!NoGui) {
926  // send updated rendering statistics //
928  }
929  }
930 
931  // Update file listeners //
934 
935  // Send the tick event //
936  if(MainEvents)
938 
939  // Call the default app tick //
941 
942  TickTime = (int)(Time::GetTimeMs64() - CurTime);
943 }
Class that represents a statically defined event.
Definition: Event.h:128
virtual DLLEXPORT void UpdateAllConnections()
RenderingStatistics * RenderTimer
Definition: Engine.h:270
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
DLLEXPORT void Tick(int PassedMs)
Definition: SoundDevice.cpp:98
DLLEXPORT void CheckFileStatus()
Called by Engine to check are updated files available.
DataStore * Mainstore
Definition: Engine.h:277
NetworkHandler * _NetworkHandler
Definition: Engine.h:286
DLLEXPORT void ProcessInvokes()
Handles InvokeQueue.
Definition: Engine.cpp:1119
virtual DLLEXPORT void Tick(int mspassed)
Window * GraphicalEntity1
Definition: Engine.h:273
Data for EVENT_TYPE_ENGINE_TICK and all others that have only int data.
Definition: Event.h:114
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
bool PreReleaseWaiting
Definition: Engine.h:325
DLLEXPORT void Tick(int mspassed)
Called by Engine.
Definition: Window.cpp:284
static DLLEXPORT int64_t GetTimeMs64()
SoundDevice * Sound
Definition: Engine.h:276
std::mutex NetworkHandlerLock
Mutex that is locked while NetworkHandler is used.
Definition: Engine.h:309
DLLEXPORT void CallEvent(Event *event)
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:289
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:306
int64_t LastTickTime
Definition: Engine.h:312
DLLEXPORT void ReportStats(DataStore *dstore)
DLLEXPORT void SetTickTime(int newval)
Definition: DataStore.cpp:369
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:321
#define GUARD_LOCK()
Definition: ThreadSafe.h:91
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:303
DLLEXPORT void SetTickCount(int newval)
Definition: DataStore.cpp:364
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:15
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:274
EventHandler * MainEvents
Definition: Engine.h:278
LeviathanApplication * Owner
Definition: Engine.h:300

Member Data Documentation

◆ _ConsoleInput

std::unique_ptr<ConsoleInput> Leviathan::Engine::_ConsoleInput
protected

Definition at line 291 of file Engine.h.

◆ _EntitySerializer

std::unique_ptr<EntitySerializer> Leviathan::Engine::_EntitySerializer
protected

Definition at line 292 of file Engine.h.

◆ _NetworkHandler

NetworkHandler* Leviathan::Engine::_NetworkHandler = nullptr
protected

Definition at line 286 of file Engine.h.

◆ _NewtonManager

NewtonManager* Leviathan::Engine::_NewtonManager = nullptr
protected

Definition at line 284 of file Engine.h.

◆ _RemoteConsole

RemoteConsole* Leviathan::Engine::_RemoteConsole = nullptr
protected

Definition at line 288 of file Engine.h.

◆ _ResourceRefreshHandler

ResourceRefreshHandler* Leviathan::Engine::_ResourceRefreshHandler = nullptr
protected

Definition at line 289 of file Engine.h.

◆ _ThreadingManager

ThreadingManager* Leviathan::Engine::_ThreadingManager = nullptr
protected

Definition at line 287 of file Engine.h.

◆ AdditionalGraphicalEntities

std::vector<Window*> Leviathan::Engine::AdditionalGraphicalEntities
protected

Definition at line 274 of file Engine.h.

◆ Define

AppDef* Leviathan::Engine::Define = nullptr
protected

Definition at line 268 of file Engine.h.

◆ FrameCount

int Leviathan::Engine::FrameCount = 0
protected

Definition at line 318 of file Engine.h.

◆ FrameLimit

int Leviathan::Engine::FrameLimit = 0
protected

Definition at line 315 of file Engine.h.

◆ GameWorlds

std::vector<std::shared_ptr<GameWorld> > Leviathan::Engine::GameWorlds
protected

List of current worlds.

Definition at line 303 of file Engine.h.

◆ GameWorldsLock

std::mutex Leviathan::Engine::GameWorldsLock
protected

Mutex that is locked when changing the worlds.

Definition at line 306 of file Engine.h.

◆ Graph

Graphics* Leviathan::Engine::Graph = nullptr
protected

Definition at line 271 of file Engine.h.

◆ GraphicalEntity1

Window* Leviathan::Engine::GraphicalEntity1 = nullptr
protected

Definition at line 273 of file Engine.h.

◆ IDDefaultInstance

IDFactory* Leviathan::Engine::IDDefaultInstance = nullptr
protected

Definition at line 299 of file Engine.h.

◆ instance

DLLEXPORT Engine * Engine::instance = nullptr
staticprotected

Definition at line 351 of file Engine.h.

◆ InvokeLock

RecursiveMutex Leviathan::Engine::InvokeLock
protected

Definition at line 342 of file Engine.h.

◆ InvokeQueue

std::list<std::function<void()> > Leviathan::Engine::InvokeQueue
protected

Definition at line 343 of file Engine.h.

◆ IsClient

bool Leviathan::Engine::IsClient = false
protected

Set to true when initialized as a client.

Used to call client specific events

Definition at line 335 of file Engine.h.

◆ LastTickTime

int64_t Leviathan::Engine::LastTickTime
protected

Definition at line 312 of file Engine.h.

◆ MainConsole

ScriptConsole* Leviathan::Engine::MainConsole = nullptr
protected

Definition at line 280 of file Engine.h.

◆ MainEvents

EventHandler* Leviathan::Engine::MainEvents = nullptr
protected

Definition at line 278 of file Engine.h.

◆ MainFileHandler

FileSystem* Leviathan::Engine::MainFileHandler = nullptr
protected

Definition at line 281 of file Engine.h.

◆ MainRandom

Random* Leviathan::Engine::MainRandom = nullptr
protected

Definition at line 282 of file Engine.h.

◆ MainScript

ScriptExecutor* Leviathan::Engine::MainScript = nullptr
protected

Definition at line 279 of file Engine.h.

◆ Mainstore

DataStore* Leviathan::Engine::Mainstore = nullptr
protected

Definition at line 277 of file Engine.h.

◆ NetworkHandlerLock

std::mutex Leviathan::Engine::NetworkHandlerLock
protected

Mutex that is locked while NetworkHandler is used.

Definition at line 309 of file Engine.h.

◆ NoGui

bool Leviathan::Engine::NoGui = false
protected

Definition at line 328 of file Engine.h.

◆ NoLeap

bool Leviathan::Engine::NoLeap = false
protected

Definition at line 329 of file Engine.h.

◆ NoSTDInput

bool Leviathan::Engine::NoSTDInput = false
protected

Definition at line 330 of file Engine.h.

◆ OutOMemory

OutOfMemoryHandler* Leviathan::Engine::OutOMemory = nullptr
protected

Definition at line 283 of file Engine.h.

◆ Owner

LeviathanApplication* Leviathan::Engine::Owner = nullptr
protected

Definition at line 300 of file Engine.h.

◆ PassedCommands

std::vector<std::unique_ptr<std::string> > Leviathan::Engine::PassedCommands
protected

Definition at line 346 of file Engine.h.

◆ PhysMaterials

PhysicsMaterialManager* Leviathan::Engine::PhysMaterials = nullptr
protected

Definition at line 285 of file Engine.h.

◆ PreReleaseCompleted

bool Leviathan::Engine::PreReleaseCompleted = false
protected

Definition at line 338 of file Engine.h.

◆ PreReleaseDone

bool Leviathan::Engine::PreReleaseDone = false
protected

Set when PreRelease is called and Tick has happened.

Definition at line 321 of file Engine.h.

◆ PreReleaseWaiting

bool Leviathan::Engine::PreReleaseWaiting = false
protected

Set when PreRelease called and waiting for Tick see PreReleaseDone

Definition at line 325 of file Engine.h.

◆ QueuedConsoleCommands

std::vector<std::unique_ptr<std::string> > Leviathan::Engine::QueuedConsoleCommands
protected

Stores console commands that came from the command line.

Definition at line 349 of file Engine.h.

◆ RenderTimer

RenderingStatistics* Leviathan::Engine::RenderTimer = nullptr
protected

Definition at line 270 of file Engine.h.

◆ Sound

SoundDevice* Leviathan::Engine::Sound = nullptr
protected

Definition at line 276 of file Engine.h.

◆ TickCount

int Leviathan::Engine::TickCount = 0
protected

Definition at line 316 of file Engine.h.

◆ TickTime

int Leviathan::Engine::TickTime = 0
protected

Definition at line 317 of file Engine.h.

◆ TimePassed

int Leviathan::Engine::TimePassed = 0
protected

Definition at line 314 of file Engine.h.


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