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, const std::shared_ptr< PhysicsMaterialManager > &physicsMaterials, const WorldNetworkSettings &networking, int overrideid=-1)
 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 bool CloseWindow (Window *window)
 Closes a window. More...
 
DLLEXPORT WindowGetWindowEntity ()
 Returns the main window. More...
 
DLLEXPORT void ReportClosedWindow (Window *windowentity)
 Removes an closed window from the engine. More...
 
DLLEXPORT bool IsValidWindow (Window *window) const
 
DLLEXPORT void SaveScreenShot ()
 
DLLEXPORT void OpenEditorWindow (Window *useexistingwindow=nullptr)
 Opens an Editor::Editor window. More...
 
DLLEXPORT void FocusOrOpenEditor ()
 Focuses the first editor or opens an editor if none are open. More...
 
GraphicsGetGraphics ()
 
bool IsInGraphicalMode () const
 
EventHandlerGetEventHandler ()
 
RenderingStatisticsGetRenderingStatistics ()
 
ScriptConsoleGetScriptConsole ()
 
FileSystemGetFileSystem ()
 
AppDefGetDefinition ()
 
LeviathanApplicationGetOwningApplication ()
 
NetworkHandlerGetNetworkHandler ()
 
ThreadingManagerGetThreadingManager ()
 
SoundDeviceGetSoundDevice ()
 
ResourceRefreshHandlerGetResourceRefreshHandler ()
 
RemoteConsoleGetRemoteConsole ()
 
RandomGetRandom ()
 
GameModuleLoaderGetGameModuleLoader ()
 
ScriptExecutorGetScriptExecutor ()
 
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...
 

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
 
NetworkHandler_NetworkHandler = nullptr
 
ThreadingManager_ThreadingManager = nullptr
 
RemoteConsole_RemoteConsole = nullptr
 
ResourceRefreshHandler_ResourceRefreshHandler = nullptr
 
std::unique_ptr< ConsoleInput_ConsoleInput
 
std::unique_ptr< GameModuleLoader_GameModuleLoader
 
std::vector< std::unique_ptr< Editor::Editor > > OpenedEditors
 
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...
 
std::vector< std::unique_ptr< Editor::Importer > > QueuedImports
 Queued importers from command line parsing. More...
 
- Protected Attributes inherited from Leviathan::ThreadSafeGeneric< MutexType >
MutexType ObjectsLock
 

Static Protected Attributes

static DLLEXPORT Engineinstance = nullptr
 

Additional Inherited Members

- Public Types inherited from Leviathan::ThreadSafeGeneric< MutexType >
using LockT = typename LockTypeResolver< MutexType >::LType
 

Detailed Description

The main class of the Leviathan Game Engine.

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

Note
Only some operations are thread safe
Todo:
Reduce the amount of logging and mention thread safety on methods that ARE thread safe and add note to assume that everything else isn't

Definition at line 34 of file Engine.h.

Constructor & Destructor Documentation

◆ Engine()

DLLEXPORT Engine::Engine ( LeviathanApplication owner)

Definition at line 62 of file Engine.cpp.

62  : Owner(owner)
63 {
64  // This makes sure that uninitialized engine will have at least some last frame time //
66 
67  instance = this;
68 }
static DLLEXPORT int64_t GetTimeMs64()
int64_t LastTickTime
Definition: Engine.h:348
static DLLEXPORT Engine * instance
Definition: Engine.h:391
LeviathanApplication * Owner
Definition: Engine.h:336

◆ ~Engine()

DLLEXPORT Engine::~Engine ( )

Definition at line 70 of file Engine.cpp.

71 {
72  // Reset the instance ptr //
73  instance = nullptr;
74 
75  _ConsoleInput.reset();
76 }
std::unique_ptr< ConsoleInput > _ConsoleInput
Definition: Engine.h:326
static DLLEXPORT Engine * instance
Definition: Engine.h:391

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 1278 of file Engine.cpp.

1279 {
1280 
1281  GUARD_LOCK();
1282 
1283  if(!absolute) {
1284 
1285  Logger::Get()->Info("Engine: adjusted tick timer by " + Convert::ToString(amount));
1286 
1287  LastTickTime += amount;
1288  return;
1289  }
1290 
1291  // Calculate the time in the current last tick //
1292  int64_t templasttick = LastTickTime;
1293 
1294  int64_t curtime = Time::GetTimeMs64();
1295 
1296  while(curtime - templasttick >= TICKSPEED) {
1297 
1298  templasttick += TICKSPEED;
1299  }
1300 
1301  // Check how far off we are from the target //
1302  int64_t intolasttick = curtime - templasttick;
1303 
1304  int changeamount = amount - static_cast<int>(intolasttick);
1305 
1306  Logger::Get()->Info("Engine: changing tick counter by " + Convert::ToString(changeamount));
1307 
1308  LastTickTime += changeamount;
1309 }
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:22
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:348
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

◆ _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 1311 of file Engine.cpp.

1312 {
1313 
1314  GUARD_LOCK();
1315 
1316  if(!absolute) {
1317 
1318  TickCount += tickamount;
1319 
1320  Logger::Get()->Info("Engine: adjusted tick by " + Convert::ToString(tickamount) +
1321  ", tick is now " + Convert::ToString(TickCount));
1322 
1323  return;
1324  }
1325 
1326  TickCount = tickamount;
1327 
1328  Logger::Get()->Info("Engine: tick set to " + Convert::ToString(TickCount));
1329 }
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:111

◆ _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 1257 of file Engine.cpp.

1258 {
1259  if(NoGui)
1260  return;
1261 
1262  // Register threads to use graphical objects //
1264 }
DLLEXPORT void MakeThreadsWorkWithOgre()
Makes the threads work with Ogre.
ThreadingManager * _ThreadingManager
Definition: Engine.h:322

◆ _ReceiveConsoleInput()

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

Console input comes through this.

Definition at line 1595 of file Engine.cpp.

1596 {
1597  Invoke([=]() {
1598  if(MainConsole) {
1599 
1600  MainConsole->RunConsoleCommand(command);
1601 
1602  } else {
1603 
1604  LOG_WARNING("No console handler attached, cannot run command");
1605  }
1606  });
1607 
1608  // Listening thread quits if PreReleaseWaiting is true
1609  return PreReleaseWaiting;
1610 }
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1162
ScriptConsole * MainConsole
Definition: Engine.h:317
bool PreReleaseWaiting
Definition: Engine.h:361
#define LOG_WARNING(x)
Definition: Define.h:89
DLLEXPORT int RunConsoleCommand(std::string cmd)
Definition: Console.cpp:49

◆ _RunQueuedConsoleCommands()

void Engine::_RunQueuedConsoleCommands ( )
protected

Runs all commands in QueuedConsoleCommands.

Definition at line 1571 of file Engine.cpp.

1572 {
1573  if(QueuedConsoleCommands.empty())
1574  return;
1575 
1576  if(!MainConsole) {
1577 
1578  LOG_FATAL("Engine: MainConsole has not been created before running command line "
1579  "passed commands");
1580  return;
1581  }
1582 
1583  LOG_INFO("Engine: Running PostStartup command line. Commands: " +
1585 
1586  for(auto& command : QueuedConsoleCommands) {
1587 
1588  LOG_INFO("Engine: Running \"" + *command + "\"");
1589  MainConsole->RunConsoleCommand(*command);
1590  }
1591 
1592  QueuedConsoleCommands.clear();
1593 }
#define LOG_INFO(x)
Definition: Define.h:88
#define LOG_FATAL(x)
Definition: Define.h:92
ScriptConsole * MainConsole
Definition: Engine.h:317
DLLEXPORT int RunConsoleCommand(std::string cmd)
Definition: Console.cpp:49
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:386

◆ AssertIfNotMainThread()

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

Asserts if not called on the main thread.

Definition at line 105 of file Engine.h.

106  {
108  IsOnMainThread(), "Function not called on main thread (AssertIfNotMainThread)");
109  }
DLLEXPORT bool IsOnMainThread() const
Returns true if called on the main thread.
Definition: Engine.cpp:90
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98

◆ ClearTimers()

DLLEXPORT void Engine::ClearTimers ( )

Clears physical timers.

Definition at line 1249 of file Engine.cpp.

1250 {
1251  Lock lock(GameWorldsLock);
1252 
1253  for(auto iter = GameWorlds.begin(); iter != GameWorlds.end(); ++iter) {
1254  }
1255 }
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:342
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18

◆ CloseWindow()

DLLEXPORT bool Engine::CloseWindow ( Window window)

Closes a window.

Note
Due to Ogre related issues the window isn't actually closed before shutting down completely
Returns
True if closed. False if window was invalid

This is a wrapper for ReportClosedWindow

Definition at line 1087 of file Engine.cpp.

1088 {
1089  if(!window)
1090  return false;
1091 
1092  if(IsValidWindow(window)) {
1093 
1094  ReportClosedWindow(window);
1095  return true;
1096  } else {
1097  return false;
1098  }
1099 }
DLLEXPORT void ReportClosedWindow(Window *windowentity)
Removes an closed window from the engine.
Definition: Engine.cpp:1101
DLLEXPORT bool IsValidWindow(Window *window) const
Definition: Engine.cpp:1047

◆ CreateWorld()

DLLEXPORT std::shared_ptr< GameWorld > Engine::CreateWorld ( Window owningwindow,
int  worldtype,
const std::shared_ptr< PhysicsMaterialManager > &  physicsMaterials,
const WorldNetworkSettings networking,
int  overrideid = -1 
)

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
Parameters
worldtypeIs the type of the world to be created. This is passed to the game's registered world factory. Types over 1024 are reserved for inbuilt types and are needed for example things like the editor
physicsMaterialsThe physical materials used for the world. This must be non-null if physics is wanted for this world. This is here in order to allow inbuilt worlds to have custom materials
overrideidSet to >= 0 if this is a clientside world and must have the specific id

Definition at line 1195 of file Engine.cpp.

1198 {
1199  std::shared_ptr<GameWorld> world;
1200  if(worldtype >= 1024) {
1201  // Standard world types
1203  static_cast<INBUILT_WORLD_TYPE>(worldtype), physicsMaterials, overrideid);
1204  } else {
1205  world =
1206  GameWorldFactory::Get()->CreateNewWorld(worldtype, physicsMaterials, overrideid);
1207  }
1208 
1209  if(!world) {
1210 
1211  LOG_ERROR("Engine: CreateWorld: factory failed to create a world of type: " +
1212  std::to_string(worldtype));
1213  return nullptr;
1214  }
1215 
1216  world->Init(networking, NoGui ? nullptr : Graph);
1217 
1218  if(owningwindow)
1219  owningwindow->LinkObjects(world);
1220 
1221  Lock lock(GameWorldsLock);
1222 
1223  GameWorlds.push_back(world);
1224  return GameWorlds.back();
1225 }
#define LOG_ERROR(x)
Definition: Define.h:90
static DLLEXPORT GameWorldFactory * Get()
DLLEXPORT bool Init(const WorldNetworkSettings &network, Graphics *graphics)
Creates resources for the world to work.
Definition: GameWorld.cpp:103
DLLEXPORT void LinkObjects(std::shared_ptr< GameWorld > world)
This function also updates the camera aspect ratio.
Definition: Window.cpp:266
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:342
virtual DLLEXPORT std::shared_ptr< GameWorld > CreateNewWorld(int worldtype, const std::shared_ptr< PhysicsMaterialManager > &physicsMaterials, int overrideid=-1)
Creates a new world that can be used.
Graphics * Graph
Definition: Engine.h:308
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
static std::shared_ptr< GameWorld > CreateNewWorld(INBUILT_WORLD_TYPE worldtype, const std::shared_ptr< PhysicsMaterialManager > &physicsMaterials, int overrideid=-1)
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18

◆ DestroyWorld()

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

Releases a GameWorld.

Parameters
worldThe world to destroy. This is taken as a const reference to allow shared_ptrs of derived types to be passed here. Make sure to call world.reset() afterwards to release the reference.
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 1227 of file Engine.cpp.

1228 {
1229  if(!world)
1230  return;
1231 
1232  // Release the world first //
1233  world->Release();
1234 
1235  // Then delete it //
1236  Lock lock(GameWorldsLock);
1237 
1238  auto end = GameWorlds.end();
1239  for(auto iter = GameWorlds.begin(); iter != end; ++iter) {
1240 
1241  if((*iter).get() == world.get()) {
1242 
1243  GameWorlds.erase(iter);
1244  return;
1245  }
1246  }
1247 }
DLLEXPORT void Release()
Release resources.
Definition: GameWorld.cpp:130
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:342
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18

◆ ExecuteCommandLine()

DLLEXPORT void Engine::ExecuteCommandLine ( )
protected

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

Definition at line 1483 of file Engine.cpp.

1484 {
1485  StringIterator itr;
1486 
1487  // TODO: this does nothing
1488  // Iterate over the commands and process them //
1489  for(size_t i = 0; i < PassedCommands.size(); i++) {
1490 
1491  itr.ReInit(PassedCommands[i].get());
1492  // Skip the preceding '-'s //
1493  itr.SkipCharacters('-');
1494 
1495  // Get the command //
1496  auto firstpart = itr.GetUntilNextCharacterOrAll<string>(':');
1497 
1498  // Execute the wanted command //
1499  if(StringOperations::CompareInsensitive<string>(*firstpart, "RemoteConsole")) {
1500 
1501  // Get the next command //
1502  auto commandpart = itr.GetUntilNextCharacterOrAll<string>(L':');
1503 
1504  if(*commandpart == "CloseIfNone") {
1505  // Set the command //
1507  Logger::Get()->Info("Engine will close when no active/waiting remote console "
1508  "sessions");
1509 
1510  } else if(*commandpart == "OpenTo") {
1511  // Get the to part //
1512  auto topart = itr.GetStringInQuotes<string>(QUOTETYPE_BOTH);
1513 
1514  int token = 0;
1515 
1516  auto numberpart = itr.GetNextNumber<string>(DECIMALSEPARATORTYPE_NONE);
1517 
1518  if(numberpart->size() == 0) {
1519 
1520  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1521  "no token number provided");
1522  continue;
1523  }
1524  // Convert to a real number. Maybe we could see if the token is
1525  // complex enough here, but that isn't necessary
1526  token = Convert::StringTo<int>(*numberpart);
1527 
1528  if(token == 0) {
1529  // Invalid number? //
1530  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1531  "couldn't parse token number, " +
1532  *numberpart);
1533  continue;
1534  }
1535 
1536  // Create a connection (or potentially use an existing one) //
1537  shared_ptr<Connection> tmpconnection =
1539 
1540  // Tell remote console to open a command to it //
1541  if(tmpconnection) {
1542 
1543  _RemoteConsole->OfferConnectionTo(tmpconnection, "AutoOpen", token);
1544 
1545  } else {
1546  // Something funky happened... //
1547  Logger::Get()->Warning("Engine: ExecuteCommandLine: RemoteConsole: "
1548  "couldn't open connection to " +
1549  *topart + ", couldn't resolve address");
1550  }
1551 
1552  } else {
1553  // Unknown command //
1554  Logger::Get()->Warning("Engine: ExecuteCommandLine: unknown RemoteConsole "
1555  "command: " +
1556  *commandpart +
1557  ", whole argument: " + *PassedCommands[i]);
1558  }
1559  }
1560  }
1561 
1562 
1563  PassedCommands.clear();
1564 
1565  // Now we can set some things that require command line arguments //
1566  // _RemoteConsole might be NULL //
1567  if(_RemoteConsole)
1569 }
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
NetworkHandler * _NetworkHandler
Definition: Engine.h:321
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:383
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't match the current character.
RemoteConsole * _RemoteConsole
Definition: Engine.h:323
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.

◆ FocusOrOpenEditor()

DLLEXPORT void Engine::FocusOrOpenEditor ( )

Focuses the first editor or opens an editor if none are open.

Todo:
Closed editors need to report that they are closed in order to open one again

Definition at line 1145 of file Engine.cpp.

1146 {
1147  if(OpenedEditors.empty()) {
1148 
1149  OpenEditorWindow();
1150  return;
1151  }
1152 
1153  OpenedEditors.front()->BringToFront();
1154 }
DLLEXPORT void OpenEditorWindow(Window *useexistingwindow=nullptr)
Opens an Editor::Editor window.
Definition: Engine.cpp:1126
std::vector< std::unique_ptr< Editor::Editor > > OpenedEditors
Definition: Engine.h:328

◆ Get()

DLLEXPORT Engine * Engine::Get ( )
static

Definition at line 85 of file Engine.cpp.

86 {
87  return instance;
88 }
static DLLEXPORT Engine * instance
Definition: Engine.h:391

◆ GetCurrentTick()

DLLEXPORT int Engine::GetCurrentTick ( ) const

Returns the number of tick that was last simulated.

Definition at line 1272 of file Engine.cpp.

1273 {
1274 
1275  return TickCount;
1276 }

◆ GetDefinition()

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

Definition at line 205 of file Engine.h.

206  {
207  return Define;
208  }
AppDef * Define
Definition: Engine.h:305

◆ GetEngine()

Engine * Engine::GetEngine ( )
static

Definition at line 80 of file Engine.cpp.

81 {
82  return instance;
83 }
static DLLEXPORT Engine * instance
Definition: Engine.h:391

◆ GetEventHandler()

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

Definition at line 189 of file Engine.h.

190  {
191  return MainEvents;
192  }
EventHandler * MainEvents
Definition: Engine.h:315

◆ GetFileSystem()

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

Definition at line 201 of file Engine.h.

202  {
203  return MainFileHandler;
204  }
FileSystem * MainFileHandler
Definition: Engine.h:318

◆ GetGameModuleLoader()

GameModuleLoader* Leviathan::Engine::GetGameModuleLoader ( )
inline

Definition at line 237 of file Engine.h.

238  {
239  return _GameModuleLoader.get();
240  }
std::unique_ptr< GameModuleLoader > _GameModuleLoader
Definition: Engine.h:327

◆ GetGraphics()

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

Definition at line 179 of file Engine.h.

180  {
181  return Graph;
182  }
Graphics * Graph
Definition: Engine.h:308

◆ GetNetworkHandler()

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

Definition at line 213 of file Engine.h.

214  {
215  return _NetworkHandler;
216  }
NetworkHandler * _NetworkHandler
Definition: Engine.h:321

◆ GetNoGui()

bool Leviathan::Engine::GetNoGui ( )
inline

Definition at line 255 of file Engine.h.

256  {
257  return NoGui;
258  }

◆ GetOwningApplication()

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

Definition at line 209 of file Engine.h.

210  {
211  return Owner;
212  }
LeviathanApplication * Owner
Definition: Engine.h:336

◆ GetRandom()

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

Definition at line 233 of file Engine.h.

234  {
235  return MainRandom;
236  }
Random * MainRandom
Definition: Engine.h:319

◆ GetRemoteConsole()

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

Definition at line 229 of file Engine.h.

230  {
231  return _RemoteConsole;
232  }
RemoteConsole * _RemoteConsole
Definition: Engine.h:323

◆ GetRenderingStatistics()

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

Definition at line 193 of file Engine.h.

194  {
195  return RenderTimer;
196  }
RenderingStatistics * RenderTimer
Definition: Engine.h:307

◆ GetResourceRefreshHandler()

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

Definition at line 225 of file Engine.h.

226  {
228  }
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:324

◆ GetScriptConsole()

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

Definition at line 197 of file Engine.h.

198  {
199  return MainConsole;
200  }
ScriptConsole * MainConsole
Definition: Engine.h:317

◆ GetScriptExecutor()

ScriptExecutor* Leviathan::Engine::GetScriptExecutor ( )
inline

Definition at line 241 of file Engine.h.

242  {
243  return MainScript;
244  }
ScriptExecutor * MainScript
Definition: Engine.h:316

◆ GetSoundDevice()

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

Definition at line 221 of file Engine.h.

222  {
223  return Sound;
224  }
SoundDevice * Sound
Definition: Engine.h:313

◆ GetThreadingManager()

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

Definition at line 217 of file Engine.h.

218  {
219  return _ThreadingManager;
220  }
ThreadingManager * _ThreadingManager
Definition: Engine.h:322

◆ 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 1266 of file Engine.cpp.

1267 {
1268 
1269  return Time::GetTimeMs64() - LastTickTime;
1270 }
static DLLEXPORT int64_t GetTimeMs64()
int64_t LastTickTime
Definition: Engine.h:348

◆ GetWindowEntity()

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

Returns the main window.

Definition at line 156 of file Engine.h.

157  {
158  return GraphicalEntity1;
159  }
Window * GraphicalEntity1
Definition: Engine.h:310

◆ GetWindowFromSDLID()

DLLEXPORT Window * Engine::GetWindowFromSDLID ( uint32_t  sdlid)

Definition at line 819 of file Engine.cpp.

820 {
821  if(GraphicalEntity1 && GraphicalEntity1->GetSDLID() == sdlid) {
822  return GraphicalEntity1;
823  }
824 
825  for(auto iter = AdditionalGraphicalEntities.begin();
826  iter != AdditionalGraphicalEntities.end(); ++iter) {
827  if((*iter)->GetSDLID() == sdlid) {
828 
829  return *iter;
830  }
831  }
832 
833  return nullptr;
834 }
Window * GraphicalEntity1
Definition: Engine.h:310
DLLEXPORT uint32_t GetSDLID() const
Definition: Window.cpp:906
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311

◆ GetWindowOpenCount()

DLLEXPORT int Engine::GetWindowOpenCount ( )

Definition at line 1026 of file Engine.cpp.

1027 {
1028  int openwindows = 0;
1029 
1030  // If we are in text only mode always return 1 //
1031  if(NoGui)
1032  return 1;
1033 
1034  // TODO: should there be an IsOpen method?
1035  if(GraphicalEntity1)
1036  openwindows++;
1037 
1038  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1039 
1041  openwindows++;
1042  }
1043 
1044  return openwindows;
1045 }
Window * GraphicalEntity1
Definition: Engine.h:310
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311

◆ 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 57 of file Engine.h.

58  {
59  return PreReleaseDone;
60  }
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:357

◆ Init()

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

Definition at line 95 of file Engine.cpp.

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

◆ 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
Todo:
Write a wrapper file that can be used for invoking without having to include this huge file

Definition at line 1162 of file Engine.cpp.

1163 {
1164  RecursiveLock lock(InvokeLock);
1165  InvokeQueue.push_back(function);
1166 }
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:19
std::list< std::function< void()> > InvokeQueue
Definition: Engine.h:379
RecursiveMutex InvokeLock
Definition: Engine.h:378

◆ IsInGraphicalMode()

bool Leviathan::Engine::IsInGraphicalMode ( ) const
inline

Definition at line 184 of file Engine.h.

185  {
186  return !NoGui;
187  }

◆ IsOnMainThread()

DLLEXPORT bool Engine::IsOnMainThread ( ) const

Returns true if called on the main thread.

Definition at line 90 of file Engine.cpp.

91 {
92  return MainThreadMagic == THREAD_MAGIC;
93 }
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

◆ IsValidWindow()

DLLEXPORT bool Engine::IsValidWindow ( Window window) const
Returns
True if window is a valid open Window

Definition at line 1047 of file Engine.cpp.

1048 {
1049  if(window == GraphicalEntity1) {
1050  return true;
1051  }
1052 
1053  for(Window* openWindow : AdditionalGraphicalEntities) {
1054  if(openWindow == window) {
1055  return true;
1056  }
1057  }
1058 
1059  return false;
1060 }
Window * GraphicalEntity1
Definition: Engine.h:310
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311

◆ MarkQuit()

DLLEXPORT void Engine::MarkQuit ( )

Marks the owning application to quit.

Definition at line 1156 of file Engine.cpp.

1157 {
1158  if(Owner)
1159  Owner->MarkAsClosing();
1160 }
DLLEXPORT void MarkAsClosing()
Thread safely marks the game to close sometime.
LeviathanApplication * Owner
Definition: Engine.h:336

◆ MessagePump()

DLLEXPORT void Engine::MessagePump ( )

Processes queued messages from Ogre, SDL and input.

Definition at line 633 of file Engine.cpp.

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

◆ OpenEditorWindow()

DLLEXPORT void Engine::OpenEditorWindow ( Window useexistingwindow = nullptr)

Opens an Editor::Editor window.

Todo:
Exit fullscreen mode if main window is in fullscreen mode

Definition at line 1126 of file Engine.cpp.

1127 {
1129 
1130  if(useexistingwindow && !IsValidWindow(useexistingwindow)) {
1131 
1132  LOG_WARNING("Engine: OpenEditorWindow: invalid window given, defaulting to opening a "
1133  "new window");
1134  useexistingwindow = nullptr;
1135  }
1136 
1137  if(!useexistingwindow) {
1138  useexistingwindow = OpenNewWindow();
1139  }
1140 
1141 
1142  OpenedEditors.emplace_back(std::make_unique<Editor::Editor>(useexistingwindow, this));
1143 }
#define LOG_WARNING(x)
Definition: Define.h:89
DLLEXPORT bool IsValidWindow(Window *window) const
Definition: Engine.cpp:1047
std::vector< std::unique_ptr< Editor::Editor > > OpenedEditors
Definition: Engine.h:328
DLLEXPORT Window * OpenNewWindow()
Opens a new window.
Definition: Engine.cpp:1062
DLLEXPORT void AssertIfNotMainThread() const
Asserts if not called on the main thread.
Definition: Engine.h:105

◆ 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 1062 of file Engine.cpp.

1063 {
1065 
1066  AppDef winparams;
1067 
1069  "Leviathan Window " + std::to_string(++WindowNameCounter), 1280, 720, "no",
1070  // Multiple vsyncs cause issues (or they can cause issues, sometimes it is fine)
1071  /* Define->GetWindowDetails().VSync */ false,
1072  // Opens on same display as the other window
1073  // TODO: open on next display
1075 #ifdef _WIN32
1076  Define->GetWindowDetails().Icon,
1077 #endif
1078  nullptr));
1079 
1080  auto newwindow = std::make_unique<Window>(Graph, &winparams);
1081 
1082  AdditionalGraphicalEntities.push_back(newwindow.get());
1083 
1084  return newwindow.release();
1085 }
AppDef * Define
Definition: Engine.h:305
static std::atomic< int > WindowNameCounter
Used for automatic unique window names.
Definition: Engine.cpp:60
DLLEXPORT WindowDataDetails & GetWindowDetails()
Definition: AppDefine.h:93
DLLEXPORT AppDef & SetWindowDetails(const WindowDataDetails &det)
Definition: AppDefine.h:75
Graphics * Graph
Definition: Engine.h:308
DLLEXPORT void AssertIfNotMainThread() const
Asserts if not called on the main thread.
Definition: Engine.h:105
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311

◆ 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 1340 of file Engine.cpp.

1341 {
1342  namespace po = boost::program_options;
1343 
1344  std::vector<std::vector<std::string>> import;
1345  std::vector<std::string> cmds;
1346  // TODO: these could probably directly be read into the variables in this class
1347  bool nogui = false;
1348  bool noleap = false;
1349  bool nocin = false;
1350 
1351  bool crash = false;
1352 
1353  po::options_description desc("Engine Options");
1354  // clang-format off
1355  desc.add_options()
1356  ("import", po::value<std::vector<std::string>>()->multitoken(),
1357  "Import assets from source to destination")
1358  ("cmd", po::value<std::vector<std::string>>(&cmds)->multitoken(),
1359  "Run console commands after startup")
1360  ("nogui", po::bool_switch(&nogui), "Disable graphics")
1361  ("nocin", po::bool_switch(&nocin), "Disable stdin reading")
1362  ("noleap", po::bool_switch(&noleap), "Disable Leap Motion")
1363  ("noleap", po::bool_switch(&crash), "Crash for testing purposes")
1364  // We see CEF arguments here, we need to allow them
1365  ("no-sandbox", "CEF option")
1366  ("single-process", "CEF option")
1367  ;
1368  // clang-format on
1369 
1370  // TODO: allow the game to add extra options here
1371 
1372  po::positional_options_description positional;
1373  positional.add("cmd", -1);
1374 
1375  // This was before added to PassedCommands.push_back(std::move(splitval));
1376  // but it would be better to make those actual flags
1377 
1378  po::variables_map vm;
1379 
1380  try {
1381  // The parsing is done in two steps here to add custom handling for the import option
1382  po::parsed_options parsed_options =
1383  po::command_line_parser(argcount, args).options(desc).positional(positional).run();
1384 
1385 
1386  // Read import option lists
1387  for(const po::option& option : parsed_options.options) {
1388  if(option.string_key == "import")
1389  import.push_back(option.value);
1390  }
1391 
1392  // Finish parsing
1393  po::store(parsed_options, vm);
1394  po::notify(vm);
1395 
1396  } catch(const po::error& e) {
1397  LOG_INFO("Engine: Command line: ");
1398  for(int i = 0; i < argcount; ++i) {
1399 
1400  LOG_WRITE("\t> " + (args[i] ? std::string(args[i]) : std::string()));
1401  }
1402 
1403  LOG_ERROR("Engine: parsing command line failed: " + std::string(e.what()));
1404 
1405  std::stringstream sstream;
1406  desc.print(sstream);
1407 
1408  LOG_WRITE(sstream.str());
1409 
1410  return false;
1411  }
1412 
1413  if(nogui) {
1414  NoGui = true;
1415  LOG_INFO("Engine starting in non-GUI mode");
1416  }
1417 
1418  if(nocin) {
1419  NoSTDInput = true;
1420  LOG_INFO("Engine not listening for terminal commands");
1421  }
1422 
1423  if(noleap) {
1424  NoLeap = true;
1425 
1426 #ifdef LEVIATHAN_USES_LEAP
1427  LOG_INFO("Engine starting with LeapMotion disabled");
1428 #endif
1429  }
1430 
1431  if(crash) {
1432  LOG_INFO("Engine testing crash handling");
1433  // TODO: write a file that disables crash handling
1434  // Make the log say something useful //
1435  Logger::Get()->Save();
1436 
1437  // Test crashing //
1438  TestCrash(12);
1439  }
1440 
1441  // // Coalesce commands
1442  // if(vm.count("console-commands")) {
1443  // }
1444 
1445  for(const std::string& command : cmds) {
1446  if(StringOperations::IsCharacterQuote(command.at(0))) {
1447 
1448  StringIterator itr(command);
1449 
1450  auto withoutquotes = itr.GetStringInQuotes<std::string>(QUOTETYPE_BOTH);
1451 
1452  if(withoutquotes) {
1453 
1454  QueuedConsoleCommands.push_back(std::move(withoutquotes));
1455 
1456  } else {
1457 
1458  LOG_WARNING("Engine: command in quotes is empty");
1459  }
1460 
1461  } else {
1462 
1463  QueuedConsoleCommands.push_back(std::make_unique<std::string>(command));
1464  }
1465  }
1466 
1467  for(const auto& group : import) {
1468 
1469  if(group.size() != 2) {
1470 
1471  LOG_ERROR("Import option needs two parameters, source and destination, parameter "
1472  "count: " +
1473  std::to_string(group.size()));
1474  return false;
1475  }
1476 
1477  QueuedImports.push_back(std::make_unique<Editor::Importer>(group[0], group[1]));
1478  }
1479 
1480  return true;
1481 }
#define LOG_INFO(x)
Definition: Define.h:88
#define LOG_ERROR(x)
Definition: Define.h:90
std::vector< std::unique_ptr< Editor::Importer > > QueuedImports
Queued importers from command line parsing.
Definition: Engine.h:389
#define LOG_WARNING(x)
Definition: Define.h:89
DLLEXPORT void Save()
Definition: Logger.cpp:203
static bool IsCharacterQuote(CharType character)
Iterator class for getting parts of a string.
#define LOG_WRITE(x)
Definition: Define.h:91
std::vector< std::unique_ptr< std::string > > QueuedConsoleCommands
Stores console commands that came from the command line.
Definition: Engine.h:386
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
int TestCrash(int writenum)
Definition: Engine.cpp:1331

◆ PostLoad()

void Engine::PostLoad ( )
protected

Definition at line 424 of file Engine.cpp.

425 {
426  // increase start count //
427  int startcounts = 0;
428 
429  if(Mainstore->GetValueAndConvertTo<int>("StartCount", startcounts)) {
430  // increase //
431  Mainstore->SetValue("StartCount", new VariableBlock(new IntBlock(startcounts + 1)));
432  } else {
433 
434  Mainstore->AddVar(
435  std::make_shared<NamedVariableList>("StartCount", new VariableBlock(1)));
436 
437  // set as persistent //
438  Mainstore->SetPersistance("StartCount", true);
439  }
440 
441  // Check if we are attached to a terminal //
442 
443  ClearTimers();
444 
445  // get time //
447 
449 
450  // Run startup command line //
452 
453  // Run queued imports
454  if(!QueuedImports.empty()) {
455  for(const auto& importer : QueuedImports) {
456  try {
457  if(!importer->Run()) {
458 
459  LOG_ERROR("An import operation failed");
460  }
461  } catch(const Exception& e) {
462  LOG_ERROR("An exception happened in importer:");
463  e.PrintToLog();
464  }
465  }
466 
467  QueuedImports.clear();
468  LOG_INFO("Marking as closing after processing imports");
469  MarkQuit();
470  }
471 }
DLLEXPORT void MarkQuit()
Marks the owning application to quit.
Definition: Engine.cpp:1156
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1249
bool GetValueAndConvertTo(const std::string &name, T &receiver) const
Definition: DataStore.h:82
#define LOG_INFO(x)
Definition: Define.h:88
#define LOG_ERROR(x)
Definition: Define.h:90
Non-template class for working with all types of DataBlocks.
Definition: DataBlock.h:425
DataStore * Mainstore
Definition: Engine.h:314
std::vector< std::unique_ptr< Editor::Importer > > QueuedImports
Queued importers from command line parsing.
Definition: Engine.h:389
void _RunQueuedConsoleCommands()
Runs all commands in QueuedConsoleCommands.
Definition: Engine.cpp:1571
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
static DLLEXPORT int64_t GetTimeMs64()
DLLEXPORT bool SetValue(const std::string &name, const VariableBlock &value1)
Definition: DataStore.cpp:164
DataBlock< int > IntBlock
Definition: DataBlock.h:382
DLLEXPORT void SetPersistance(unsigned int index, bool toset)
Definition: DataStore.cpp:135
int64_t LastTickTime
Definition: Engine.h:348
DLLEXPORT void ExecuteCommandLine()
Definition: Engine.cpp:1483
DLLEXPORT void AddVar(std::shared_ptr< NamedVariableList > values)
Definition: DataStore.cpp:208
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ PreFirstTick()

DLLEXPORT void Engine::PreFirstTick ( )

Definition at line 942 of file Engine.cpp.

943 {
944  GUARD_LOCK();
945 
948 
949  ClearTimers();
950 
951  Logger::Get()->Info("Engine: PreFirstTick: everything fine to start running");
952 }
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1249
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:322
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

◆ 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 473 of file Engine.cpp.

474 {
475  GUARD_LOCK();
476 
478  return;
479 
480  PreReleaseWaiting = true;
481  // This will stay true until the end of times //
482  PreReleaseCompleted = true;
483 
484  // Stop command handling first //
485  if(_ConsoleInput) {
486 
487  _ConsoleInput->Release(false);
488  Logger::Get()->Info("Successfully stopped command handling");
489  }
490 
491  // Close all editors
492  OpenedEditors.clear();
493 
494  // Automatically destroy input sources //
496 
497  // Then kill the network //
498  {
499  Lock lock(NetworkHandlerLock);
500 
502  }
503 
504  // Let the game release it's resources //
506 
507  // Close remote console //
509 
510  // Close all connections //
511  {
512  Lock lock(NetworkHandlerLock);
513 
515  }
516 
518 
519  // Set worlds to empty //
520  {
521  Lock lock(GameWorldsLock);
522 
523  for(auto iter = GameWorlds.begin(); iter != GameWorlds.end(); ++iter) {
524  // Set all objects to release //
525  (*iter)->MarkForClear();
526  }
527  }
528 
529  // Set tasks to a proper state //
532 
533  Logger::Get()->Info("Engine: prerelease done, waiting for a tick");
534 }
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:321
std::unique_ptr< ConsoleInput > _ConsoleInput
Definition: Engine.h:326
bool PreReleaseWaiting
Definition: Engine.h:361
virtual DLLEXPORT void CloseDown()=0
Called when the program is closing.
ThreadingManager * _ThreadingManager
Definition: Engine.h:322
std::vector< std::unique_ptr< Editor::Editor > > OpenedEditors
Definition: Engine.h:328
#define SAFE_RELEASEDEL(x)
Definition: Define.h:139
RemoteConsole * _RemoteConsole
Definition: Engine.h:323
std::mutex NetworkHandlerLock
Mutex that is locked while NetworkHandler is used.
Definition: Engine.h:345
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:324
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:342
bool PreReleaseCompleted
Definition: Engine.h:374
#define SAFE_DELETE(x)
Definition: Define.h:147
DLLEXPORT void ReleaseInputHandler()
Destroys the networked input handler and all input objects.
#define GUARD_LOCK()
Definition: ThreadSafe.h:111
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18
LeviathanApplication * Owner
Definition: Engine.h:336

◆ ProcessInvokes()

DLLEXPORT void Engine::ProcessInvokes ( )
protected

Handles InvokeQueue.

Definition at line 1168 of file Engine.cpp.

1169 {
1170  RecursiveLock lock(InvokeLock);
1171 
1172  while(!InvokeQueue.empty()) {
1173 
1174  const auto& func = InvokeQueue.front();
1175 
1176  // Recursive mutex allows the invoke to call extra invokes
1177  func();
1178 
1179  InvokeQueue.pop_front();
1180  }
1181 }
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:19
std::list< std::function< void()> > InvokeQueue
Definition: Engine.h:379
RecursiveMutex InvokeLock
Definition: Engine.h:378

◆ Release()

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

Definition at line 536 of file Engine.cpp.

537 {
538  GUARD_LOCK();
539 
540  if(!forced)
541  LEVIATHAN_ASSERT(PreReleaseDone, "PreReleaseDone must be done before actual release!");
542 
543  // Force garbase collection //
544  if(MainScript)
546 
547  // Make windows clear their stored objects //
548  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
549 
550  AdditionalGraphicalEntities[i]->UnlinkAll();
551  }
552 
553  // Finally the main window //
554  if(GraphicalEntity1) {
555 
557  }
558 
559  // Destroy worlds //
560  {
561  Lock lock(GameWorldsLock);
562 
563  while(GameWorlds.size()) {
564 
565  GameWorlds[0]->Release();
566  GameWorlds.erase(GameWorlds.begin());
567  }
568  }
569 
570  if(_NetworkHandler)
572 
573  // Wait for tasks to finish //
574  if(!forced)
576 
577  // Destroy windows //
578  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
579 
581  }
582 
584 
586 
587 #ifdef LEVIATHAN_USES_LEAP
588  SAFE_RELEASEDEL(LeapData);
589 #endif
590 
591  // Console needs to be released before script release //
593 
594  _GameModuleLoader.reset();
595 
597 
598  // Save at this point (just in case it crashes before exiting) //
599  Logger::Get()->Save();
600 
601 
603 
606 
607  // If graphics aren't unregistered crashing will occur //
609 
610  // Stop threads //
612 
614 
616  // delete randomizer last, for obvious reasons //
618 
621 
622  // clears all running timers that might have accidentally been left running //
624 
625  // safe to delete this here //
627 
629 
630  Logger::Get()->Write("Goodbye cruel world!");
631 }
ScriptExecutor * MainScript
Definition: Engine.h:316
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:307
DataStore * Mainstore
Definition: Engine.h:314
IDFactory * IDDefaultInstance
Definition: Engine.h:335
NetworkHandler * _NetworkHandler
Definition: Engine.h:321
ScriptConsole * MainConsole
Definition: Engine.h:317
OutOfMemoryHandler * OutOMemory
Definition: Engine.h:320
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:310
DLLEXPORT void Save()
Definition: Logger.cpp:203
ThreadingManager * _ThreadingManager
Definition: Engine.h:322
#define SAFE_RELEASEDEL(x)
Definition: Define.h:139
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98
SoundDevice * Sound
Definition: Engine.h:313
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void UnlinkAll()
Definition: Window.cpp:289
FileSystem * MainFileHandler
Definition: Engine.h:318
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:342
Random * MainRandom
Definition: Engine.h:319
DLLEXPORT void UnregisterGraphics()
Must be called if MakeThreadsWorkWithOgre has been called, BEFORE releasing graphics.
#define SAFE_DELETE(x)
Definition: Define.h:147
Graphics * Graph
Definition: Engine.h:308
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:357
#define GUARD_LOCK()
Definition: ThreadSafe.h:111
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18
std::unique_ptr< GameModuleLoader > _GameModuleLoader
Definition: Engine.h:327
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311
EventHandler * MainEvents
Definition: Engine.h:315

◆ RenderFrame()

void Engine::RenderFrame ( )

Definition at line 954 of file Engine.cpp.

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

◆ ReportClosedWindow()

DLLEXPORT void Engine::ReportClosedWindow ( Window windowentity)

Removes an closed window from the engine.

Definition at line 1101 of file Engine.cpp.

1102 {
1103  windowentity->UnlinkAll();
1104 
1105  if(GraphicalEntity1 == windowentity) {
1106 
1108  return;
1109  }
1110 
1111  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1112 
1113  if(AdditionalGraphicalEntities[i] == windowentity) {
1114 
1117 
1118  return;
1119  }
1120  }
1121 
1122  // Didn't find the target //
1123  Logger::Get()->Error("Engine: couldn't find closing Window");
1124 }
Window * GraphicalEntity1
Definition: Engine.h:310
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void UnlinkAll()
Definition: Window.cpp:289
#define SAFE_DELETE(x)
Definition: Define.h:147
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311

◆ 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 1183 of file Engine.cpp.

1184 {
1185  if(!IsOnMainThread()) {
1186 
1187  Invoke(function);
1188 
1189  } else {
1190 
1191  function();
1192  }
1193 }
DLLEXPORT bool IsOnMainThread() const
Returns true if called on the main thread.
Definition: Engine.cpp:90
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1162

◆ SaveScreenShot()

DLLEXPORT void Engine::SaveScreenShot ( )

Definition at line 1016 of file Engine.cpp.

1017 {
1018  LEVIATHAN_ASSERT(!NoGui, "really shouldn't try to screenshot in text-only mode");
1019  GUARD_LOCK();
1020 
1021  const string fileprefix = MainFileHandler->GetDataFolder() + "Screenshots/Captured_frame_";
1022 
1023  GraphicalEntity1->SaveScreenShot(fileprefix);
1024 }
static DLLEXPORT std::string GetDataFolder()
Definition: FileSystem.cpp:198
Window * GraphicalEntity1
Definition: Engine.h:310
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98
DLLEXPORT void SaveScreenShot(const std::string &filename)
Definition: Window.cpp:957
FileSystem * MainFileHandler
Definition: Engine.h:318
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

◆ SetNoGUI()

void Leviathan::Engine::SetNoGUI ( )
inline

Definition at line 261 of file Engine.h.

262  {
263 
264  NoGui = true;
265  }

◆ Tick()

void Engine::Tick ( )

Definition at line 836 of file Engine.cpp.

837 {
838  // Always try to update networking //
839  {
840  Lock lock(NetworkHandlerLock);
841 
842  if(_NetworkHandler)
844  }
845 
846  // And handle invokes //
847  ProcessInvokes();
848 
849  GUARD_LOCK();
850 
851  if(PreReleaseWaiting) {
852 
853  PreReleaseWaiting = false;
854  PreReleaseDone = true;
855 
856  Logger::Get()->Info("Engine: performing final release tick");
857 
858 
859 
860  // Call last tick event //
861 
862  return;
863  }
864 
865  // Get the passed time since the last update //
866  auto CurTime = Time::GetTimeMs64();
867  TimePassed = (int)(CurTime - LastTickTime);
868 
869 
870  if((TimePassed < TICKSPEED)) {
871  // It's not tick time yet //
872  return;
873  }
874 
875 
877  TickCount++;
878 
879  // Update input //
880 #ifdef LEVIATHAN_USES_LEAP
881  if(LeapData)
882  LeapData->OnTick(TimePassed);
883 #endif
884 
885  if(!NoGui) {
886  // sound tick //
887  if(Sound)
889 
890  // update windows //
891  if(GraphicalEntity1)
893 
894  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
895 
897  }
898  }
899 
900 
901  // Update worlds //
902  {
903  Lock lock(GameWorldsLock);
904 
905  // This will also update physics //
906  auto end = GameWorlds.end();
907  for(auto iter = GameWorlds.begin(); iter != end; ++iter) {
908 
909  (*iter)->Tick(TickCount);
910  }
911  }
912 
913 
914  // Some dark magic here //
915  if(TickCount % 25 == 0) {
916  // update values
920  // TODO: having the max tick time of the past second, would also be nice
921 
922  if(!NoGui) {
923  // send updated rendering statistics //
925  }
926  }
927 
928  // Update file listeners //
931 
932  // Send the tick event //
933  if(MainEvents)
935 
936  // Call the default app tick //
938 
939  TickTime = (int)(Time::GetTimeMs64() - CurTime);
940 }
Class that represents a statically defined event.
Definition: Event.h:138
virtual DLLEXPORT void UpdateAllConnections()
RenderingStatistics * RenderTimer
Definition: Engine.h:307
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
DLLEXPORT void Tick(int PassedMs)
DLLEXPORT void CheckFileStatus()
Called by Engine to check are updated files available.
DataStore * Mainstore
Definition: Engine.h:314
NetworkHandler * _NetworkHandler
Definition: Engine.h:321
DLLEXPORT void ProcessInvokes()
Handles InvokeQueue.
Definition: Engine.cpp:1168
virtual DLLEXPORT void Tick(int mspassed)
Window * GraphicalEntity1
Definition: Engine.h:310
Data for EVENT_TYPE_ENGINE_TICK and all others that have only int data.
Definition: Event.h:122
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:22
bool PreReleaseWaiting
Definition: Engine.h:361
DLLEXPORT void Tick(int mspassed)
Called by Engine.
Definition: Window.cpp:294
static DLLEXPORT int64_t GetTimeMs64()
SoundDevice * Sound
Definition: Engine.h:313
DLLEXPORT void SetTicksBehind(int value)
Definition: DataStore.cpp:411
std::mutex NetworkHandlerLock
Mutex that is locked while NetworkHandler is used.
Definition: Engine.h:345
DLLEXPORT void CallEvent(Event *event)
ResourceRefreshHandler * _ResourceRefreshHandler
Definition: Engine.h:324
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
std::mutex GameWorldsLock
Mutex that is locked when changing the worlds.
Definition: Engine.h:342
int64_t LastTickTime
Definition: Engine.h:348
DLLEXPORT void ReportStats(DataStore *dstore)
DLLEXPORT void SetTickTime(int newval)
Definition: DataStore.cpp:405
bool PreReleaseDone
Set when PreRelease is called and Tick has happened.
Definition: Engine.h:357
#define GUARD_LOCK()
Definition: ThreadSafe.h:111
std::vector< std::shared_ptr< GameWorld > > GameWorlds
List of current worlds.
Definition: Engine.h:339
DLLEXPORT void SetTickCount(int newval)
Definition: DataStore.cpp:399
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18
std::vector< Window * > AdditionalGraphicalEntities
Definition: Engine.h:311
EventHandler * MainEvents
Definition: Engine.h:315
LeviathanApplication * Owner
Definition: Engine.h:336

Member Data Documentation

◆ _ConsoleInput

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

Definition at line 326 of file Engine.h.

◆ _GameModuleLoader

std::unique_ptr<GameModuleLoader> Leviathan::Engine::_GameModuleLoader
protected

Definition at line 327 of file Engine.h.

◆ _NetworkHandler

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

Definition at line 321 of file Engine.h.

◆ _RemoteConsole

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

Definition at line 323 of file Engine.h.

◆ _ResourceRefreshHandler

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

Definition at line 324 of file Engine.h.

◆ _ThreadingManager

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

Definition at line 322 of file Engine.h.

◆ AdditionalGraphicalEntities

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

Definition at line 311 of file Engine.h.

◆ Define

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

Definition at line 305 of file Engine.h.

◆ FrameCount

int Leviathan::Engine::FrameCount = 0
protected

Definition at line 354 of file Engine.h.

◆ FrameLimit

int Leviathan::Engine::FrameLimit = 0
protected

Definition at line 351 of file Engine.h.

◆ GameWorlds

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

List of current worlds.

Definition at line 339 of file Engine.h.

◆ GameWorldsLock

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

Mutex that is locked when changing the worlds.

Definition at line 342 of file Engine.h.

◆ Graph

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

Definition at line 308 of file Engine.h.

◆ GraphicalEntity1

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

Definition at line 310 of file Engine.h.

◆ IDDefaultInstance

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

Definition at line 335 of file Engine.h.

◆ instance

DLLEXPORT Engine * Engine::instance = nullptr
staticprotected

Definition at line 391 of file Engine.h.

◆ InvokeLock

RecursiveMutex Leviathan::Engine::InvokeLock
protected

Definition at line 378 of file Engine.h.

◆ InvokeQueue

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

Definition at line 379 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 371 of file Engine.h.

◆ LastTickTime

int64_t Leviathan::Engine::LastTickTime
protected

Definition at line 348 of file Engine.h.

◆ MainConsole

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

Definition at line 317 of file Engine.h.

◆ MainEvents

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

Definition at line 315 of file Engine.h.

◆ MainFileHandler

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

Definition at line 318 of file Engine.h.

◆ MainRandom

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

Definition at line 319 of file Engine.h.

◆ MainScript

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

Definition at line 316 of file Engine.h.

◆ Mainstore

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

Definition at line 314 of file Engine.h.

◆ NetworkHandlerLock

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

Mutex that is locked while NetworkHandler is used.

Definition at line 345 of file Engine.h.

◆ NoGui

bool Leviathan::Engine::NoGui = false
protected

Definition at line 364 of file Engine.h.

◆ NoLeap

bool Leviathan::Engine::NoLeap = false
protected

Definition at line 365 of file Engine.h.

◆ NoSTDInput

bool Leviathan::Engine::NoSTDInput = false
protected

Definition at line 366 of file Engine.h.

◆ OpenedEditors

std::vector<std::unique_ptr<Editor::Editor> > Leviathan::Engine::OpenedEditors
protected

Definition at line 328 of file Engine.h.

◆ OutOMemory

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

Definition at line 320 of file Engine.h.

◆ Owner

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

Definition at line 336 of file Engine.h.

◆ PassedCommands

std::vector<std::unique_ptr<std::string> > Leviathan::Engine::PassedCommands
protected
Todo:
Remove this doesn't work now and needs redoing

Definition at line 383 of file Engine.h.

◆ PreReleaseCompleted

bool Leviathan::Engine::PreReleaseCompleted = false
protected

Definition at line 374 of file Engine.h.

◆ PreReleaseDone

bool Leviathan::Engine::PreReleaseDone = false
protected

Set when PreRelease is called and Tick has happened.

Definition at line 357 of file Engine.h.

◆ PreReleaseWaiting

bool Leviathan::Engine::PreReleaseWaiting = false
protected

Set when PreRelease called and waiting for Tick see PreReleaseDone

Definition at line 361 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 386 of file Engine.h.

◆ QueuedImports

std::vector<std::unique_ptr<Editor::Importer> > Leviathan::Engine::QueuedImports
protected

Queued importers from command line parsing.

Definition at line 389 of file Engine.h.

◆ RenderTimer

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

Definition at line 307 of file Engine.h.

◆ Sound

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

Definition at line 313 of file Engine.h.

◆ TickCount

int Leviathan::Engine::TickCount = 0
protected

Definition at line 352 of file Engine.h.

◆ TickTime

int Leviathan::Engine::TickTime = 0
protected

Definition at line 353 of file Engine.h.

◆ TimePassed

int Leviathan::Engine::TimePassed = 0
protected

Definition at line 350 of file Engine.h.


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