Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Julién

Alter Hase

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

711

30.08.2016, 00:50

Ihr kennt alle sicherlich folgendes Meme:

Zitat

It doesn't work and I don't know why.
It does work and I don't know why.


Gerade erwischt mich letzter Satz: "It does work and I don't know why."
Erwartetes Ergebnis: NullPointer-Exception. Abstürzen des Programmes
Tatsächliches Ergebnis: Es funktioniert ohne Abzustürzen.

Per Templates erstelle ich einen Wrapper, damit Method mit unterschiedlicher Signatur in einem 'std::vector' speichern kann;
einzige Beschränkung: die Signatur hat nur einen Parameter.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
                //...
                using EventPtr = void*;
                using InstancePtr = void*;
                //...

                template<typename TEvent, class TClass, void(TClass::*TCallback)(TEvent*)>                
                static inline void MethodCallback(InstancePtr instance, EventPtr event){
                    (static_cast<TClass*>(instance)->*TCallback)(static_cast<TEvent*>(event));
                }


Der Pointer auf die Instanz der Klasse sowie der Pointer zur Methode wird im 'std::pair' gespeichert.

C-/C++-Quelltext

1
2
                using CallbackPtr   = void(*)(InstancePtr, EventPtr);
                using Callback      = std::pair<InstancePtr, CallbackPtr>;


Ein Callback wird wiederum in einem std::vector-Container gespeichert (welcher wiederum in einer std::map gespeichert wird).

C-/C++-Quelltext

1
2
3
4
                using CallbackList = std::vector<Callback>;
                using UUID         = uint32_t;
                using Connections  = std::map<uint32_t, CallbackList>;
                Connections connections;


Zum Befühlen der Liste verwende ich folgenden Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
               template<struct TEvent, class TClass, void(TClass::*TCallback)(TEvent*)>
               void bind(TClass* instance){
                   uint32_t uuid{TEvent::uuid()};
                 
                   connections[uuid].emplace_back(nullptr,// Eigentlich sollte hier [b]instance[/b] stehen.
                                                  &MethodCallback<TEvent, TClass, TCallback>);
               }


Und die Callbacks werden so aufgerufen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
                template<typename TEvent>
                void    emit(TEvent* event){
                    for(auto cb : connections[TEvent::uuid()])
                        cb.second(cb.first, event); // <- Hier nullptr exception erwartet.
                        
                        // Vergleich mit vorherigen Codebeispiel
                        // std::pair.first  -> Pointer zur Instanz der Klasse
                        // std::pair.second -> Pointer zur Methode
                }


Seltsamerweise kompiliert das Beispiel bei mir und läuft ohne Abzustürzen. 8|

P.S.: Verzeiht Typo's, meine Kaffeemaschine ist leider kaputt.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Julién« (30.08.2016, 01:00)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

712

30.08.2016, 07:29

Also, erstens gibt es in C++ gar keine Null Pointer Exception. Zweitens sehe ich nicht, warum der Code eine solche auslösen sollte (wenn es sie denn gäbe). Es ist doch nur der Parameter null, nicht der Funktionszeiger.

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

713

10.10.2016, 17:26

Zu informativ für den "Mal wieder was lustiges" Thread, zu kurz für einen eigenen, daher hier:


Die Videos von Bisqwit sind übrigens immer sehenswert, sind auch ein paar Sachen in Richtung Grafikprogrammierung dabei, einfach mal stöbern ;)

(Ernsthaft, man muss den Typen gern haben)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

714

10.10.2016, 19:45

Oh ja, Bisqwit ist :thumbup:

Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

715

21.11.2016, 15:45





Programmiert er da tatsächlich in DosBox? Wenn ja, gibt's dazu irgendwo Infos/Tutorials, wie man als Laie so ein Setup aufsetzt? Das sieht extrem witzig aus!
Liebe Grüße,
René

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

716

21.11.2016, 16:09

Er hat da ein total lustiges Setup, siehe hier
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

717

26.08.2017, 23:06

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main;

public class Main {
    
    public static class ServerConnection {
        void sendRegistartionAborted() {
            System.out.println("RegistrationAborted - sent");
        }
        void sendCrashed(int playerID) {
            System.out.println("Crashed(" + new Integer(playerID) + ") - sent");
        }
        void sendKicked(int playerID, String msg) {
            System.out.println("Kicked(" + new Integer(playerID) +
                               ", \"" + msg + "\") - sent");
        }
    }

    public interface Event {
        public void send(ServerConnection con);
    }

    enum Events implements Event {
        RegistrationAborted {
            @Override
            public void init() {
                System.out.println("RegistrationAborted - Init");
            }
            
            @Override
            public void send(ServerConnection con) {
                con.sendRegistartionAborted();
            }
        },
        Crashed {
            private int i;
            
            @Override
            public void init(int i) {
                System.out.println("Crashed - Init");
                
                this.i = i;
            }
            
            @Override
            public void send(ServerConnection con) {
                con.sendCrashed(this.i);
            }
        },
        Kicked {
            private int i;
            private String msg;
            
            @Override
            public void init(int i, String msg) {
                System.out.println("Kicked - Init");
                
                this.i = i;
                this.msg = msg;
            }
            
            @Override
            public void send(ServerConnection con) {
                con.sendKicked(this.i, this.msg);
            }
        };

        public void init()
        { throw new IllegalArgumentException("Undefined for this enum value"); }
        public void init(int val)
        { throw new IllegalArgumentException("Undefined for this enum value"); }
        public void init(int val, String msg)
        { throw new IllegalArgumentException("Undefined for this enum value"); }
    }

    public static void main(String[] args) {
        ServerConnection sv = new ServerConnection();
        
        Events.Crashed.init(100);
        Events.Crashed.send(sv);
        
        Events.Kicked.init(123, "Being dumb");
        Events.Kicked.send(sv);
        
        Events.RegistrationAborted.init();
        Events.RegistrationAborted.send(sv);
        
        System.out.println();
        
        Events ev = Events.Crashed;
        ev.init(556);
        Events.Crashed.send(sv);
    }

}


Stateful enums. Richtig gruselig.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

718

13.11.2017, 16:19

C-/C++-Quelltext

1
std::vector<std::vector<std::vector<std::vector<char>>>>
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

719

13.11.2017, 16:38

Das wird auch bei using namespace keinen Deut besser... :huh:
fka tm

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

720

13.11.2017, 18:06

darf man fragen in welchem Kontext dieses Meisterwerk auftauchte?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige