Is it okay to use a reference instead of a pointer in this case?

Started by
20 comments, last by Drakkcon 16 years, 2 months ago
Quote:Original post by stonemetal
Probably because it is considered a poor programming practice to hand out your privates. Normally you would see it in reverse. Where things register with the event dispatcher which would then pole them for events and push them out to listeners.


What privates are being handed out? The handler's interface has only a single function for handling events. Pass a handler to dispatcher and whenever a listener wants to raise an event it tells the dispatcher to send the event to the proper handlers.

My problem is that I need the listeners to know which dispatcher is responsible for raising the event, since dispatcher is not a singleton. Thus, they need some kind of pointer. I tried using references but I have never seen that before.

Forget about the std::list<x&>, my actual design does not use that. Sorry for miscommunicating.
Advertisement
bitten
The class VideoSystem:
class VideoSystem {private:  const EventDispatcher& dispatcher;public:  VideoSystem(const EventDispatcher& dispatcher) : dispatcher(dispatcher) {     dispatcher.RaiseEvent(VideoSystemCreatedEvent());  }};


Will not be stored in an STL container.
Also, thanks for your help everyone, specifically SiCrane, ToohrVyk, and mossmoss. Sorry again for the miscommunication that confused everyone into thinking that I have a list of references stored in an STL container.
class Game {
private:
VideoSystem video;
EventDispatcher dispatcher;

^^^ is a private.
Game() : video(dispatcher) {
^^^^
that is being handed out to any thing that wishes to use the event dispatcher, or am I confused?

I would put a super class for video that had the post event function and an internal queue of events make event dispatcher have a friend function that pulled events out of the queue then processed them.
Quote:
that is being handed out to any thing that wishes to use the event dispatcher, or am I confused?


No, it's only being handed out to that specific VideoSystem instance.
Quote:Original post by stonemetal
class Game {
private:
VideoSystem video;
EventDispatcher dispatcher;

^^^ is a private.
Game() : video(dispatcher) {
^^^^
that is being handed out to any thing that wishes to use the event dispatcher, or am I confused?

I would put a super class for video that had the post event function and an internal queue of events make event dispatcher have a friend function that pulled events out of the queue then processed them.


This is fine: the dependency is inverted. We would have a design problem if the VideoSystem *took* the EventDispatcher from game (e.g. by an accessor).

Quote:Original post by Drakkcon
I realized that this wouldn't work because my EventDispatcher is allocated on the stack


Er, how exactly is that? Do you just create a local Game instance in main() or something?
Quote:
Er, how exactly is that? Do you just create a local Game instance in main() or something?


Yes, actually:
int main(int, char**) {    Game game;    game.Run();     return 0;}
Good :) You may want to flesh that out a little (e.g. stuff argv into a vector<string> and pass it to the constructor; catch exceptions and report errors). But yeah, there's no especially good reason I can think of not to have the Game class give references to its subsystems to each other. It's certainly nicer than working with Singletons. :)

(EDIT: Careful of order of initialization! And if you have a cyclic dependency, you'll have to use pointers, because references must be initialized, and there's a chicken-and-egg problem with the initialization.)

But you should consider, for each pair of subsystems, if they really need to talk to each other like that. Consider, for example: instead of talking to a SoundManager, construct a Sound object. The Sound object can register itself with a Manager if needed (or simply play with static data of the class), but the calling code needn't know that Manager (or static data) exists. This is how we get object-oriented ;)
Quote:
(EDIT: Careful of order of initialization! And if you have a cyclic dependency, you'll have to use pointers, because references must be initialized, and there's a chicken-and-egg problem with the initialization.)


Ooo, I didn't even think of that. Thanks for warning me, I'll try to avoid that. It seems similar to the circular reference problem with shared_ptrs (except dealing with initialization and not freeing).

Quote:
But you should consider, for each pair of subsystems, if they really need to talk to each other like that. Consider, for example: instead of talking to a SoundManager, construct a Sound object. The Sound object can register itself with a Manager if needed (or simply play with static data of the class), but the calling code needn't know that Manager (or static data) exists. This is how we get object-oriented ;)

This is a flaw in my current project right now. The way I originally envisioned it, I would create the individual parts of my engine like middleware (they don't talk to each other), and then create an event system. The components would not be aware of the event system so I would wrap them with manager classes that would expose methods allowing me to create, destroy, and perform special actions with objects, referenced with a string and using std::map. These managers would raise events whenever you did any of these things.

This seems like a pretty clunky system now that I look at it (especially the name-based lookup). I'm not really sure how I would do such a thing now. I guess you'd have to make each class event-aware, but then how would you tie in 3rd-party libraries to your engine? I was reading the book "Game Coding Complete" and Mike McShaffrey recommends strongly that you do event based programming, but I really don't see what the benefits are.

Anyway thanks for all your advice on my code, and also advice you've given to me in the past. Do you have a website for all the coding you do? They say "don't read source code" but I get the feeling that reading yours would be pretty educational =)

This topic is closed to new replies.

Advertisement