-
design problem
I'm creating a gui api. I've run into a problem though that isn't easy to solve. Right now I use the following calls to receive messages :
Code:
gui_read_events();
//sees if there's a keyboard/mouse event and puts it in a list
while (gui_get_event(*event)){
handleEvents(*event);
}
//copies the first element of the list and removes it from the list.
I added functions for creating buttons and sliders etc...
Everything works as it should, but after implenting timer events, I get a problem. When eg a togglebutton is pushed, I go into a subloop untill the mouse is released. In that subloop, I use gui_read_events() and gui_get_event(). I check if there's a MOUSE_UP event and if there is one, I exit the subloop. The problem is that timer events aren't sent to the user of the gui library anymore because his code can't be reached from the subloop. I've thought a little over this, but I can't find the ideal solution.
Should I redisign the whole system or is there an easier solution that doesn't require to much time recodeing everything ?
I hope I've made myself clear.
-
Unfortunately, there is just not enough info in your post to provide a decent response. But I'll assume your OS is Windows.
WM_TIMER is nonpreemptive, meaning that they are given very low priority. If there are any other types of messages pending, the other messages will be processed first. Also, if multiple WM_TIMER messages are queued, only one message is processed. Thus, it is possible to have many WM_TIMER messages queued up but you will only process one WM_TIMER message.
It is possible that your code is not written to process all messages in an efficient manner.
To repeat myself, this is a "wild guess" response based upon the minimal information provided.
Bob
-
I'm not entirely clear on the code you have here. What is the type of the variable "event"? The reason I ask is because you're passing the thing pointed to by event by value to gui_get_event() and handleEvents(), and that only makes sense to me if event is a pointer to a pointer to some event structure.
Does handleEvents() deal with the timer events? When does gui_get_event() return 0? (I assume that it does it when there is no event waiting.)
If handleEvents() gets an event that it doesn't want while waiting for MOUSE_UP, what does it do with that event?
-
Maybe your subloop can foreward events it dosen't use to your main loop. I'm not sure why you would need a subloop. couldn't you just send the mouseup message to the currently pressed button from your main loop?
-
Bob : It has nothing to do with the windows API. I'm writing my own API for it, and that's where I got into problems.
filker0 : it doesn't really matter what type event is. It is a structure which contains information about the event. But that doesn't matter for the problem.
I'll try to explain the problem again :
The two functions I showed are functions from the API I'm making. I use them in my mainloop for receiving events. So when somebody presses the E-key, I receive a an event through gui_get_event(...). Then I can do whatever I need to do when the E-key is pressed. When I do a mouseclick on a button or a slider, I enter a subloop where I again use those functions to receive events. When I get a MOUSE_UP event, I exit the subloop, and thus re-enter the mainloop. The problem is that now my timer-events are catched in the subloop, and not in the mainloop, where I can handle them.
I don't want to handle every event in every subloop, so handling every message in every subloop is not an option. So I wonder if there's another way to do it.
-
When I've done this in the past (and I have), I've had my housekeeping events handled by a default_event_handler() that gets called from the main event loop when I'm there, and from any sub event handlers when I was in them. That way, the same code is handling the same events whether you're in the main loop or the button press loop.
I hope this helps.
-
Why do you create a subloop to handle a button or slider? Why not have only one loop, a main loop (message pump
in Windows terminology) for each window and process the mouse, slider keyboard etc messages in that loop? Thus,
each window created would have its own loop (message pump). This loop would also have a default processing option
to process all messages that were not specifically caught in the loop. For instance, a windows message pump may
receive 200 messages when the window is resized. We only want to catch the left mouse button when it is used to
resize the window. All the other remaining 199 resizing messages are passed onto the default window processing
function to allow the window to resize itself.
In your situation, I would assume you would have to create a thread to handle the left mouse button to allow the main loop
to continue processing.
I've just described the classical Windows design.