Very interesting. I didnt know about that pattern yet so thanks!
however, I think I came up with something that is kind of the same with a little twist. A CAnimation is designed to be only used by CAnimationList and CAnimationManager. CAnimationManager manages CAnimationLists with a ZOrder. So I made all the virtual functions private and I made CAnimationList and Manager a friend. The idea is that the programmer maintaining CAnimationList *must* know the inner workings of CAnimation anyways so he has to remember to update the time.
Code:
class CAnimation {
friend class CAnimationList;
friend class CAnimationManager;
public:
explicit CAnimation(unsigned long Timer);
virtual ~CAnimation();
private:
virtual Status Init() = 0;
virtual void Render() = 0;
virtual Status Update(unsigned long TimeElapsed) = 0;
virtual void Cleanup() = 0;
virtual bool IsDone();
};
Then Update of CAnimationList:
Code:
void CAnimationList::Update(unsigned long TimeElapsed)
{
for (AnimIter Anim = m_RenderList.begin(); Anim != m_RenderList.end(); )
{
(void)(*Anim)->CAnimation::Update(TimeElapsed);
if ((*Anim)->Update(TimeElapsed) == CAnimation::DONE)
{
(*Anim)->Cleanup();
Anim = m_RenderList.erase(Anim);
}
else
++Anim; // only increment when erase is not called
}
}
and CAnimationManager call Update for every CAnimationList from lowest Z-Order to highest: (the list is sorted)
Code:
void CAnimationManager::Update(unsigned long TimeElapsed)
{
for_each(m_lists.begin(), m_lists.end(),
bind2nd(mem_fun_ref(&ContainedType::Update), TimeElapsed));
}
I'm kinda happy with this design but when I get time Ill check out and maybe implement the non virtual interface pattern exactly. The only difference I see here is that the interface is still private but I only give access to the classes that must know how to talk to the class.