1 /**
2 *	Initialization and error handling.
3 */
4 module glfw3d.Main;
5 
6 import std.experimental.logger;
7 version(Have_derelict_glfw3) {
8 	import derelict.glfw3.glfw3;
9 } else {
10 	import glfw3d.glfw3;
11 }
12 import std.string : fromStringz;
13 
14 shared static this() {
15 	glfw3dLogger = sharedLog;
16 	version(Have_derelict_glfw3) {
17 		DerelictGLFW3.load();
18 	}
19 }
20 
21 /**
22 *	Logger for glfw3d
23 */
24 __gshared Logger glfw3dLogger;
25 
26 /**
27 *	`true` if any error happened
28 */
29 __gshared bool glfw3dErrorHappened = false;
30 
31 /**
32 *	Terminates glfw3d
33 */
34 alias glfw3dTerminate = glfwTerminate;
35 
36 /**
37 *	glfw3d throws this exception on errors
38 */
39 class glfw3dException : Exception {
40 	pure nothrow @nogc @safe this(string msg,
41 		string file = __FILE__,
42 		size_t line = __LINE__,
43 		Throwable next = null) {
44 			super(msg, file, line, next);
45 	}
46 }
47 
48 /**
49 *	Returns GLFW version
50 *	Returns: [Major, Minor, Rev]
51 */
52 int[3] glfw3dVersion() {
53 	int major, minor, rev;
54 	glfwGetVersion(&major, &minor, &rev);
55 	return [major, minor, rev];
56 }
57 
58 /**
59 *	Returns: GLFW version string
60 */
61 string glfw3dVersionString() {
62 	return cast(string) glfwGetVersionString().fromStringz;
63 }
64 
65 private extern(C) nothrow void glfw3dErrorCallback(int error, const(char)* desc) {
66 	template Error(string e) {
67 		import std.string : fromStringz;
68 		const char[] Error =
69 		"case GLFW_" ~ e ~ ":" ~
70 		"glfw3dErrorHappened = true; try {glfw3dLogger.log(\"GLFW error: \", desc.fromStringz);} catch(Throwable) {} break;";
71 	}
72 
73 	switch(error) {
74 		mixin(Error!("VERSION_UNAVAILABLE"));
75 		mixin(Error!("NO_CURRENT_CONTEXT"));
76 		mixin(Error!("FORMAT_UNAVAILABLE"));
77 		version(Have_derelict_glfw3) {
78 
79 		} else {
80 			mixin(Error!("NO_WINDOW_CONTEXT"));
81 		}
82 		mixin(Error!("NOT_INITIALIZED"));
83 		mixin(Error!("API_UNAVAILABLE"));
84 		mixin(Error!("PLATFORM_ERROR"));
85 		mixin(Error!("INVALID_VALUE"));
86 		mixin(Error!("OUT_OF_MEMORY"));
87 		mixin(Error!("INVALID_ENUM"));
88 
89 		default:
90 			try {glfw3dLogger.log("GLFW error: unknown");} catch(Throwable) {}
91 			break;
92 	}
93 }
94 
95 /**
96 *	Initializes glfw3d
97 *	Throws: glfw3dException on error
98 *	Params:
99 *		l = logger for glfw3d
100 */
101 void glfw3dInit(Logger l) {
102 	glfw3dLogger = l;
103 	glfw3dInit();
104 }
105 /// ditto
106 void glfw3dInit() {
107 	if(!glfwInit()) {
108 		glfw3dTerminate();
109 		throw new glfw3dException("GLFW initialization failed");
110 	}
111 	glfwSetErrorCallback(&glfw3dErrorCallback);
112 }