#pragma once #include "Type.h" #include "../eterbase/Random.h" #include "../eterlib/Pool.h" class CParticleInstance; namespace NEffectUpdateDecorator { class CDecoratorData { public: float fTime; float fElapsedTime; CParticleInstance * pInstance; CDecoratorData(float fTime, float fElapsedTime, CParticleInstance * pInstance) : fTime(fTime), fElapsedTime(fElapsedTime), pInstance(pInstance) {} }; class CBaseDecorator { friend class CParticleSystemData; public: CBaseDecorator() :m_NextDecorator(0), m_PrevDecorator(0) {} virtual ~CBaseDecorator(){} void Excute(const CDecoratorData & d) { CBaseDecorator* pd = this; while(pd) { CBaseDecorator* pNextDecorator = pd->m_NextDecorator; pd->__Excute(d); pd = pNextDecorator; } } CBaseDecorator * AddChainFront(CBaseDecorator * pd) { pd->m_NextDecorator = this; m_PrevDecorator = pd; return pd; } void DeleteThis() { //return; if (m_NextDecorator) m_NextDecorator->DeleteThis(); delete this; } CBaseDecorator * Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) { CBaseDecorator * pNewDecorator = __Clone(pFirstInstance, pInstance); CBaseDecorator * pSrc = this; CBaseDecorator * pDest = pNewDecorator; while (pSrc->m_NextDecorator) { pDest->m_NextDecorator = pSrc->m_NextDecorator->__Clone(pFirstInstance, pInstance); pDest->m_NextDecorator->m_PrevDecorator = pDest; pSrc = pSrc->m_NextDecorator; pDest = pDest->m_NextDecorator; } return pNewDecorator; } protected: virtual void __Excute(const CDecoratorData & d) = 0; virtual CBaseDecorator* __Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) = 0; void RemoveMe() { m_PrevDecorator->m_NextDecorator = m_NextDecorator; m_NextDecorator->m_PrevDecorator=m_PrevDecorator; delete this; } CBaseDecorator * m_NextDecorator; CBaseDecorator * m_PrevDecorator; }; class CHeaderDecorator : public CBaseDecorator, public CPooledObject { public: CHeaderDecorator() {} virtual ~CHeaderDecorator() {} protected: virtual void __Excute(const CDecoratorData&) {} virtual CBaseDecorator* __Clone(CParticleInstance*, CParticleInstance*) { return new CHeaderDecorator; } }; class CNullDecorator : public CBaseDecorator, public CPooledObject { public: CNullDecorator(){} virtual ~CNullDecorator(){} protected: virtual void __Excute(const CDecoratorData & d) {} virtual CBaseDecorator* __Clone(CParticleInstance*, CParticleInstance* ) { return new CNullDecorator; } }; template class CTimeEventDecorator : public CBaseDecorator, public CPooledObject > { public: typedef CTimeEvent TTimeEventType; typedef std::vector TTimeEventContainerType; CTimeEventDecorator(const TTimeEventContainerType& TimeEventContainer, T * pValue = 0) : it_start(TimeEventContainer.begin()), it_cur(TimeEventContainer.begin()), it_next(TimeEventContainer.begin()), it_end(TimeEventContainer.end()), pData(pValue) { if (it_start == it_end) *pValue = T(); else ++it_next; } virtual ~CTimeEventDecorator() {} void SetData( T * pValue ) { pData = pValue; } protected: //CTimeEventDecorator(CTimeEventDecorator& ted, CParticleInstance * pFirstInstance, CParticleInstance * pInstance); CTimeEventDecorator(CTimeEventDecorator& ted, CParticleInstance* pFirstInstance, CParticleInstance* pInstance) : it_start(ted.it_start), it_end(ted.it_end), it_cur(ted.it_cur), it_next(ted.it_next), pData((T*)( (unsigned char*)ted.pData - (DWORD)pFirstInstance + (DWORD)pInstance)) { if (it_start == it_end) *pData = T(); } virtual CBaseDecorator* __Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) { return new CTimeEventDecorator(*this, pFirstInstance, pInstance); } virtual void __Excute(const CDecoratorData & d) { if (it_start==it_end) { RemoveMe(); } else if (it_cur->m_fTime>d.fTime) { *pData = it_cur->m_Value; } else { while (it_next!=it_end && it_next->m_fTime<=d.fTime) ++it_cur, ++it_next; if (it_next == it_end) { // setting value *pData = it_cur->m_Value; RemoveMe(); } else { float length = it_next->m_fTime - it_cur->m_fTime; //*pData = it_cur->m_Value + (it_next->m_Value - it_cur->m_Value)*(d.fTime-it_cur->m_fTime)/length; *pData = it_cur->m_Value*(1-(d.fTime-it_cur->m_fTime)/length) ; *pData += it_next->m_Value * ((d.fTime-it_cur->m_fTime)/length); } } } typename TTimeEventContainerType::const_iterator it_start; typename TTimeEventContainerType::const_iterator it_end; typename TTimeEventContainerType::const_iterator it_cur; typename TTimeEventContainerType::const_iterator it_next; T * pData; }; typedef CTimeEventDecorator CScaleValueDecorator; typedef CTimeEventDecorator CColorValueDecorator; typedef CTimeEventDecorator CColorAllDecorator; typedef CTimeEventDecorator CAirResistanceValueDecorator; typedef CTimeEventDecorator CGravityValueDecorator; typedef CTimeEventDecorator CRotationSpeedValueDecorator; class CTextureAnimationCWDecorator : public CBaseDecorator, public CPooledObject { public: CTextureAnimationCWDecorator(float fFrameTime, DWORD n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} virtual ~CTextureAnimationCWDecorator(){} protected: virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationCWDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } virtual void __Excute(const CDecoratorData & d) { fLastFrameTime -= d.fElapsedTime; while (fLastFrameTime<0.0f) { fLastFrameTime += fFrameTime; if (++(*pIdx) >= n) *pIdx = 0; } } DWORD n; float fLastFrameTime; float fFrameTime; BYTE* pIdx; }; class CTextureAnimationCCWDecorator : public CBaseDecorator, public CPooledObject { public: CTextureAnimationCCWDecorator(float fFrameTime, BYTE n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} virtual ~CTextureAnimationCCWDecorator(){} protected: virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationCCWDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } virtual void __Excute(const CDecoratorData & d) { fLastFrameTime -= d.fElapsedTime; while (fLastFrameTime<0.0f) { fLastFrameTime += fFrameTime; if (--(*pIdx) >= n && n != 0) // Because variable is unsigned.. *pIdx = BYTE(n - 1); } } BYTE n; float fLastFrameTime; float fFrameTime; BYTE* pIdx; }; class CTextureAnimationRandomDecorator : public CBaseDecorator, public CPooledObject { public: CTextureAnimationRandomDecorator(float fFrameTime, BYTE n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} virtual ~CTextureAnimationRandomDecorator(){} protected: virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationRandomDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } virtual void __Excute(const CDecoratorData & d) { fLastFrameTime -= d.fElapsedTime; if (fLastFrameTime<0.0f && n!=0) { *pIdx = (BYTE)random_range(0,n-1); } while (fLastFrameTime<0.0f) fLastFrameTime += fFrameTime; } BYTE n; float fLastFrameTime; float fFrameTime; BYTE* pIdx; }; class CAirResistanceDecorator : public CBaseDecorator, public CPooledObject { public: CAirResistanceDecorator(){} virtual ~CAirResistanceDecorator(){} protected: virtual void __Excute(const CDecoratorData & d); virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi); }; class CGravityDecorator : public CBaseDecorator, public CPooledObject { public: CGravityDecorator(){} virtual ~CGravityDecorator(){} protected: virtual void __Excute(const CDecoratorData& d); virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi); }; class CRotationDecorator : public CBaseDecorator, public CPooledObject { public: CRotationDecorator(){} virtual ~CRotationDecorator() { } protected: virtual void __Excute(const CDecoratorData& d); virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) ; }; }