What's the "best" way to implement a game loop in a C++-based Haiku app?

Hi there! I’m a software developer experimenting with building a simple RTS game on Haiku to introduce myself to the Haiku development experience.

I’ve got a basic BWindow with a BView displaying a custom bitmap and some text. I want a main game loop running that will allow various units to move independently. How would I implement this?

I’ve tried creating a thread spawned when the BView is created, but have run into problems passing data back and forth to it and updating the BView, so I’m not sure that’s the right approach. What’s the most “Haiku” way to have things run autonomously (again, like enemies moving around on their own at a consistent rate)?

Thanks in advance!

2 Likes

I would use BMessageRunner to setup 60 Hz timer and process game logic step in BView::MessageReceived.

Thanks! That makes sense to me.

I’m trying that now and having a bit of trouble. Here’s what I’ve defined as a test, but I’m not ever seeing “My message received” printed in the Terminal when I run it from there (other printf() messages do appear).

Any idea what I might be doing wrong?

class MainView : public BView {
  public:
    MainView(BStringView *label);
    void MessageReceived(BMessage *message);
  private:
    // ...
    BMessenger *messenger;
    BMessageRunner *messageRunner;

void MainView :: MainView(BStringView *label) : BView(...) {
  // ...
  BMessage message(1);
  // Construct a message runner that will send messages back to this MainView, once per second, 10 times
  messenger = new BMessenger((BHandler *)this, NULL, NULL);
  messageRunner = new BMessageRunner(*messenger, message, 1000, 10);
}

void MainView::MessageReceived(BMessage *message) {
  if( message->what == 1 ) {
    printf("My message received\n");
  }
}

Your BMessageRunner sends the message to your BMessenger. Try to set the BMessageRunner’s target to your MainView by using “this” instead.

Ah, interesting! Unfortunately I’m having no luck there.

Here’s the updated code in the BView’s constructor. Is there something else I should do?

  messenger = new BMessenger((BHandler *)this, NULL, NULL);
  messageRunner = new BMessageRunner(this, message, 1000, 10);
}

Oh I should point out: I’m running R1/beta4 (Revision hrever56578+95) on a 64-bit virtual machine.

Other than you don’t need that BMessenger at all, this should work. I just tried in a BWindow instead of a BView, because there’s a quick little template for that coming with Genio. It should work the same in a BView though, I think…

Ah-ha! It worked in a BWindow, not a BView. OK, so I’ll have to handle the logic there. I can make that work. Thanks very much for your prompt and clear help!

Good luck with your exploratory coding. Keep us posted. :slight_smile:

You probably should set the target of the BMessageRunner after the BView is attached to the BWindow it belongs to. Do it in the AttachedToWindow method.

Nexus-6 wrote:
You probably should set the target of the BMessageRunner after the BView is attached to the BWindow it belongs to. Do it in the AttachedToWindow method.

Ahhhh, that makes sense. Thanks! I think it’ll be better for my overall architecture to just handle it via BWindow for now, but I’ll keep that in mind for the future!