Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


#Actualmetsfan

Posted 24 May 2013 - 07:48 PM

 

  • For instance, there is no reason for a sound object to contain a pointer to a physics object. Keep your systems separate and join them using a higher level interface.

Well, this is where it gets tricky for me. The APIs for sound and graphics are different systems. I can encapsulate them in my own classes and simplify the interfaces for my use. But for example there has to be a place in the code where a sound is triggered when the animation passes a point. We are now far down a method in the animation class and we discover that we need to trigger a sound. Where is the pointer to the sound interface when we are in the animation system?

Globals?
Singletons?
Coupling by having a pointer to the sound system as a member in the animation class?

Having a higher level interface that calls the DoAnimation() method, I need return values in order to call DoSound() afterwards. But I just shuffle the burden up the food chain. Now I have to code a ton of different states that must be passed and returned and bloat the calling code, making it more complex.

The way I handle this is with callbacks. For instance, let's take a Rock object as an example. A Rock object falls to the ground, and when it hits the ground, it should trigger a "thump" sound.

 

typedef std::function<void()> DelegateFunction; 

class Rock {  
  Sound mSound;  
  Animation mFallAnimation;    
  Rock()  
  {     
    DelegateFunction delegate = std::bind(&Rock::FallAnimationEnded, *this);     
    mFallAninmation.addDelegate(delegate);     
    mFallAnimation.Start();  
  }  

  void FallAnimationEnded()  
  {     
    mSound.Play();  
  }
};

class Animation
{   
  std::vector<DelegateFunction> mDelegates;  
  void AddDelegate(DelegateFunction func) { mDelegates.push_back(func); }  

  void Start(); // Begins a timer, or adds it to an animation manager, however you want to do this.  

  void Update() // Called every animation update  
  {    
    if(animationStillRunning) 
    {      
      this->UpdateAnimationStuff();    
    } else {     
      for(int i = 0; i < mDelegates.size(); i++) {         
        mDelegates[i]();      
      }  
    }
  }
};

 

 

So as you can see, we have no coupling between our Sound system or Animation system. The Rock is created, it will attach its FallAnimationEnded member function to the animation's delegate list, and when the animation is done, it will call all registered delegates. Obviously this code is far from complete and I'm not even sure if all my syntax is correct, but the idea should be clear.


#2metsfan

Posted 24 May 2013 - 07:46 PM


  • For instance, there is no reason for a sound object to contain a pointer to a physics object. Keep your systems separate and join them using a higher level interface.

Well, this is where it gets tricky for me. The APIs for sound and graphics are different systems. I can encapsulate them in my own classes and simplify the interfaces for my use. But for example there has to be a place in the code where a sound is triggered when the animation passes a point. We are now far down a method in the animation class and we discover that we need to trigger a sound. Where is the pointer to the sound interface when we are in the animation system?

Globals?
Singletons?
Coupling by having a pointer to the sound system as a member in the animation class?

Having a higher level interface that calls the DoAnimation() method, I need return values in order to call DoSound() afterwards. But I just shuffle the burden up the food chain. Now I have to code a ton of different states that must be passed and returned and bloat the calling code, making it more complex.

The way I handle this is with callbacks. For instance, let's take a Rock object as an example. A Rock object falls to the ground, and when it hits the ground, it should trigger a "thump" sound.
class Rock{  Sound mSound;  Animation mFallAnimation;    Rock()  {     DelegateFunction delegate = std::bind(&Rock::FallAnimationEnded, *this);     mFallAninmation.addDelegate(delegate);     mFallAnimation.Start();  }  void FallAnimationEnded()  {     mSound.Play();  }};class Animation{  typedef std::function<void()> DelegateFunction;  std::vector<DelegateFunction> mDelegates;  void AddDelegate(DelegateFunction func) { mDelegates.push_back(func); }  void Start(); // Begins a timer, or adds it to an animation manager, however you want to do this.  void Update() // Called every animation update  {    if(animationStillRunning) {      this->UpdateAnimationStuff();    } else {      for(int i = 0; i < mDelegates.size(); i++) {         mDelegates[i]();      }  }}
So as you can see, we have no coupling between our Sound system or Animation system. The Rock is created, it will attach its FallAnimationEnded member function to the animation's delegate list, and when the animation is done, it will call all registered delegates. Obviously this code is far from complete and I'm not even sure if all my syntax is correct, but the idea should be clear.

#1metsfan

Posted 24 May 2013 - 07:45 PM


 

  • For instance, there is no reason for a sound object to contain a pointer to a physics object.  Keep your systems separate and join them using a higher level interface.

 

Well, this is where it gets tricky for me. The APIs for sound and graphics are different systems. I can encapsulate them in my own classes and simplify the interfaces for my use. But for example there has to be a place in the code where a sound is triggered when the animation passes a point. We are now far down a method in the animation class and we discover that we need to trigger a sound. Where is the pointer to the sound interface when we are in the animation system?

 

Globals?

Singletons?

Coupling by having a pointer to the sound system as a member in the animation class?

 

Having a higher level interface that calls the DoAnimation() method, I need return values in order to call DoSound() afterwards. But I just shuffle the burden up the food chain. Now I have to code a ton of different states that must be passed and returned and bloat the calling code, making it more complex.

 

The way I handle this is with callbacks.  For instance, let's take a Rock object as an example.  A Rock object falls to the ground, and when it hits the ground, it should trigger a "thump" sound.  

 

class Rock
{
  Sound mSound;
  Animation mFallAnimation; 
 
  Rock()
  {
     DelegateFunction delegate = std::bind(&Rock::FallAnimationEnded, *this);
     mFallAninmation.addDelegate(delegate);
     mFallAnimation.Start();
  }

  void FallAnimationEnded()
  {
     mSound.Play();
  }
};

class Animation
{
  typedef std::function<void()> DelegateFunction;

  std::vector<DelegateFunction> mDelegates;

  void AddDelegate(DelegateFunction func) { mDelegates.push_back(func); }

  void Start(); // Begins a timer, or adds it to an animation manager, however you want to do this.

  void Update() // Called every animation update
  {
    if(animationStillRunning) {
      this->UpdateAnimationStuff();
    } else {
      for(int i = 0; i < mDelegates.size(); i++) {
         mDelegates[i]();
      }
  }
} 

So as you can see, we have no coupling between our Sound system or Animation system.  The Rock is created, it will attach its FallAnimationEnded member function to the animation's delegate list, and when the animation is done, it will call all registered delegates.  Obviously this code is far from complete and I'm not even sure if all my syntax is correct, but the idea should be clear.


PARTNERS