Du bist nicht angemeldet.

Werbeanzeige

Fawkes

Frischling

  • »Fawkes« ist der Autor dieses Themas

Beiträge: 58

Beruf: Realschüler :)

  • Private Nachricht senden

1

14.03.2015, 15:28

Funktion als parameter übergeben

Hallo, ich möchte eine Funktion als Parameter übergeben.

Der Sinn dahinter ist, das man einen Button erstellen kann und diesem eine Funktion beim klicken zuweisen kann.


C-/C++-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
int Button::run( sf::RenderWindow *window, sf::Event *event, void (*onClick)(void) ){ // Hier soll irgendeine Funktion übergeben werden, die weiter unten aufgerufen wird

    /***********/
    // ABFRAGE //
    /**********/
    
    mousePosition.x = event->mouseMove.x;
    mousePosition.y = event->mouseMove.y;

    if( mousePosition.x > this->sprite.getPosition().x && mousePosition.x < this->sprite.getPosition().x + this->sprite.getScale().x * this->texture.getSize().x ){

        if( mousePosition.y > this->sprite.getPosition().y && mousePosition.y < this->sprite.getPosition().y + this->sprite.getScale().y * this->texture.getSize().y ){
            this->text.setColor( sf::Color( 255,0, 0 ) );
            
            /*************/
            // Beim KLICK //
            /*************/
            
            if( event->type == event->MouseButtonPressed ){
                onClick(); // Hier die aufzurufende Funktion
            }
        }
    }
    else{
        this->text.setColor( sf::Color( 0, 0, 0 ) );
    }


    return 0;
}


Danke schonmal vorab.

Fawkes

Frischling

  • »Fawkes« ist der Autor dieses Themas

Beiträge: 58

Beruf: Realschüler :)

  • Private Nachricht senden

2

14.03.2015, 15:34

Ich habe das ganze jetzt etwas anders gemacht, beim Klick gibt die Funktion jetzt -1 zurück. Dann frage ich nur ab und kann eine Funktion abspielen lassen.


C-/C++-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
int Button::run( sf::RenderWindow *window, sf::Event *event ){

    /***********/
    // ABFRAGE //
    /**********/
    
    mousePosition.x = event->mouseMove.x;
    mousePosition.y = event->mouseMove.y;

    if( mousePosition.x > this->sprite.getPosition().x && mousePosition.x < this->sprite.getPosition().x + this->sprite.getScale().x * this->texture.getSize().x ){

        if( mousePosition.y > this->sprite.getPosition().y && mousePosition.y < this->sprite.getPosition().y + this->sprite.getScale().y * this->texture.getSize().y ){
            this->text.setColor( sf::Color( 255,0, 0 ) );
            
            /*************/
            // Beim KLICK //
            /*************/
            
            if( event->type == event->MouseButtonPressed ){
                return -1; // Mousebutton wurde geklickt
            }
        }
    }
    else{
        this->text.setColor( sf::Color( 0, 0, 0 ) );
    }


    return 0;
}

3

14.03.2015, 16:04

Wo genau war denn das Problem in der ersten Version? Sollte so doch funktionieren.
Wenn du einen halbwegs neuen Compiler verwendest (Visual Studio 2013 hat einen), dann kannst du auch das Observer-Pattern recht cool umsetzen:

C-/C++-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
class Button
{
    using ListenerType = std::function<void()>;

public:
    void OnClick()
    {
         for (const auto& listener : listeners)
         {
             listener();
         }
    }

    unsigned int AddListener(const ListenerType& listener)
    {
         auto id = listeners.size();
         listeners.push_back(listener);
         return id;
    }

    void RemoveListener(unsigned int id)
    {
        listeners.erase(std::begin(listeners) + id);
    }

private:
    std::vector<ListenerType> listeners;
};


Angewendet wird das ganze dann so (nur ein paar Beispiele):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void DoMagic() { std::cout << "Magic!"; }
class Wizard { public: void DoBetterMagic() { std::cout << "OOP Magic!" } };

int main()
{
    Wizard wizard;

    Button button;
    button.AddListener(&DoMagic); // Function
    button.AddListener(std::bind(&Wizard::DoBetterMagic, &wizard)); // Method
    auto id = button.AddListener([]{ std::cout << "C++11 Magic!"; }); // Lambda

    // Output:
    // Magic!OOP Magic!C++11 Magic!
    button.OnClick();
    button.RemoveListener(id);

    // Output:
    // Magic!OOP Magic!
    button.OnClick();
    return 0;
}


Nur um dir eine Idee zu geben, wie man sowas umsetzen könnte.

Schorsch

Supermoderator

Beiträge: 5 206

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

4

14.03.2015, 16:14

Mit C++ 11 gibt es doch auch neue Funktionszeiger, wenn man die so nennen möchte. Ich meine std::function wäre das, bin da aber absolut nicht im Thema. Ansonsten wäre Observer sicherlich eine Möglichkeit wobei hier ein wenig mehr Overhead im Spiel ist.
„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.“

5

14.03.2015, 17:19

Mit C++ 11 gibt es doch auch neue Funktionszeiger, wenn man die so nennen möchte. Ich meine std::function wäre das, bin da aber absolut nicht im Thema. Ansonsten wäre Observer sicherlich eine Möglichkeit wobei hier ein wenig mehr Overhead im Spiel ist.

Siehe mein Post. Hab ich alles drinnen...

Schorsch

Supermoderator

Beiträge: 5 206

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

6

14.03.2015, 18:41

Ah das ist richtig. Hab ich falsch geguckt:)
„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.“

Nox

Supermoderator

Beiträge: 5 282

Beruf: Student

  • Private Nachricht senden

7

14.03.2015, 19:48

Bleibt nur noch die Frage zu klären, warum die erste Version nicht funktioniert hat. Wenn onClick eine freie Funktion ist, sollte es eigentlich funktionieren. Wenn es eine Memberfunktion sein sollte, dann natürlich nicht.
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.

8

15.03.2015, 08:06

@Batzer: Wenn du einen Listener löschst und es nicht der letzte Listener ist, ändern sich die IDs der anderen Listener. Das kann man noch anders umsetzen.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

9

15.03.2015, 18:34

Jo stimmt hast recht, hab den Code nicht getestet. War nur um zu Zeigen, wie einfach das alles mit den neuen Features geht.

Werbeanzeige