6 #define GLFW_INCLUDE_NONE
7 #include <GLFW/glfw3.h>
10 #define GLFW_EXPOSE_NATIVE_WIN32
11 #include <GLFW/glfw3native.h>
22 #if defined(__APPLE__)
23 #include <Carbon/Carbon.h>
26 #if !defined(_MSC_VER)
60 using std::shared_ptr;
84 Renderer* Application::renderer =
nullptr;
87 int64_t Application::timeLast = -1L;
88 bool Application::limitFPS =
true;
90 GLFWwindow* Application::glfwWindow =
nullptr;
91 array<unsigned int, 10> Application::glfwMouseButtonDownFrames;
92 int Application::glfwMouseButtonLast = -1;
93 bool Application::glfwCapsLockEnabled =
false;
94 GLFWcursor* Application::glfwHandCursor =
nullptr;
98 string Application::execute(
const string& command) {
100 array<char, 128> buffer;
102 #if defined(_MSC_VER)
103 shared_ptr<FILE> pipe(_popen(command.c_str(),
"r"), _pclose);
105 shared_ptr<FILE> pipe(popen(command.c_str(),
"r"), pclose);
107 if (!pipe)
throw std::runtime_error(
"popen() failed!");
108 while (!feof(pipe.get())) {
109 if (fgets(buffer.data(), buffer.size(), pipe.get()) !=
nullptr)
110 result += buffer.data();
117 system((
"start " + command).c_str());
119 system((command +
" </dev/null &>/dev/null &").c_str());
125 execute(
"explorer \"" + url +
"\"");
126 #elif defined(__APPLE__) || defined(__HAIKU__)
127 execute(
"open \"" + url +
"\"");
129 execute(
"xdg-open \"" + url +
"\"");
134 glfwSetWindowShouldClose(
glfwWindow, GLFW_FALSE);
146 glfwSetWindowShouldClose(
glfwWindow, GLFW_TRUE);
152 LONG WINAPI windowsExceptionHandler(
struct _EXCEPTION_POINTERS* exceptionInfo) {
162 HANDLE process = GetCurrentProcess();
163 HANDLE thread = GetCurrentThread();
165 vector<string> backtraceLines;
166 auto backtraceHeaderLine =
"windowsExceptionHandler(): process " + to_string((uint64_t)process) +
" crashed: Printing stacktrace(thread " + to_string((uint64_t)thread) +
")";
167 Console::println(backtraceHeaderLine);
168 backtraceLines.push_back(backtraceHeaderLine);
170 CHAR _pathToExecutable[MAX_PATH];
171 GetModuleFileName(GetModuleHandleW(NULL), _pathToExecutable, MAX_PATH);
172 string pathToExecutable = _pathToExecutable;
174 #if defined(_MSC_VER) == false
175 auto addr2lineToolCmd = StringTools::substring(pathToExecutable, 0, StringTools::lastIndexOf(pathToExecutable,
'\\')) +
"\\addr2line.exe";
176 if (FileSystem::getInstance()->fileExists(addr2lineToolCmd) ==
false) {
177 Console::println(
"handler(): " + addr2lineToolCmd +
": not found! Please copy addr2line utility to binary location!");
187 return EXCEPTION_EXECUTE_HANDLER;
189 addr2lineToolCmd =
"\"" + StringTools::replace(addr2lineToolCmd,
"\\",
"\\\\") +
"\"";
192 auto backtraceExecutableLine =
"windowsExceptionHandler(): path to executable: " + pathToExecutable;
193 Console::println(backtraceExecutableLine);
194 backtraceLines.push_back(backtraceExecutableLine);
196 pathToExecutable = string(
"\"") + StringTools::replace(pathToExecutable,
"\\",
"\\\\") +
"\"";
201 SYMOPT_OMAP_FIND_NEAREST |
202 SYMOPT_DEFERRED_LOADS |
212 STACKFRAME64 stackFrame;
213 memset(&stackFrame, 0,
sizeof(STACKFRAME64));
216 memset(&context, 0,
sizeof(context));
217 context.ContextFlags = CONTEXT_FULL;
218 RtlCaptureContext(&context);
222 image = IMAGE_FILE_MACHINE_I386;
223 stackFrame.AddrPC.Offset = context.Eip;
224 stackFrame.AddrPC.Mode = AddrModeFlat;
225 stackFrame.AddrFrame.Offset = context.Ebp;
226 stackFrame.AddrFrame.Mode = AddrModeFlat;
227 stackFrame.AddrStack.Offset = context.Esp;
228 stackFrame.AddrStack.Mode = AddrModeFlat;
230 image = IMAGE_FILE_MACHINE_AMD64;
231 stackFrame.AddrPC.Offset = context.Rip;
232 stackFrame.AddrPC.Mode = AddrModeFlat;
233 stackFrame.AddrFrame.Offset = context.Rsp;
234 stackFrame.AddrFrame.Mode = AddrModeFlat;
235 stackFrame.AddrStack.Offset = context.Rsp;
236 stackFrame.AddrStack.Mode = AddrModeFlat;
238 image = IMAGE_FILE_MACHINE_IA64;
239 stackFrame.AddrPC.Offset = context.StIIP;
240 stackFrame.AddrPC.Mode = AddrModeFlat;
241 stackFrame.AddrFrame.Offset = context.IntSp;
242 stackFrame.AddrFrame.Mode = AddrModeFlat;
243 stackFrame.AddrBStore.Offset = context.RsBSP;
244 stackFrame.AddrBStore.Mode = AddrModeFlat;
245 stackFrame.AddrStack.Offset = context.IntSp;
246 stackFrame.AddrStack.Mode = AddrModeFlat;
248 #error "Machine not supported"
253 while (StackWalk64(image, process, thread, &stackFrame, &context, NULL, &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
254 if (stackFrame.AddrPC.Offset == stackFrame.AddrReturn.Offset)
break;
255 if (stackFrame.AddrPC.Offset == 0)
continue;
258 char _fileName[1024];
259 char _functionName[1024];
263 #define cnBufferSize 1024
264 unsigned char byBuffer[
sizeof(IMAGEHLP_SYMBOL64) + cnBufferSize];
265 IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer;
266 DWORD64 dwDisplacement;
267 memset(pSymbol, 0,
sizeof(IMAGEHLP_SYMBOL64) + cnBufferSize);
268 pSymbol->SizeOfStruct =
sizeof(IMAGEHLP_SYMBOL64);
269 pSymbol->MaxNameLength = cnBufferSize;
270 if (!SymGetSymFromAddr64(process, stackFrame.AddrPC.Offset, &dwDisplacement, pSymbol)) {
271 strcpy(_functionName,
"??");
273 pSymbol->Name[cnBufferSize-1] =
'\0';
274 strcpy(_functionName, pSymbol->Name);
280 IMAGEHLP_LINE64 theLine;
281 DWORD dwDisplacement;
282 memset(&theLine, 0,
sizeof(theLine));
283 theLine.SizeOfStruct =
sizeof(theLine);
284 if(!SymGetLineFromAddr64(process, stackFrame.AddrPC.Offset, &dwDisplacement, &theLine))
286 strcpy(_fileName,
"??");
290 const char* pszFile = strrchr(theLine.FileName,
'\\');
291 if (!pszFile) pszFile = theLine.FileName;
else ++pszFile;
292 strncpy(_fileName, pszFile, cnBufferSize);
293 line = theLine.LineNumber;
298 string functionName = _functionName;
299 string fileName = _fileName;
300 #if defined(_MSC_VER) == false
301 if (functionName ==
"??") {
303 Hex::encodeInt(stackFrame.AddrPC.Offset, hexAddr);
304 string addr2LineCommand =
"\"" + addr2lineToolCmd +
" -f -p -e " + string(pathToExecutable) +
" " + hexAddr +
"\"";
309 auto addr2lineFunctionName = t.
nextToken();
310 addr2LineOutput = StringTools::replace(StringTools::replace(addr2LineOutput, addr2lineFunctionName, RTTI::demangle(addr2lineFunctionName.c_str())),
"\n",
"");
312 auto backtraceLine = to_string(frameIdx) +
": " + addr2LineOutput;
313 Console::println(backtraceLine);
314 backtraceLines.push_back(backtraceLine);
316 auto backtraceLine = to_string(frameIdx) +
": " + string(RTTI::demangle(_functionName)) +
" at " + fileName +
":" + to_string(line);
317 Console::println(backtraceLine);
318 backtraceLines.push_back(backtraceLine);
321 Console::println(to_string(frameIdx) +
": " + functionName +
" at " + fileName +
":" + to_string(line));
327 FileSystem::getInstance()->setContentFromStringArray(
".",
"crash.log", backtraceLines);
339 return EXCEPTION_EXECUTE_HANDLER;
352 Engine::getRenderer()->setVSync(vSync);
353 if (Engine::getRenderer()->getRendererType() != Renderer::RENDERERTYPE_VULKAN) {
354 glfwSwapInterval(vSync ==
true?1:0);
359 #if defined(__FreeBSD__)
361 #elif defined(__HAIKU__)
363 #elif defined(__linux__)
365 #elif defined(__APPLE__)
367 #elif defined(__NetBSD__)
369 #elif defined(__OpenBSD__)
371 #elif defined(_MSC_VER)
372 return "Windows-MSC";
373 #elif defined(_WIN32)
374 return "Windows-MINGW";
381 #if defined(__amd64__) || defined(_M_X64)
383 #elif defined(__ia64__) || defined(_M_IA64)
385 #elif defined(__aarch64__)
387 #elif defined(__arm__) || defined(_M_ARM)
389 #elif defined(__powerpc64__)
391 #elif defined(__powerpc__)
399 setlocale(LC_ALL, locale.c_str());
408 return GetActiveWindow() == GetForegroundWindow();
463 auto windowMonitor = glfwGetWindowMonitor(
glfwWindow);
464 if (windowMonitor ==
nullptr &&
fullScreen ==
true) {
465 auto monitor = glfwGetPrimaryMonitor();
466 auto mode = glfwGetVideoMode(monitor);
467 glfwSetWindowMonitor(
glfwWindow, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
469 if (windowMonitor !=
nullptr &&
fullScreen ==
false) {
482 SetUnhandledExceptionFilter(windowsExceptionHandler);
489 glfwSetInputMode(
glfwWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
493 glfwSetInputMode(
glfwWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
497 glfwSetInputMode(
glfwWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
503 double mouseX, mouseY;
504 glfwGetCursorPos(
glfwWindow, &mouseX, &mouseY);
505 return static_cast<int>(mouseX);
509 double mouseX, mouseY;
510 glfwGetCursorPos(
glfwWindow, &mouseX, &mouseY);
511 return static_cast<int>(mouseY);
515 #if defined(__APPLE__)
516 int windowXPos, windowYPos;
519 point.x = windowXPos + x;
520 point.y = windowYPos + y;
521 CGWarpMouseCursorPosition(point);
522 CGAssociateMouseAndMouseCursorPosition(
true);
529 if (Engine::getRenderer()->getRendererType() != Renderer::RENDERERTYPE_VULKAN) glfwSwapBuffers(
glfwWindow);
533 return string(glfwGetClipboardString(
glfwWindow));
537 glfwSetClipboardString(
glfwWindow, content.c_str());
541 Console::println(
string(
"glfwErrorCallback(): ") + description);
545 string rendererLibrary =
"libopengl3corerenderer";
546 for (
auto i = 1; i < argc; i++) {
547 auto argValue = string(argv[i]);
549 if (argValue ==
"--gles2") rendererLibrary =
"libopengles2renderer";
else
550 if (argValue ==
"--gl2") rendererLibrary =
"libopengl2renderer";
else
551 if (argValue ==
"--gl3core") rendererLibrary =
"libopengl3corerenderer";
else
552 if (argValue ==
"--vulkan") rendererLibrary =
"libvulkanrenderer";
556 rendererLibrary = rendererLibrary +
".dll";
557 #elif defined(__APPLE__)
558 rendererLibrary = rendererLibrary +
".dylib";
560 rendererLibrary = rendererLibrary +
".so";
569 if (glfwInit() ==
false) {
570 Console::println(
"glflInit(): failed!");
583 GLFWmonitor* monitor = glfwGetPrimaryMonitor();
584 const GLFWvidmode* monitorMode = glfwGetVideoMode(monitor);
585 if (monitorMode !=
nullptr) {
588 glfwGetMonitorPos(monitor, &monitorX, &monitorY);
595 Console::println(
"Application::run(): Opening renderer library: " + rendererLibrary);
598 #if defined(_MSC_VER)
600 auto rendererLibraryHandle = LoadLibrary(rendererLibrary.c_str());
601 if (rendererLibraryHandle ==
nullptr) {
602 Console::println(
"Application::run(): Could not open renderer library");
607 Renderer* (*rendererCreateInstance)() = (
Renderer*(*)())GetProcAddress(rendererLibraryHandle,
"createInstance");
609 if (rendererCreateInstance ==
nullptr) {
610 Console::println(
"Application::run(): Could not find renderer library createInstance() entry point");
617 Console::println(
"Application::run(): Could not create renderer");
623 #if defined(__HAIKU__)
624 auto rendererLibraryHandle = dlopen((
"lib/" + rendererLibrary).c_str(), RTLD_NOW);
626 auto rendererLibraryHandle = dlopen(rendererLibrary.c_str(), RTLD_NOW);
628 if (rendererLibraryHandle ==
nullptr) {
629 Console::println(
"Application::run(): Could not open renderer library");
634 Renderer* (*rendererCreateInstance)() = (
Renderer*(*)())dlsym(rendererLibraryHandle,
"createInstance");
636 if (rendererCreateInstance ==
nullptr) {
637 Console::println(
"Application::run(): Could not find renderer library createInstance() entry point");
644 Console::println(
"Application::run(): Could not create renderer");
664 Console::println(
"glfwCreateWindow(): Could not create window");
671 Console::println(
"glfwCreateWindow(): Could not initialize window system renderer context");
697 #if defined(__APPLE__)
699 auto executablePathName = string(argv[0]);
700 if (executablePathName.find(
".app/Contents/MacOS/") != string::npos) {
701 auto appBundleName = StringTools::substring(executablePathName, 0, executablePathName.rfind(
".app") +
string(
".app").size());
702 auto workingPathName = StringTools::substring(appBundleName, 0, appBundleName.rfind(
'/'));
703 FileSystem::getStandardFileSystem()->changePath(workingPathName);
709 auto gameControllerDatabase = FileSystem::getInstance()->getContentAsString(
"resources/engine/misc",
"gamecontrollerdb.txt");
710 glfwUpdateGamepadMappings(gameControllerDatabase.c_str());
712 Console::println(
"An error occurred: " +
string(exception.what()));
716 for (
auto joystickIdx = GLFW_JOYSTICK_1; joystickIdx <= GLFW_JOYSTICK_16; joystickIdx++) {
721 while (glfwWindowShouldClose(
glfwWindow) ==
false) {
723 if (Engine::getRenderer()->getRendererType() != Renderer::RENDERERTYPE_VULKAN) glfwSwapBuffers(
glfwWindow);
734 Console::println(
"Application::run(): Shutting down application");
746 return localExitCode;
750 auto logoFileName = StringTools::replace(StringTools::toLowerCase(
executableFileName),
".exe",
"") +
"-icon.png";
751 if (FileSystem::getInstance()->exists(
"resources/platforms/icons/" + logoFileName) ==
false) logoFileName =
"default-icon.png";
752 auto texture = TextureReader::read(
"resources/platforms/icons", logoFileName,
false,
false);
753 if (texture !=
nullptr) {
754 auto textureData = texture->getRGBTextureData();
755 auto textureWidth = texture->getTextureWidth();
756 auto textureHeight = texture->getTextureHeight();
757 auto textureBytePerPixel = texture->getRGBDepthBitsPerPixel() == 32?4:3;
758 vector<uint8_t> glfwPixels(textureWidth * textureHeight * 4);
759 for (
auto y = 0; y < textureHeight; y++)
760 for (
auto x = 0; x < textureWidth; x++) {
761 glfwPixels[y * textureWidth * 4 + x * 4 + 0] = textureData.get(y * textureWidth * textureBytePerPixel + x * textureBytePerPixel + 0);
762 glfwPixels[y * textureWidth * 4 + x * 4 + 1] = textureData.get(y * textureWidth * textureBytePerPixel + x * textureBytePerPixel + 1);
763 glfwPixels[y * textureWidth * 4 + x * 4 + 2] = textureData.get(y * textureWidth * textureBytePerPixel + x * textureBytePerPixel + 2);
764 glfwPixels[y * textureWidth * 4 + x * 4 + 3] = textureBytePerPixel == 3?255:textureData.get(y * textureWidth * textureBytePerPixel + x * textureBytePerPixel + 3);
767 glfwIcon.width = texture->getTextureWidth();
768 glfwIcon.height = texture->getTextureHeight();
769 glfwIcon.pixels = glfwPixels.data();
771 texture->releaseReference();
782 int64_t timeNow = Time::getCurrentMillis();
785 int64_t timePassed = timeNow -
timeLast;
786 if (
limitFPS ==
true && timePassed < timeFrame) Thread::sleep(timeFrame - timePassed);
802 double mouseX, mouseY;
803 glfwGetCursorPos(window, &mouseX, &mouseY);
809 double mouseX, mouseY;
810 glfwGetCursorPos(window, &mouseX, &mouseY);
812 if (key == GLFW_KEY_CAPS_LOCK) {
813 if (action == GLFW_PRESS) {
817 if (action == GLFW_PRESS || action == GLFW_REPEAT) {
818 auto keyName = key == GLFW_KEY_SPACE?
" ":glfwGetKeyName(key, scanCode);
820 keyName ==
nullptr?-1:((mods & GLFW_MOD_SHIFT) == 0 &&
glfwCapsLockEnabled ==
false?Character::toLowerCase(keyName[0]):keyName[0]),
822 static_cast<int>(mouseX),
823 static_cast<int>(mouseY),
824 action == GLFW_REPEAT,
828 if (action == GLFW_RELEASE) {
829 auto keyName = key == GLFW_KEY_SPACE?
" ":glfwGetKeyName(key, scanCode);
831 keyName ==
nullptr?-1:((mods & GLFW_MOD_SHIFT) == 0 &&
glfwCapsLockEnabled ==
false?Character::toLowerCase(keyName[0]):keyName[0]),
850 double mouseX, mouseY;
851 glfwGetCursorPos(window, &mouseX, &mouseY);
853 if (action == GLFW_PRESS) {
863 double mouseX, mouseY;
864 glfwGetCursorPos(window, &mouseX, &mouseY);
878 Console::println(
"Application::glfwOnDrop(): " + to_string(count) +
" items have been dropped");
879 vector<string> pathsVector;
880 for (
auto i = 0; i < count; i++) {
881 Console::println(
"\t" +
string(paths[i]));
882 pathsVector.push_back(paths[i]);
890 if (event == GLFW_CONNECTED) {
891 if (glfwJoystickIsGamepad(joystickIdx) ==
true) {
892 Console::println(
"Application::glfwOnJoystickConnect(): connected gamepad with idx = " + to_string(joystickIdx) +
", name = " + glfwGetJoystickName(joystickIdx));
895 Console::println(
"Application::glfwOnJoystickConnect(): connected joystick with idx = " + to_string(joystickIdx) +
", name = " + glfwGetJoystickName(joystickIdx));
898 }
else if (event == GLFW_DISCONNECTED) {
899 Console::println(
"Application::glfwOnJoystickConnect(): disconnected joystick/gamepad with idx = " + to_string(joystickIdx));
913 double mouseX, mouseY;
914 glfwGetCursorPos(
glfwWindow, &mouseX, &mouseY);
915 GLFWgamepadstate gamepadState;
917 auto now = Time::getCurrentMillis();
920 if (gamepadState.buttons[buttonIdx] == GLFW_PRESS &&
926 if (gamepadState.buttons[buttonIdx] == GLFW_RELEASE &&
932 if (gamepadState.buttons[buttonIdx] == GLFW_PRESS &&
940 if (glfwGetGamepadState(joystickIdx, &gamepadState) ==
true) {
static void glfwErrorCallback(int error, const char *description)
#define MOUSE_CURSOR_HAND
#define MOUSE_CURSOR_ENABLED
#define MOUSE_CURSOR_DISABLED
Application base class, please make sure to allocate application on heap to have correct application ...
static void setMousePosition(int x, int y)
Set mouse position.
static STATIC_DLL_IMPEXT Renderer * renderer
static STATIC_DLL_IMPEXT int glfwMouseButtonLast
static void glfwOnMouseWheel(GLFWwindow *window, double x, double y)
GLFW on key.
static string getCPUName()
static string getOSName()
static constexpr int EXITCODE_FAILURE
static void executeBackground(const string &command)
Execute a command in background.
static STATIC_DLL_IMPEXT Application * application
static void swapBuffers()
Swap rendering buffers.
array< array< int64_t, 16 >, 16 > joystickButtons
void setIcon()
Set application icon.
virtual void reshape(int width, int height)=0
Resize.
static void glfwOnMouseMoved(GLFWwindow *window, double x, double y)
GLFW on mouse moved.
int run(int argc, char **argv, const string &title, InputEventHandler *inputEventHandler=nullptr, int windowHints=WINDOW_HINT_NONE)
Run this application.
int getWindowWidth() const
void setWindowXPosition(int windowXPosition)
Set window X position when initializing.
static void glfwOnClose(GLFWwindow *window)
GLFW on close.
string executableFileName
static void glfwOnWindowResize(GLFWwindow *window, int width, int height)
GLFW on window resize.
bool isFullScreen() const
static STATIC_DLL_IMPEXT array< unsigned int, 10 > glfwMouseButtonDownFrames
void setWindowYPosition(int windowYPosition)
Set window Y position when initializing.
static string execute(const string &command)
Execute a command and wait until it finished running.
void setClipboardContent(const string &content)
Set clipboard content.
static void glfwOnDrop(GLFWwindow *window, int count, const char **paths)
GLFW on drop.
static void displayInternal()
Display function.
static constexpr int64_t JOYSTICK_BUTTON_TIME_REPEAT
static void glfwOnChar(GLFWwindow *window, unsigned int key)
GLFW on char.
static void reshapeInternal(int width, int height)
Reshape function.
void setWindowWidth(int windowWidth)
Set window width.
static STATIC_DLL_IMPEXT bool limitFPS
void updateJoystickInput(int joystickIdx)
Update joystick input for given joystick index.
virtual ~Application()
Destructor.
static void cancelExit()
Cancels a users requested exit (ALT-F4 or X button)
int getWindowHeight() const
virtual void onClose()
On close.
static STATIC_DLL_IMPEXT bool glfwCapsLockEnabled
string getClipboardContent()
static void installExceptionHandler()
Windows only: Install exception handler that will print a stack trace if crashing.
virtual void display()=0
Display.
static STATIC_DLL_IMPEXT int64_t timeLast
void setFullScreen(bool fullScreen)
Set full screen mode.
static constexpr int WINDOW_HINT_MAXIMIZED
static STATIC_DLL_IMPEXT InputEventHandler * inputEventHandler
static int getMousePositionY()
static int getMousePositionX()
virtual void initialize()=0
Init.
static STATIC_DLL_IMPEXT int mouseCursor
static constexpr int WINDOW_HINT_NOTDECORATED
static constexpr int WINDOW_HINT_INVISIBLE
static void exit(int exitCode)
Exits this application with given exit code.
void updateGamepadInput(int gamepadIdx)
Update gamepad input for given gamepad index.
unordered_set< int > connectedGamepads
static STATIC_DLL_IMPEXT GLFWwindow * glfwWindow
static constexpr int WINDOW_HINT_NOTRESIZEABLE
unordered_set< int > connectedJoysticks
static void setVSyncEnabled(bool vSync)
Set vsync enabled.
void setWindowHeight(int windowHeight)
Set window height.
virtual void dispose()=0
Disposes.
static void glfwOnJoystickConnect(int joystickIdx, int event)
GLFW on joystick connect/disconnect.
static void glfwOnKey(GLFWwindow *window, int key, int scanCode, int action, int mods)
GLFW on key.
static void openBrowser(const string &url)
Open browser with given url.
void setInputEventHandler(InputEventHandler *inputEventHandler)
Set input event handler.
static void setLocale(const string &locale)
Set locale.
Application()
Public constructor.
static void glfwOnMouseButton(GLFWwindow *window, int button, int action, int mods)
GLFW on key.
static void setMouseCursor(int mouseCursor)
Set mouse cursor.
static STATIC_DLL_IMPEXT GLFWcursor * glfwHandCursor
virtual void onDrop(const vector< string > &paths)
On drop.
Interface to audio module.
virtual bool initializeWindowSystemRendererContext(GLFWwindow *glfwWindow)=0
Initialize window system renderer context.
virtual bool prepareWindowSystemRendererContext(int tryIdx)=0
Prepare window system renderer context.
File system singleton class.
Integer to hex string conversion utility class.
Run time type information utility class.
const string & nextToken()
void tokenize(const string &str, const string &delimiters, bool emptyTokens=false)
Tokenize.
std::exception Exception
Exception base class.