On Friday, 28 February 2020 at 08:08:59 UTC, Виталий Фадеев wrote:
On Friday, 28 February 2020 at 06:12:37 UTC, Виталий Фадеев wrote:
Searching solution for idea !

Goal is to get System message, dispatch/route to method !
If method implemented only !

I dream on in future write clean code of a derived widgets like this :

    class Base
    {
       // dispatch
       void On( message ... )
       {
           // call On<message>()
// example: call OnKeyUp() - if method OnKeyUp() is exists only
       }
    }

May be other than derived ? May be templating ?
How to implement ?

Now I go in ths way:
[snip]
Searching for beauty readable code...

Here's an attempt. It looks up all subclasses of Base in the same module, and calls the named method if it exists. However, it will fail for any subclass of Base that is defined in a different module.

import core.sys.windows.windows;
import std.stdio;

class Base {
    LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
        switch (message) {
            case WM_KEYDOWN:
                return tryCall!"OnWM_KEYDOWN"(wParam, lParam);
            default:
        }
        return 0;
    }

    auto tryCall(string name, Args...)(Args args) {
        import std.meta;

        alias This = typeof(this);
        alias module_ = __traits(parent, This);

        enum isSubclass(T...) = is(T[0] : This);
alias getModuleMember(string name) = __traits(getMember, module_, name);
        enum hasMethod(T) = __traits(hasMember, T, name);

        // Get every member in this module
        enum memberNames = __traits(allMembers, module_);
        alias members = staticMap!(getModuleMember, memberNames);

        // Filter away anything that isn't derived from Base
        alias subclasses = Filter!(isSubclass, members);

// Get rid of anything that doesn't have a method with the correct name alias subclassesWithMethod = Filter!(hasMethod, subclasses);

        // Sort them so you get the most derived types first
        alias Types = DerivedToFront!subclassesWithMethod;

// Check for each type if the `this` is an instance of that specific one
        static foreach (T; Types) {
            if (cast(T)this !is null) {
                // And look up that method and call it.
return __traits(getMember, cast(T)this, name)(args);
            }
        }

// If `this` is not one of the types with that method, return some default value
        return 0;
    }
}

class Button : Base {
    LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
        writeln("WM_KEYDOWN");
        return 0;
    }
}

unittest {
    Base b1 = new Base();
    Base b2 = new Button();

    writeln("Base:");
    b1.On(WM_KEYDOWN, 0, 0);
    writeln("Button:");
    b2.On(WM_KEYDOWN, 0, 0);
}

--
  Simen
  • Call method if declare... Виталий Фадеев via Digitalmars-d-learn
    • Re: Call method i... Виталий Фадеев via Digitalmars-d-learn
      • Re: Call meth... Simen Kjærås via Digitalmars-d-learn
      • Re: Call meth... mipri via Digitalmars-d-learn
        • Re: Call ... Виталий Фадеев via Digitalmars-d-learn
    • Re: Call method i... Simen Kjærås via Digitalmars-d-learn
      • Re: Call meth... Виталий Фадеев via Digitalmars-d-learn
        • Re: Call ... drug via Digitalmars-d-learn
        • Re: Call ... Simen Kjærås via Digitalmars-d-learn
          • Re: C... Виталий Фадеев via Digitalmars-d-learn
            • ... Виталий Фадеев via Digitalmars-d-learn
              • ... Виталий Фадеев via Digitalmars-d-learn
                • ... Simen Kjærås via Digitalmars-d-learn

Reply via email to