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

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

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

1260 {
1261  if(NoGui)
1262  return;
1263 
1264  // Register threads to use graphical objects //
1266 }
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 1597 of file Engine.cpp.

1598 {
1599  Invoke([=]() {
1600  if(MainConsole) {
1601 
1602  MainConsole->RunConsoleCommand(command);
1603 
1604  } else {
1605 
1606  LOG_WARNING("No console handler attached, cannot run command");
1607  }
1608  });
1609 
1610  // Listening thread quits if PreReleaseWaiting is true
1611  return PreReleaseWaiting;
1612 }
DLLEXPORT void Invoke(const std::function< void()> &function)
Runs function on the main thread before the next tick.
Definition: Engine.cpp:1164
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 1573 of file Engine.cpp.

1574 {
1575  if(QueuedConsoleCommands.empty())
1576  return;
1577 
1578  if(!MainConsole) {
1579 
1580  LOG_FATAL("Engine: MainConsole has not been created before running command line "
1581  "passed commands");
1582  return;
1583  }
1584 
1585  LOG_INFO("Engine: Running PostStartup command line. Commands: " +
1587 
1588  for(auto& command : QueuedConsoleCommands) {
1589 
1590  LOG_INFO("Engine: Running \"" + *command + "\"");
1591  MainConsole->RunConsoleCommand(*command);
1592  }
1593 
1594  QueuedConsoleCommands.clear();
1595 }
#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 1251 of file Engine.cpp.

1252 {
1253  Lock lock(GameWorldsLock);
1254 
1255  for(auto iter = GameWorlds.begin(); iter != GameWorlds.end(); ++iter) {
1256  }
1257 }
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 1089 of file Engine.cpp.

1090 {
1091  if(!window)
1092  return false;
1093 
1094  if(IsValidWindow(window)) {
1095 
1096  ReportClosedWindow(window);
1097  return true;
1098  } else {
1099  return false;
1100  }
1101 }
DLLEXPORT void ReportClosedWindow(Window *windowentity)
Removes an closed window from the engine.
Definition: Engine.cpp:1103
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 1197 of file Engine.cpp.

1200 {
1201  std::shared_ptr<GameWorld> world;
1202  if(worldtype >= 1024) {
1203  // Standard world types
1205  static_cast<INBUILT_WORLD_TYPE>(worldtype), physicsMaterials, overrideid);
1206  } else {
1207  world =
1208  GameWorldFactory::Get()->CreateNewWorld(worldtype, physicsMaterials, overrideid);
1209  }
1210 
1211  if(!world) {
1212 
1213  LOG_ERROR("Engine: CreateWorld: factory failed to create a world of type: " +
1214  std::to_string(worldtype));
1215  return nullptr;
1216  }
1217 
1218  world->Init(networking, NoGui ? nullptr : Graph);
1219 
1220  if(owningwindow)
1221  owningwindow->LinkObjects(world);
1222 
1223  Lock lock(GameWorldsLock);
1224 
1225  GameWorlds.push_back(world);
1226  return GameWorlds.back();
1227 }
#define LOG_ERROR(x)
Definition: Define.h:90
static DLLEXPORT GameWorldFactory * Get()
DLLEXPORT void LinkObjects(std::shared_ptr< GameWorld > world)
This function also updates the camera aspect ratio.
Definition: Window.cpp:256
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 1229 of file Engine.cpp.

1230 {
1231  if(!world)
1232  return;
1233 
1234  // Release the world first //
1235  world->Release();
1236 
1237  // Then delete it //
1238  Lock lock(GameWorldsLock);
1239 
1240  auto end = GameWorlds.end();
1241  for(auto iter = GameWorlds.begin(); iter != end; ++iter) {
1242 
1243  if((*iter).get() == world.get()) {
1244 
1245  GameWorlds.erase(iter);
1246  return;
1247  }
1248  }
1249 }
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 1485 of file Engine.cpp.

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

1148 {
1149  if(OpenedEditors.empty()) {
1150 
1151  OpenEditorWindow();
1152  return;
1153  }
1154 
1155  OpenedEditors.front()->BringToFront();
1156 }
DLLEXPORT void OpenEditorWindow(Window *useexistingwindow=nullptr)
Opens an Editor::Editor window.
Definition: Engine.cpp:1128
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 1274 of file Engine.cpp.

1275 {
1276 
1277  return TickCount;
1278 }

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

1269 {
1270 
1271  return Time::GetTimeMs64() - LastTickTime;
1272 }
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:904
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:242
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT bool Init(bool simulatesound=false, bool noconsolelog=false)
Definition: SoundDevice.cpp:26
#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:1597
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
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 1164 of file Engine.cpp.

1165 {
1166  RecursiveLock lock(InvokeLock);
1167  InvokeQueue.push_back(function);
1168 }
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 1158 of file Engine.cpp.

1159 {
1160  if(Owner)
1161  Owner->MarkAsClosing();
1162 }
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:1158
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:894
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:326
DLLEXPORT void InjectMouseButtonUp(const SDL_Event &event)
Definition: Window.cpp:1167
DLLEXPORT void OnResize(int width, int height)
Definition: Window.cpp:302
DLLEXPORT void InjectKeyDown(const SDL_Event &event)
Definition: Window.cpp:1200
Window * GraphicalEntity1
Definition: Engine.h:310
DLLEXPORT void InjectMouseMove(const SDL_Event &event)
Definition: Window.cpp:1095
DLLEXPORT void ReportClosedWindow(Window *windowentity)
Removes an closed window from the engine.
Definition: Engine.cpp:1103
DLLEXPORT void FocusOrOpenEditor()
Focuses the first editor or opens an editor if none are open.
Definition: Engine.cpp:1147
DLLEXPORT void InputEnd()
Translates a client space coordinate to screen coordinate.
Definition: Window.cpp:1038
DLLEXPORT void InjectKeyUp(const SDL_Event &event)
Definition: Window.cpp:1232
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:1150
DLLEXPORT void InjectCodePoint(const SDL_Event &event)
Injects text.
Definition: Window.cpp:1184
DLLEXPORT void InjectMouseWheel(const SDL_Event &event)
Definition: Window.cpp:1117
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 1128 of file Engine.cpp.

1129 {
1131 
1132  if(useexistingwindow && !IsValidWindow(useexistingwindow)) {
1133 
1134  LOG_WARNING("Engine: OpenEditorWindow: invalid window given, defaulting to opening a "
1135  "new window");
1136  useexistingwindow = nullptr;
1137  }
1138 
1139  if(!useexistingwindow) {
1140  useexistingwindow = OpenNewWindow();
1141  }
1142 
1143 
1144  OpenedEditors.emplace_back(std::make_unique<Editor::Editor>(useexistingwindow, this));
1145 }
#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  // yes, gamma
1074  true,
1075  // TODO: open on next display
1077 #ifdef _WIN32
1078  Define->GetWindowDetails().Icon,
1079 #endif
1080  nullptr));
1081 
1082  auto newwindow = std::make_unique<Window>(Graph, &winparams);
1083 
1084  AdditionalGraphicalEntities.push_back(newwindow.get());
1085 
1086  return newwindow.release();
1087 }
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 1342 of file Engine.cpp.

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

◆ 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:1158
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1251
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:1573
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:1485
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:1251
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 1170 of file Engine.cpp.

1171 {
1172  RecursiveLock lock(InvokeLock);
1173 
1174  while(!InvokeQueue.empty()) {
1175 
1176  const auto& func = InvokeQueue.front();
1177 
1178  // Recursive mutex allows the invoke to call extra invokes
1179  func();
1180 
1181  InvokeQueue.pop_front();
1182  }
1183 }
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:279
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:290
DLLEXPORT bool Frame()
Definition: Graphics.cpp:538
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 1103 of file Engine.cpp.

1104 {
1105  windowentity->UnlinkAll();
1106 
1107  if(GraphicalEntity1 == windowentity) {
1108 
1110  return;
1111  }
1112 
1113  for(size_t i = 0; i < AdditionalGraphicalEntities.size(); i++) {
1114 
1115  if(AdditionalGraphicalEntities[i] == windowentity) {
1116 
1119 
1120  return;
1121  }
1122  }
1123 
1124  // Didn't find the target //
1125  Logger::Get()->Error("Engine: couldn't find closing Window");
1126 }
Window * GraphicalEntity1
Definition: Engine.h:310
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void UnlinkAll()
Definition: Window.cpp:279
#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 1185 of file Engine.cpp.

1186 {
1187  if(!IsOnMainThread()) {
1188 
1189  Invoke(function);
1190 
1191  } else {
1192 
1193  function();
1194  }
1195 }
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:1164

◆ 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:955
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:1170
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:284
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: