making an event-driven game

I want to make a structure of an event-driven game. Especially the parallelizing of the event loop and the game running I cannot master.

Here is what I have so far:

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
// I want to elaborate a structure in which I could parrallelizing the
// processes of event-driven within a game.

#include <iostream>
#include <vector>
#include <cstdlib>
#include <chrono>
#include <thread>

enum Item { Food, Weapon, Empty };
enum Act { Move, Fight, Nothing };
struct Point { int x; int y; };

struct Event {
    Act action;
    union {
        Point pos;
        //...
    };
};
struct Actor {
    std::vector<Item> itemlist;
    Point pos = {0,0};
    int health = 10;
    int power = 1;
};

// simulating a Game class
struct Game {
  Actor player, enemy;

  void process_input( const Event & e ) {
      switch( e.action ) {
          case Move: player.pos.x = e.pos.x; player.pos.y = e.pos.y ; break;
          case Fight: fight(); break;
          //...
      }
  }
  void run() { /*...*/ }
  void fight() { /*...*/ }
};

// simulating a Window class with event processing
struct Window
{
    int width, height;
    Event event;
    std::vector< (void*)(Event &) > listeners;  // This doesn't work

     void draw( const Game & game ) { /*...*/ }

     // event generating simulation
     void simulate_events() {
           std::this_thread::sleep_for( std::chrono::milliseconds( rand() % 10000 ) );
           event.action = rand() % 2;
           event.pos.x = rand() % width, event.pos.y = rand() % height;
     }
     void register_listener( (void * listener)(Event &) ) {
         listeners.push_back( listener );
     }
     void show() { /*...*/ }

     void run() {
         simulate_events();
         for( auto & listener : listeners ) listener( event );
         show();
    }
};

int main()
{
    Game game;
    Window win;

    win.register_listener( &(game.process_input) );

    // These processes I want to parallelize, but I don't know how.
    win.run();
    game.run();
}

I need help in parallelizing both threads.
Here's how you might create a message queue which is protected from concurrent access by a reader and a writer.
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
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

class Event {
  int m_id;
public:
  Event() : m_id(0) {};
  Event(int id) : m_id{id} {};
  int value() {
    return m_id;
  }
};

// An event queue with a built-in mutex
class EvtQueue : public std::queue<Event> {
  std::mutex              m_mutex;
  std::condition_variable m_cv;
  bool                    m_ready;
public:
  EvtQueue() : m_ready(false) {}

  void push(const Event &ev) {
    std::unique_lock<std::mutex> lock(m_mutex);
    std::queue<Event>::push(ev);
    m_ready = true;
    m_cv.notify_one();
  }

  const Event pop(void) {
    Event result;
    std::unique_lock<std::mutex> lock(m_mutex);
    if ( std::queue<Event>::size() > 0 ) {
      result = std::queue<Event>::front();
      std::queue<Event>::pop();
    } else {
      std::cout << "Waiting..." << std::endl;
      while (!m_ready) m_cv.wait(lock);
      m_ready = false;
      result = std::queue<Event>::front();
      std::queue<Event>::pop();
    }
    return result;
  }
};

void reader ( EvtQueue &myq ) {
  std::cout << "Hello from reader" << std::endl;
  Event e2 = myq.pop();
  std::cout << "E=" << e2.value() << std::endl;
}

void writer( EvtQueue &myq ) {
  std::cout << "Hello from writer" << std::endl;
  Event e1(42);
  myq.push(e1);
}

int main ( ) {
  EvtQueue  myq;
  std::thread wr(writer,std::ref(myq));
  std::thread rd(reader,std::ref(myq));
  rd.join();
  wr.join();
}
Thank you salem c, your example helped me a lot. With this I could pass my Window to a writer() and the Game class to a reader().

Have you (or someone else) good suggestions for reading me deeper into parallel programming? Especially I want to know about the basics of.
Last edited on
Topic archived. No new replies allowed.