C++ Pattern Register/Unregister Events



  • Guten Morgen Leute,

    habe mal ne Frage hinsichtlich Architektur bzw. eines Eventhandler. (Psuedo code)

    class Eventhandler
    {
      public:
    
      void Add(IComponent* p){ /* list mit registrierten Komponenten */...}
      void Del(IComponent* p){ /* list mit registrierten Komponenten */...}
    
    void Invoke(){ /*loop () p->Call(); */}
    }
    
    class IComponent 
    {
      virtual void Call() = 0;
    }
    
    
    class Component : public IComponent
    {
    
    public :
    
    Component(Eventhandler* registrar, ....)
    {
      registrar->Add(this); /* register event */
    }
    
    ~Component(.)
    {
      registrar->Del(this); /* unregister event */
    }
    
    virtual Call() override
    { 
    /* on event */}
    }
    

    ich habe Komponenten , welche sich an einem EventHandler anmelden können, so dass die Method "call" von außen durch den handler aufgerufen werden können.

    1. Ist der Ansatz so "schöne", da gibt es bestimmt schönere Lössungen pattern!?

    2. gibt es ne möglichleit dass man die

    registrar->Del(this); /* unregister event */
    

    im Dtor automatisch aufrufen könnte:

    EDIT:

    Achja, so vll.:) hmmm

    class Registrar()
    {
      Eventhandler* _eh:
      IComponent * _c;
    public:
    
    Registrar(Eventhandler* eh, IComponent * c)
    {
      _eh = eh; 
      _c= c;
      _eh->Add(_c);
    }
    
    virtual ~Registrar()
    {
      _eh->Del(_c);
    }
    }
    

    und dann

    class Component : public IComponent
    {
     Registrar _r;
    public :
    
    Component(Eventhandler* registrar, ....)
     : _r(registrar, this)
    {
    }
    
    ....
    
    }
    

    bin gespannt was es da für ideen gibt;)



  • Du hast schon die übliche Herangehensweise umgesetzt, es ist allerdings ziemlich altbacken (oder auch C-isch). Heutzutage verwendet man dafür die Support Templates aus dem functional Header. Ich denke da speziell an die std::function und ganze invoke Funktionalität (std::invoke, std::invoke_result_t usw.) drumherum. Allerdings ist die neuere invoke Funktionalität ein C++17 Feature, brauchst also ein Compiler, der das unterstützt. Bei der Übergabe der Parameter bzw Callables (wie zum Beispiel Fuctionpointer) kannst du dann auch forward (std::forward) Funktionalität verwenden. Wenn du willst kann ich mir mal ein Beispiel ausdenken (denke da spontan an einen Threadpool), würde aber C++20 werden. 😉 (Und ich kann das ganze nur aus der Sicht des gcc bzw clang unter Linux/BSD beurteilen.)



  • @VLSI_Akiko sagte in C++ Pattern Register/Unregister Events:

    Du hast schon die übliche Herangehensweise umgesetzt, es ist allerdings ziemlich altbacken (oder auch C-isch). Heutzutage verwendet man dafür die Support Templates aus dem functional Header. Ich denke da speziell an die std::function und ganze invoke Funktionalität (std::invoke, std::invoke_result_t usw.) drumherum. Allerdings ist die neuere invoke Funktionalität ein C++17 Feature, brauchst also ein Compiler, der das unterstützt. Bei der Übergabe der Parameter bzw Callables (wie zum Beispiel Fuctionpointer) kannst du dann auch forward (std::forward) Funktionalität verwenden. Wenn du willst kann ich mir mal ein Beispiel ausdenken (denke da spontan an einen Threadpool), würde aber C++20 werden. (Und ich kann das ganze nur aus der Sicht des gcc bzw clang unter Linux/BSD beurteilen.)

    servus, ja ich habe vergessen zu erwähnen dass ich in der C++03 (MFC) welt unterwegs bin, d.h. deletegates, function, etc. C++11 > kann ich so nicht verwendetn;)



  • @SoIntMan sagte in C++ Pattern Register/Unregister Events:

    servus, ja ich habe vergessen zu erwähnen dass ich in der C++03 (MFC) welt unterwegs bin, d.h. deletegates, function, etc. C++11 > kann ich so nicht verwendetn;)

    Hmm ja, da bleibt nicht viel übrig, außer vielleicht auf const- und exception-Correctness zu achten, einfach um die höhere Typsicherheit von C++ zu nutzen. Man kann auch noch die eine oder andere Geschichte über Metatemplateprogrammierung machen. Ist allerdings vor C++11 schwierig bzw macht nicht gerade Spaß. Wenn du dir da ein bisschen was abgucken willst gibt es da vom "C++Großmeister" Alexandrescu die LOKI lib, welche eine Menge moderner C++ Features in C++98 realisiert.



  • Boost.Signals2 ist auch nicht schlecht, könnte man sich auch mal ansehen.

    Was ich komisch finde ist dein Naming. Als Event-Handler bezeichnet man normalerweise das Ding was dann letztendlich aufgerufen wird um eben auf ein Ereignis zu reagieren. Bei dir heisst aber der "Verteiler" so. IComponent für die "Empfänger" finde ich auch nicht gut. Call ist auch nicht unbedingt der beste Name, sowas wie OnEvent wäre denke ich besser.



  • @SoIntMan sagte in C++ Pattern Register/Unregister Events:

    servus, ja ich habe vergessen zu erwähnen dass ich in der C++03 (MFC) welt unterwegs bin, d.h. deletegates, function, etc. C++11 > kann ich so nicht verwendetn;)

    Ich habe ja echt Verständnis, wenn man an große und lange gewachsene Projekte sehr konservativ herangeht, aber vielleicht kann man bei einem fast 20 Jahre alten Standard doch mal ein paar vorsichtige Schritte in Richtung eines 10 Jahre alten Standards wagen. Vor allem weil sich gewisse Lösungen damit simpler formulieren lassen (<functional>, Labmdas, etc.), was letztendlich Wartungskosten sparen kann. Immerhin wurde bei C++ immer sehr viel Wert auf Abwärtskompatibilität gelegt - gut möglich also, dass das erstaunlich wenig Probleme mit bereits vorhandenem Code machen würde.

    Aber ich verstehe schon, da bist du wahrscheinlich nicht der richtige Ansprechpartner für 😉



  • @Finnegan sagte in C++ Pattern Register/Unregister Events:

    Immerhin wurde bei C++ immer sehr viel Wert auf Abwärtskompatibilität gelegt - gut möglich also, dass das erstaunlich wenig Probleme mit bereits vorhandenem Code machen würde.

    Es kommt darauf an wie konform der verwendete C++98/03 Compiler ist. Umstieg von z.B. MSVC 2005 kann schon einiges an Aufwand sein. Weil MSVC 2005 halt viele Dinge frisst die nicht Standard sind, und umgekehrt auch einige Dinge nicht frisst die legales standard C++98/03 sind.



  • @hustbaer sagte in C++ Pattern Register/Unregister Events:

    @Finnegan sagte in C++ Pattern Register/Unregister Events:

    Immerhin wurde bei C++ immer sehr viel Wert auf Abwärtskompatibilität gelegt - gut möglich also, dass das erstaunlich wenig Probleme mit bereits vorhandenem Code machen würde.

    Es kommt darauf an wie konform der verwendete C++98/03 Compiler ist. Umstieg von z.B. MSVC 2005 kann schon einiges an Aufwand sein. Weil MSVC 2005 halt viele Dinge frisst die nicht Standard sind, und umgekehrt auch einige Dinge nicht frisst die legales standard C++98/03 sind.

    Ja, das ist was dran, dann will ich nichts gesagt haben. Ist sehr lange her bei mir mit den alten MSVC-Compilern, aber ich erinnere mich auch noch vage an ein paar Dinge, die ich mir abgewöhnen musste, als ich zum Standard-Pendantiker wurde 🙂 ... zumindest kann man mal versuchen es zu bauen und schauen ob eventuelle Tests laufen. Oder man schafft es irgendwie, neue Programmteile als eigene Module so weit zu isolieren, dass man die dann mit einem neueren Compiler bauen kann.



  • @Finnegan
    Ja, einen Versucht ist es sicherlich Wert.
    Was neue Programmteile angeht: kann man machen, zahlt sich aber eher nur dann aus wenn die wirklich gross sind. Macht ja auch einiges an Aufwand diese Schnittstellen zu definieren und zu warten. Und die können dann ja kaum C++ Features verwenden. Also z.B. schonmal nix aus der Standard Library.

    Bei späteren Visual Studio Versionen ist das dann auch besser, die sind ja dann irgendwann binary kompatibel und man kann sogar Standary Library Komponenten zwischen den verschiedenen Teilen rumschieben. Wobei es bei späteren Visual Studio Versionen mMn. dann auch weniger wichtig ist, weil da ein Upgrade meist relativ wenig Aufwand bedeutet.

    Das Upgrade von VS 2015 -> 2017 war bei uns z.B. schon ein bisschen Arbeit, aber nicht extrem. Upgrade von 2017 -> 2019 war kaum Aufwand. Upgrade auf 2022 haben wir noch nicht probiert. Sollte ich vielleicht bei Zeiten mal ausprobieren wie viel Fehler das wirft 🙂



  • Guten Morgen,

    ja ich würde auch gern neue Standards verwenden. Leider muss ich hier gerade ein App entwickeln welche auf "uralten WinCE" panel laufen sollen. Auch wenn diese nicht mehr Zeitgemäß sind bzw. teilweise abgekündigt sind. (brown-field).

    Und nach meinem besten Wissen habe ich eben dann ein VS2008 C++03 std MFC verwenden um native WinCE apps zu bauen.

    Wenn es allerdings ohne großen Aufwand möglich wäre das ganze in VS2019 C++11 < zu bauen und für die alten Systeme zu kompilieren wäre ich dafür.

    Da es sich hier auch um POV und POC's hatte wollte ich eben da nicht so viel elan reinstecken. Wenn es mein Tagegeschäft wäre und ich Jahre nicht andere tun würde... und deinen Weg @Finnegan gehen



  • @SoIntMan sagte in C++ Pattern Register/Unregister Events:

    ja ich würde auch gern neue Standards verwenden. Leider muss ich hier gerade ein App entwickeln welche auf "uralten WinCE" panel laufen sollen. Auch wenn diese nicht mehr Zeitgemäß sind bzw. teilweise abgekündigt sind. (brown-field).

    Ach du meine Güte, wo laufen denn noch WinCE Sachen? 🤔



  • @VLSI_Akiko sagte in C++ Pattern Register/Unregister Events:

    Ach du meine Güte, wo laufen denn noch WinCE Sachen?

    Bspw: In der Industrie. bspw. Siemens HMI Panels .. WinCE based. zwar abgekündigt aber bis da komplett ersetzt wird (bei Siemens Kunden) dauert es noch "jahre".



  • @SoIntMan sagte in C++ Pattern Register/Unregister Events:

    @VLSI_Akiko sagte in C++ Pattern Register/Unregister Events:

    Ach du meine Güte, wo laufen denn noch WinCE Sachen?

    Bspw: In der Industrie. bspw. Siemens HMI Panels .. WinCE based. zwar abgekündigt aber bis da komplett ersetzt wird (bei Siemens Kunden) dauert es noch "jahre".

    Ah ja, die üblichen Täter. Ich kenne das von anderen Siemensgeräten wo noch ewig lang Windows NT 4 benutzt wurde. Wobei für die letzte WindowsCE Version gibts doch noch Support bis 2023 oder? Seweit ich mich erinnern kann, war das immer Erscheinungsdatum + 10 Jahre Support.
    Naja, zumindest musstest du dich nicht mit HP C3600 und C3750 rumschlagen. Also die Kisten mit HP-PA 8600 und 8700 Prozessoren drin und uralt HP-UX drauf. Die Prozessoren sind cool (genau genommen sogar besser als Alpha), aber dieses Unix war schmerzhaft. 😅



  • @VLSI_Akiko sagte in C++ Pattern Register/Unregister Events:

    Ah ja, die üblichen Täter. Ich kenne das von anderen Siemensgeräten wo noch ewig lang Windows NT 4 benutzt wurde. Wobei für die letzte WindowsCE Version gibts doch noch Support bis 2023 oder? Seweit ich mich erinnern kann, war das immer Erscheinungsdatum + 10 Jahre Support.
    Naja, zumindest musstest du dich nicht mit HP C3600 und C3750 rumschlagen. Also die Kisten mit HP-PA 8600 und 8700 Prozessoren drin und uralt HP-UX drauf. Die Prozessoren sind cool (genau genommen sogar besser als Alpha), aber dieses Unix war schmerzhaft.

    Ist halt Siemens, die haben ne gewisse Stellung:) Es gibt natürlich schon da moderne technologien Web bases Scada System etc. Aber die (siemens) Kunden wollen eben oft noch bei bewährten und bekannten Technologien bleiben. Und wenn immer auf neue Technologien aufgesprungen wird, ist eben die Angst da, dass es nicht funktioniert, oder man sich damit nicht auskennt:) etc.



  • @SoIntMan sagte in C++ Pattern Register/Unregister Events:

    Ist halt Siemens, die haben ne gewisse Stellung:) Es gibt natürlich schon da moderne technologien Web bases Scada System etc. Aber die (siemens) Kunden wollen eben oft noch bei bewährten und bekannten Technologien bleiben. Und wenn immer auf neue Technologien aufgesprungen wird, ist eben die Angst da, dass es nicht funktioniert, oder man sich damit nicht auskennt:) etc.

    Komisch, also ich mache gerade wieder die Erfahrung, dass man sich mit den alten Systemen nicht mehr auskennt, weil die ursprünglichen Kollegen nicht mehr da sind.
    Wühle mich gerade durch Upstart Patches, die Upstart um die Nutzung von Capabilities erweitert. Niemand weiß was die Patches machen, niemand weiß, was die Scripte machen, niemand weiß was Capabilities sind. Aber hey, immerhin schon ein 2.6.32 Kernel. Welches Securitypatchlevel? Keine Ahnung, ist nicht ersichtlich (für die Laien, Linux hatte mal eine 4-stellig Versionsnummer). Naja, ist immerhin spaßiger als Treiber aus dem Xilinx Kernel branch rauszufummeln und in den Mainline Kernel zu portieren. 🤣



  • @VLSI_Akiko sagte in C++ Pattern Register/Unregister Events:

    Wobei für die letzte WindowsCE Version gibts doch noch Support bis 2023 oder? Seweit ich mich erinnern kann, war das immer Erscheinungsdatum + 10 Jahre Support.

    Support heisst aber nicht dass MS es unbedingt mit neuen Visual Studio Versionen unterstützt. Sondern bloss dass es Security Fixes gibt und dass MS Support Cases annimmt. Wobei wohl der "normale" Support für WindowsCE 8.0 bereits 2018 abgelaufen ist:

    Mainstream Support Ended October 9, 2018, and Extended Support Until October 10, 2023.

    https://en.wikipedia.org/wiki/Windows_Embedded_Compact


Log in to reply