Page 1 of 1

Event Handling!

Posted: Mon Dec 15, 2014 9:04 pm
by 0fb1d8
Hi,
I am developing an x86/x86_64 operating system. You can read more about it here.

So now as I am able to do advanced process handling (obviously I can load ELF executables), I have ported libstdc++ and libc (used newlib) for me to directly build applications for my operating system. Playing around with this, I decided to write a library (like the .Net framework) to do "basic" operations for the user. I recently wrote a library called "iVGA", which is a graphics compositor that allows advanced 2D graphics. And this library (I am calling it "VX Framework" for now) will be an extension to this library where it will support buttons, windows, file I/O, ... and other high-level interfaces that allow easy development. All this will be done in C++. (Really, for those who ONLY use C, this is 21st century, we have to move on. It is true that C and ASM are the best languages to use for low-level programming, but when it comes to userland programs, C++ is better).

So then I ran into a problem.

How do I handle events?

I have already created a basic class structure (VX-->vObject-->vButton, vWindow, vFileStream, ... --> ... --> ...
The events will be represented by the "vEvent" class objects, which will be instantiated automatically once a vObject is instantiated. Each vObject-inherited classes, depending on their needs, may define as many events as they want

For instance:

Code: Select all

class vButton : (public vObject) {
    ...
    vEvent MouseDownEvent;
    vEvent MouseUpEvent;
    vEvent MouseDragEvent;
    ...
};
like this.

The constructors of the class will configure the "vEvent" objects so that the events are properly linked (binded) to a function that the user desires. (You could link "MouseDownEvent" against "Application::Exit" for close buttons.)

This approach is used because even after the constructor is called, the developers actually are able to modify, unlink , and link new functions against the predefined events. Like this:

Code: Select all

int foo (vEventArgs e) {
    std::cout << "Close Button Clicked! Closing..." << std::endl;
}

int main (int __argc, char* __argv[]) {
    vButton btn1 ("Close", Application::Close);  // constructor links button mousedown event
                                                 // against "Application::Close"
    btn1.MouseDownEvent.unlink();                // unlink previous linkage against mousedown event
    btn1.MouseDownEvent.link(foo);                // re-link mousedown events against new function
}
(In case anybody is wondering, the "vEventArgs" class is used as like a little packet for the vEvent to send information about the event (e.g. mouse x coordinate, y coordinate, duration) to the function. It will have a "char bin[]" field so that special events (non-"standard" and irregular) can just send the information in bytes.)

So getting to the point, how could I write the "vEvent" class so that it allows the selection of different events (mouse up, mouse down, etc.), creation of new events, and call the linked function(s) once the corresponding events have occurred?

btw, I have something called the ICN (Intercomponent Network) system, which allows the kernel, processses, and/or threads to communicate with each other.
Thank you!

Re: Event Handling!

Posted: Mon Dec 15, 2014 11:20 pm
by SpyderTL
It's entirely up to you, but I think .NET handles it by keeping a collection of "listeners" for each event. So your event class could simply have a collection of a specific interface that you could call, one-by-one. Or you could simply store a list of pointers to methods that need to be called.

If you don't think you'll need multiple listeners, then all you need is to store one interface reference, or one pointer, and call it inside of your event "Invoke" method.

You can make it as simple, or as complex as you want. What "features" are you looking for from your event system?

EDIT: .NET uses Delegates to define the method arguments, and it allows you to specify the type of Delegate that your Event will use. You can try going this route, but it may be difficult to do this using C++.

It may be easier to use the Java approach, which simply uses Interfaces to define the functions required to be considered an Event Listener.

Re: Event Handling!

Posted: Tue Dec 16, 2014 1:31 am
by gerryg400
In my (very simple) GUI toolkit when a mouse event is received by the app it passes the event to the widget that is at that screen position.
The chosen widget converts the mouse event (press or release) to a widget event. For example a Button will convert a mouse release to Button OnClisk. There may be a callback attached to the particular event for that widget instance. I use std::bind to call it.

At the top level ...

Code: Select all

 
    case ACE_EVTYPE_MOUSE_DOWN:
        mouse_grab_point = Point(ace_event.mouse.x, ace_event.mouse.y);
        w = win->DeliverEvent(mouse_grab_point, Event(Event::Type::ButtonPress, ace_event.mouse.x, ace_event.mouse.y));
        win->Draw(NULL);
        break;

    case ACE_EVTYPE_MOUSE_UP:
        point = Point(ace_event.mouse.x, ace_event.mouse.y);
        if ((point.m_x != mouse_grab_point.m_x) || (point.m_y != mouse_grab_point.m_y))
        {
            win->DeliverEvent(mouse_grab_point, Event(Event::Type::ButtonRelease, mouse_grab_point.m_x, mouse_grab_point.m_y));
        }
        win->DeliverEvent(point, Event(Event::Type::ButtonRelease, ace_event.mouse.x, ace_event.mouse.y));
        win->Draw(NULL);
        break;

.. and in the widget

Code: Select all

Aw::Widget *Aw::Button::eventHandle(const Point& point, const Event& ev)
{
    anvil_syslog(0, "Button::eventHandle()\n");
    switch (ev.getType())
    {
    case Event::Type::ButtonPress:
        m_pressed = true;
        // todo: send draw event
        break;
    case Event::Type::ButtonRelease:
        m_pressed = false;
        // todo: send draw event
        click_callback(this, ev);
        // We handled the event
        return this;
        break;
    }
    return nullptr;
}
Is that what you are asking ?

Re: Event Handling!

Posted: Tue Dec 16, 2014 1:58 am
by Satoshi
In .NET you have something like Button -> ButtonBase -> Control. If you call OnMouseDown() to change mouse event it will be changed in Control.
In Control you have a variables corresponding to every event Delegate http://referencesource.microsoft.com/#S ... rol.cs,220

And here is the setter of OnMouseDown in Control.
http://referencesource.microsoft.com/#S ... ol.cs,9069

But I preffer using chain of responsibility patter against this unnamed !@#$ from M$. I rewritten a huge part of .NET to Dlang for my OS and I think whole concept of .NET is !@#$. But its only my opinion...
http://en.wikipedia.org/wiki/Chain-of-r ... ty_pattern


BTW.
Really, for those who ONLY use C/C++, this is 21st century, we have to move on. It is true that C/C++ and ASM are the best languages to use for low-level programming, but when it comes to userland programs, D is better.

Re: Event Handling!

Posted: Tue Dec 16, 2014 5:07 am
by Brendan
Hi,
Bloodman wrote:But I preffer using chain of responsibility patter against this unnamed !@#$ from M$. I rewritten a huge part of .NET to Dlang for my OS and I think whole concept of .NET is !@#$. But its only my opinion...
http://en.wikipedia.org/wiki/Chain-of-r ... ty_pattern
If you post a disassembly of a (minimal) example of the chain of responsibility pattern; I'll point out all the potential branch mis-predictions and cache misses it has caused. Then you'll understand why I think "programming best practice" gets closer and closer to "worst quality software possible" every year.


Cheers,

Brendan

Re: Event Handling!

Posted: Tue Dec 16, 2014 6:32 am
by Combuster
Chain of responsibility means you have to implement chaining in every implementation. Composition means you have one class that forwards calls to many simple classes, implementing the same chaining only once. And you always know who's in charge of the chain.

Re: Event Handling!

Posted: Wed Dec 17, 2014 4:33 pm
by 0fb1d8
Thank you gerryg400!
Your post inspired me! I successfully implemented event handling in my OS Application Framework ("VX")!!