Blog
User Interface Code-fu
Date: 21/10/2005
Note: This is aimed purely at coders, so don't get too worried if it doesn't make any sense.

Background: In the world of programming user interfaces it is common to have an object wrap each user interface element (window), which virtual methods that trigger when various things happen, like "OnMouseClick" and "OnPaint". These methods are implemented by the application to add functionality to the base controls provided by the application framework. In C++ these are virtual member functions in the parent C++ window class.

Ideally the code inside these event handlers, as implemented by the specific application, would take minimal time to run and be generally well behaved. But in reality it sometimes needs to do a lot of work in the event handler and can do nasty things like delete the current window object processing an event. So I'm getting to grips with this in Lgi and I've come up with a reasonably neat solution.

Firstly for the issue of long running event handlers, you often want to know that the handler "hung" for a while. This is reasonably easy to check, just take a tick count at the start, and another at the end and work out the milliseconds the handler ran for. If it's over some threshold you can change the post event handler behaviour. I do this in the list control when the application puts up a right click menu and "hangs" the event handler. Normally I trigger a timer to check if the user has started a drag and drop operation, but if the handler hangs, a d'n'd operation should NOT be started.

The second issue is the one of the event handler destroying the window during it's processing of the event. Now you could setup a complicated system of return values on the events to indicate whether the application has deleted the window, but that is prone to error because it puts the responsibility on the application to "Do The Right Thing(TM)". I'd prefer a system that doesn't require any smarts on the application side to work correctly. So I came up with a better way (And sorry if it's obvious). Basically the problem with the current object being deleted during the event handler is that you can not access any of the member variables or methods after the event handler. However anything on the stack is still fair game, and I use this fact to get notification of the objects destruction. e.g. my code to call the event handler now looks like this:

bool DeleteFlag = false;
this->pDeleteFlag = &DeleteFlag;
this->EventHandler(EventParams);
if (DeleteFlag)
    return;
this->pDeleteFlag = NULL;


I have put a pointer to the delete flag in the object so that in the destructor of the object I can return information of the destruction event to some interested party (i.e the event handler calling code furthur up the call stack):
Object::~Object()
{
    if (pDeleteFlag)
        *pDeleteFlag = true;
    // other stuff....
}
This way if the event handler deletes the object, the flag on the stack gets set, and I can trap that AFTER the event handler has returned and the current object no longer exists. Nice, neat and robust.
 
Reply
From:
Email (optional): (Will be HTML encoded to evade harvesting)
Message:
 
Remember username and/or email in a cookie.
Notify me of new posts in this thread via email.
BBcode:
[q]text[/q]
[url=link]description[/url]
[img]url_to_image[/img]
[pre]some_code[/pre]
[b]bold_text[/b]