www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A question of function design?

reply WhatMeWorry <kheaser gmail.com> writes:
I'm using Derelict GLFW3 and I found the following GLFW3 code 
snippet in a demo.


float distance = 3.0;

extern(C) void key_callback(GLFWwindow* window, int key, int 
scancode, int action, int modifier) nothrow
{
     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
     {
         glfwSetWindowShouldClose(window, GL_TRUE);
     }
     if (key == GLFW_KEY_TAB && action == GLFW_PRESS)
     {
         distance = distance + .25;
     }
}


I'm looking at the call back function and all but one of the 
parameters are pass by values and there is no return type.  So 
they use this distance variable (is this called a global 
variable?) which I thought was considered bad programing and the 
classical example of a side-effect.  Isn't this particularly 
dangerous as programs get larger and larger.

So given the way this function was designed, how is a programmer 
supposed to convey information to the outside world?  Do I just 
suck it up?

I looked at D code projects using this function on git hub, but 
stuff there was either either like this or too complex.
Oct 27 2016
parent reply pineapple <meapineapple gmail.com> writes:
On Thursday, 27 October 2016 at 22:17:35 UTC, WhatMeWorry wrote:
 I'm using Derelict GLFW3 and I found the following GLFW3 code 
 snippet in a demo.
In a small demo, crap like this usually isn't a big deal. It's not common practice, though, and for good reason. You should definitely avoid imitating it.
Oct 27 2016
parent reply WhatMeWorry <kheaser gmail.com> writes:
On Thursday, 27 October 2016 at 22:51:13 UTC, pineapple wrote:
 On Thursday, 27 October 2016 at 22:17:35 UTC, WhatMeWorry wrote:
 I'm using Derelict GLFW3 and I found the following GLFW3 code 
 snippet in a demo.
In a small demo, crap like this usually isn't a big deal. It's not common practice, though, and for good reason. You should definitely avoid imitating it.
Anyone have a good example of what I should be doing?
Oct 28 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 28 October 2016 at 13:19:19 UTC, WhatMeWorry wrote:

 Anyone have a good example of what I should be doing?
I generally use GLFW event callbacks to populate an event queue with custom event types, then process the queue and handle events elsewhere. That way, the callbacks need no nothing at all about the game code. ``` void setCallbacks() { glfwSetKeyCallback(&key_callback); } private: MyEventQueue _eventq; extern(C) void key_callback(GLFWwindow* window, int key, int scancode, int action, int modifier) { eventq.push(KeyEvent(window, key, scancode, action, modifier); } An alternative approach is to forego the event queue and just have the callbacks process event listeners. The listeners could be delegates, function pointers, or interfaces, whatever works for your scenario, or some specific event handler class. They might be stored in flat arrays, or aas keyed on the window or a KeyEvent structure. Whatever works. ``` alias KeyHandler = bool delegate(GLFWwindow, int, int, int, int); void registerKeyHandler(KeyHandler handler) { _keyHandlers ~= handler; } private: KeyHandler[] _keyHandlers; extern(C) void key_callback(GLFWwindow* window, int key, int scancode, int action, int modifier) { foreach(handler; _keyHandlers) { if(_keyHandler(window, key, scancode, action, modifier)) break; } } ```
Oct 28 2016
parent WhatMeWorry <kheaser gmail.com> writes:
On Friday, 28 October 2016 at 14:12:53 UTC, Mike Parker wrote:
 On Friday, 28 October 2016 at 13:19:19 UTC, WhatMeWorry wrote:

 [...]
I generally use GLFW event callbacks to populate an event queue with custom event types, then process the queue and handle events elsewhere. That way, the callbacks need no nothing at all about the game code. [...]
Thanks! I'll study this code. I guess APIs can only give you so much.
Oct 28 2016