Event Handling!

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
0fb1d8
Member
Member
Posts: 27
Joined: Mon Nov 03, 2014 2:20 pm
Location: Seoul, South Korea
Contact:

Event Handling!

Post 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!
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: Event Handling!

Post 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.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Event Handling!

Post 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 ?
If a trainstation is where trains stop, what is a workstation ?
User avatar
Satoshi
Member
Member
Posts: 28
Joined: Thu Sep 13, 2012 2:18 pm

Re: Event Handling!

Post 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.
Trinix (written in D) https://github.com/Rikarin/Trinix
Streaming OS development https://www.livecoding.tv/satoshi/
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Event Handling!

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Event Handling!

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
0fb1d8
Member
Member
Posts: 27
Joined: Mon Nov 03, 2014 2:20 pm
Location: Seoul, South Korea
Contact:

Re: Event Handling!

Post by 0fb1d8 »

Thank you gerryg400!
Your post inspired me! I successfully implemented event handling in my OS Application Framework ("VX")!!
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
Post Reply