Leviathan  0.8.0.0
Leviathan game engine
Application.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
2 #include "Application.h"
3 
4 #include "FileSystem.h"
5 
6 #include <iostream>
7 
8 using namespace Leviathan;
9 // ------------------------------------ //
11 {
12  Curapp = this;
13 }
14 
17  ExternalEngineInstance(true), _Engine(engine)
18 {
19  LEVIATHAN_ASSERT(_Engine, "no engine pointer given");
20  Curapp = this;
21 }
22 
24 {
25  // Release should have been called when exiting the main loop
28  _Engine = nullptr;
29  Curapp = nullptr;
30 }
31 
33 {
34  return Curapp;
35 }
36 
38 // ------------------------------------ //
40 {
41  GUARD_LOCK();
42 
43  // Store configuration //
44  ApplicationConfiguration = configuration;
45 
46  // Init engine //
47  if(!_Engine->Init(
49  return false;
50 
51  _InternalInit();
52  return true;
53 }
54 
56 {
57  {
58  GUARD_LOCK();
59  // set as quitting //
60  Quit = true;
61 
62  // Nothing else to do if no engine //
63  if(!_Engine)
64  return;
65 
66  // Shutdown the packet handler
67  // PreRelease should have been done at this point and the NetworkHandler
68  // should have been released so this can no longer be in use
70  }
71 
72  // This avoids deadlocking //
73  _Engine->Release();
74 
75  {
76  GUARD_LOCK();
77  // Delete the already released engine //
78  delete _Engine;
79  _Engine = NULL;
80  }
81 }
82 
84 {
85  GUARD_LOCK();
86  ShouldQuit = true;
87 
88  // Tell Engine to expect a Release soon //
90 }
91 // ------------------------------------ //
93 {
94  GUARD_LOCK();
95  ShouldQuit = true;
96  Quit = true;
97 
98  if(_Engine) {
99  // The prelease does some which requires a tick //
100  _Engine->PreRelease();
101  _Engine->Tick();
102  _Engine->Release(true);
103  }
104 
106 }
107 // ------------------------------------ //
108 DLLEXPORT bool LeviathanApplication::PassCommandLine(int argcount, char* args[])
109 {
110  return _Engine->PassCommandLine(argcount, args);
111 }
112 
114 // ------------------------------------ //
116 {
117  _Engine->RenderFrame();
118 }
119 
121 // ------------------------------------ //
123 {
124  // This is almost at tick so call this outside the loop for performance //
126  PreFirstTick();
127 
128  // For reporting wait failures //
129  int FailCount = 0;
130 
131  while(!_Engine->HasPreReleaseBeenDone()) {
132  // Store this //
133  bool canprocess = _Engine->GetWindowOpenCount() != 0;
134 
135  _Engine->MessagePump();
136 
137  // Set as quitting //
138  if((!canprocess || QuitSometime) && !ShouldQuit) {
139  Logger::Get()->Info("Application: starting real close");
140  StartRelease();
141  }
142 
143  // engine tick //
144  _Engine->Tick();
145 
146  if(ShouldQuit || Quit) {
147  // We need to have done a proper run after calling StartRelease //
148  continue;
149  }
150 
151  Render();
152 
153  // We could potentially wait here //
156  try {
157  std::this_thread::sleep_for(std::chrono::milliseconds(1));
158  } catch(...) {
159  FailCount++;
160  }
161  }
162 
163  // Report problems //
164  if(FailCount)
165  std::cout << "Application main loop sleep fails: " << FailCount << std::endl;
166 
167  // always release before quitting to avoid tons of memory leaks //
168  Release();
169 
170  return 0;
171 }
172 // ------------------------------------ //
174 {
175 
176  _Engine->ClearTimers();
177 }
178 // ------------------ Default callbacks that do nothing ------------------ //
180 {
181 
182  return true;
183 }
184 
186 
188 
190 
191 DLLEXPORT std::shared_ptr<GameWorld> LeviathanApplication::GetGameWorld(int id)
192 {
193 
194  return nullptr;
195 }
196 
197 
199  GameConfiguration* configobj)
200 {}
201 
203  KeyConfiguration* keyconfigobj)
204 {}
205 
207 {
208  QuitSometime = true;
209 }
210 // ------------------------------------ //
212  const std::string& processname, const std::string& commandline)
213 {
214 
215 #ifdef _WIN32
216  // Create needed info //
217  STARTUPINFOA processstart;
218  PROCESS_INFORMATION startedinfo;
219 
220  ZeroMemory(&processstart, sizeof(STARTUPINFOA));
221  ZeroMemory(&startedinfo, sizeof(PROCESS_INFORMATION));
222 
223  processstart.cb = sizeof(STARTUPINFOA);
224  // processstart.dwFlags = STARTF_FORCEOFFFEEDBACK;
225  // processstart.wShowWindow = SW_SHOWMINIMIZED;
226 
227  std::string finalstart = "\"" + processname + "\" " + commandline;
228 
229  // Use windows process creation //
230  if(!CreateProcessA(NULL, const_cast<char*>(finalstart.c_str()), NULL, NULL, FALSE, 0, NULL,
231  NULL, &processstart, &startedinfo)) {
232  // Failed to start the process
233  Logger::Get()->Error("Failed to start the server process, error code: " +
234  Convert::ToString(GetLastError()));
235  return;
236  }
237 
238  // Close our handles //
239  CloseHandle(startedinfo.hThread);
240  DEBUG_BREAK;
241  // ServerProcessHandle = startedinfo.hProcess;
242 
243 
244 #else
245  // Popen should work //
246 
247  // Actually fork might be simpler //
248  if(fork() == 0) {
249  // We are now in the child process //
250 
251  execl(processname.c_str(), commandline.c_str(), (char*)NULL);
252  }
253 
254 
255 #endif // _WIN32
256 }
DLLEXPORT void PreRelease()
Sets objects ready to be released.
Definition: Engine.cpp:473
DLLEXPORT void ClearTimers()
Clears physical timers.
Definition: Engine.cpp:1251
virtual DLLEXPORT void EnginePreShutdown()
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
Holds key configuration for an application.
static DLLEXPORT void DummyGameConfigurationVariables(GameConfiguration *configobj)
static LeviathanApplication * Curapp
Definition: Application.h:130
virtual NetworkInterface * _GetApplicationPacketHandler()=0
Called in Initialize to get the derived packet handler type.
DLLEXPORT bool HasPreReleaseBeenDone() const
Checks if PreRelease is done and Release can be called.
Definition: Engine.h:57
virtual DLLEXPORT int RunMessageLoop()
virtual DLLEXPORT NETWORKED_TYPE GetProgramNetType() const =0
virtual DLLEXPORT void _InternalInit()
virtual DLLEXPORT void Tick(int mspassed)
DLLEXPORT bool Init(AppDef *definition, NETWORKED_TYPE ntype, NetworkInterface *packethandler)
Definition: Engine.cpp:95
The main class of the Leviathan Game Engine.
Definition: Engine.h:34
virtual DLLEXPORT std::shared_ptr< GameWorld > GetGameWorld(int id)
Used to query a world for specific id.
DLLEXPORT void ForceRelease()
Used to immediately terminate the program.
Definition: Application.cpp:92
virtual DLLEXPORT void PreFirstTick()
virtual DLLEXPORT bool Initialize(AppDef *configuration)
Definition: Application.cpp:39
DLLEXPORT void PreFirstTick()
Definition: Engine.cpp:942
virtual DLLEXPORT ~LeviathanApplication()
Definition: Application.cpp:23
DLLEXPORT int GetWindowOpenCount()
Definition: Engine.cpp:1026
DLLEXPORT void MarkAsClosing()
Thread safely marks the game to close sometime.
virtual DLLEXPORT bool PassCommandLine(int argcount, char *args[])
virtual DLLEXPORT void Release()
Performs the final steps in the release process.
Definition: Application.cpp:55
virtual DLLEXPORT bool InitLoadCustomScriptTypes(asIScriptEngine *engine)
DLLEXPORT void ClearTimers()
Resets all time sensitive timers.
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT void DummyGameKeyConfigVariables(KeyConfiguration *keyconfigobj)
DLLEXPORT void MessagePump()
Processes queued messages from Ogre, SDL and input.
Definition: Engine.cpp:633
virtual DLLEXPORT void StartRelease()
Safely releases the Application //.
Definition: Application.cpp:83
static DLLEXPORT void StartServerProcess(const std::string &processname, const std::string &commandline)
DLLEXPORT void RenderFrame()
Definition: Engine.cpp:954
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
static DLLEXPORT LeviathanApplication * Get()
Definition: Application.cpp:32
DLLEXPORT void Tick()
Definition: Engine.cpp:836
virtual void _ShutdownApplicationPacketHandler()=0
#define DLLEXPORT
Definition: Include.h:84
Base class for all leviathan programs.
Definition: Application.h:16
virtual DLLEXPORT void CustomizeEnginePostLoad()
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
#define SAFE_DELETE(x)
Definition: Define.h:147
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
DLLEXPORT bool PassCommandLine(int argcount, char *args[])
Definition: Engine.cpp:1342
#define GUARD_LOCK()
Definition: ThreadSafe.h:111
bool QuitSometime
This can be quickly set anywhere to quit sometime in the future.
Definition: Application.h:121
DLLEXPORT void Release(bool forced=false)
Definition: Engine.cpp:536
virtual DLLEXPORT void Render()