Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Problem Writing My Own Event System Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
almostconnected

March 15, 2005, 09:44 PM

Hello all,

So Im writing a game in C++ and for fun I created a simple event system. It usually works fine but sometimes my code generates an odd run-time error. (Im using VS.NET) Anyway, let me start with a snip of my code:

  1.  
  2. class EventHandler { } // classes that want to handle events inherit this
  3.  
  4. class MemberCallBack
  5. {
  6.         typedef void (EventHandler::*Method) (void *);
  7.  
  8. protected:
  9.  
  10.         EventHandler *that;
  11.         Method call;
  12.  
  13. public:
  14.  
  15.         MemberCallBack (void) :
  16.           call (0) { };
  17.  
  18.         template <class X>
  19.         void Set (X *x, void (X::*callback) (void*))
  20.         {
  21.                 that = x;   // sometimes this is set just off the correct value
  22.                 call = (Method) callback;
  23.         }
  24.  
  25.         void Clear (void);
  26.        
  27.         void operator ( )(void *param = 0);
  28.         bool operator ==(const MemberCallBack &test);
  29. };
  30.  


so a class that triggers events looks something like this:

  1.  
  2. struct Something
  3. {
  4.         MemberCallBack trigger;
  5.  
  6.         void DoStuff (void)
  7.         {
  8.                 trigger ( );
  9.         }
  10. }
  11.  


and an object that wants to catch the event does this:

  1.  
  2. Something something;
  3.  
  4. // ...
  5.  
  6. struct Watcher : public EventHandler
  7. {
  8.         void Init (void)
  9.         {
  10.                 something.trigger.Set (this, OnTrigger);
  11.         }
  12.  
  13.         void OnTrigger (void *p)
  14.         {
  15.                 // called when something.trigger ( ) is called handle event
  16.         }
  17. }
  18.  


So this seemed to work great for what I needed it for, but on a couple of occasions it just refused to work. I stepped through MemberCallBack::Set and I think I found the problem. The first line does not always set that to x. Sometimes it is slightly off. Here are some sample memory address:

x == 0x004c1e84
that == 0x004c1e88

x == 0x003ff1b8
that == 0x003ff1bc

Whats going on? The first time it happened, I recompiled the code in Release mode (as opposed to Debug mode) and that seemed to fix it. Now I am having the problem again and nothing I do fixes it. Any suggestions?

almostconnected

 
Reedbeta

March 16, 2005, 12:18 AM

Instead of making it a template function, why don't you let x be of type EventHandler*? This will work when you call Set, since every class that calls it will be a descendant of EventHandler.

 
I'M BRIAN FELLOWS

March 16, 2005, 12:24 PM

THAT IS THE DEVIL'S CODE.

 
Chris

March 16, 2005, 12:40 PM

The offset is related to inheritance issues, only I don't remember when exactly it occurrs. You're casting class pointers up or down the inheritance tree, either explicitely or implicitely through function calls. I bet it works fine whenever you can make sure that no cast is involved.

 
almostconnected

March 16, 2005, 02:04 PM

I'm not using virtual or multiple inheritance anywhere, so I would think that problem would be avoided (maybe this is an incorrect assumption?).

 
almostconnected

March 16, 2005, 02:08 PM

lol

What's wrong with the way I code? :)

 
Alex Herz

March 16, 2005, 06:18 PM

can u get something asm like out of the .net code?
Would be interesting to see what the compiler actually does to produce this effect.

Alex

 
Brian Legge

March 16, 2005, 09:35 PM

Type safety is a good thing. Why do you need to perform the cast
'call = (Method) callback;'?

 
almostconnected

March 16, 2005, 10:51 PM

Everyone:

Btw, I am not using virtual or multiple inheritance in my code. I could see how that would have made casting 'x' a problem, but since I'm not using them, I would think X* would cast to EventHandler* just fine. I'm not so sure about the Method cast but it seems to me like it should work. (Please correct me if I am wrong).

Reedbeta:

The reason I used a template is because 'void (X::*callback) (void*)' (where X is inherited from EventHandler) does not automatically cast to 'void (EventHandler::*callback) (void*)'. If I don't use templates then I have to define my method like:

  1. void Set (EventHandler *x, Method callback) { ... }


But when I do this I have to cast the second parameter on my call to Set. Like this:

  1. something.trigger.Set (this, (MemberCallBack::Method) OnTrigger);


So thats not terrible, but I don't like it, so that is why I used a template.

Anyway, I tryed it without templates and I still have the same problem. Only now the value of 'x' is incorrect on entering the Set method.

 
This thread contains 9 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.