1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_SharedAnimCache.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_GFX_SHAREDANIMCACHE_H_
19 #define NW_GFX_SHAREDANIMCACHE_H_
20 
21 #include <nw/gfx/gfx_GfxObject.h>
22 
23 namespace nw {
24 namespace gfx {
25 
26 //---------------------------------------------------------------------------
27 //! @brief 共有可能なアニメーションキャッシュのクラスです。
28 //!
29 //! 複数の AnimEvaluator で共有することができるキャッシュクラスです。
30 //! アニメーション結果を共有する場合、キャッシュ結果を流用することで高速化が期待できます。
31 //!
32 //! @sa nw::gfx::AnimEvaluator::SetSharedCacheBuffer
33 //---------------------------------------------------------------------------
34 class SharedAnimCache : public GfxObject
35 {
36 public:
37     //! @brief 共有アニメキャッシュの生成用クラスです。
38     class Builder
39     {
40     public:
41         //! @brief コンストラクタです。
Builder()42         Builder()
43         : m_AnimDataPtr(NULL),
44           m_CacheBufferSize(0)
45         {
46         }
47 
48         //! @brief 対象のアニメーションを設定します。
AnimData(anim::ResAnim animData)49         Builder& AnimData(anim::ResAnim animData)
50         {
51             m_AnimDataPtr = animData.ptr();
52             return *this;
53         }
54 
55         //! @brief 確保するキャッシュのサイズを設定します。
56         //!
57         //! nw::gfx::AnimEvaluator::GetCacheBufferSizeNeeded() を利用して、必要なサイズが求められます。
CacheBufferSize(int size)58         Builder& CacheBufferSize(int size)
59         {
60             m_CacheBufferSize = size;
61             return *this;
62         }
63 
64         //! @brief 共有可能なアニメーションキャッシュを生成します。
65         //!
66         //! @param[in] allocator アロケータです。
67         //!
68         //! @return 生成したアニメーションキャッシュです。
69         //!
Create(os::IAllocator * allocator)70         SharedAnimCache* Create(os::IAllocator* allocator)
71         {
72             void* memory = allocator->Alloc(sizeof(SharedAnimCache));
73             if (memory == NULL)
74             {
75                 return NULL;
76             }
77 
78             SharedAnimCache* result = new(memory) SharedAnimCache(allocator);
79             result->SetAnimData(m_AnimDataPtr);
80 
81             bool cacheBufferAlloced = result->AllocBuffer(m_CacheBufferSize);
82             if (!cacheBufferAlloced)
83             {
84                 result->~SharedAnimCache();
85                 allocator->Free(result);
86                 return NULL;
87             }
88 
89             return result;
90         }
91 
92     private:
93         anim::ResAnimData* m_AnimDataPtr;
94         int m_CacheBufferSize;
95     };
96 
97     //! @brief デストラクタです。
98     //!
~SharedAnimCache()99     virtual ~SharedAnimCache()
100     {
101         DestroyCache();
102     }
103 
104     // キャッシュ更新のために必要なインターフェースです。
105     // ユーザーが直接操作することは想定されていません。
SetFrame(f32 frame)106     void SetFrame(f32 frame) { m_Frame = frame; } //!< @details :private
GetFrame()107     f32 GetFrame() const { return m_Frame; } //!< @details :private
SetStepFrame(f32 stepFrame)108     void SetStepFrame(f32 stepFrame) { m_StepFrame = stepFrame; } //!< @details :private
GetStepFrame()109     f32 GetStepFrame() const { return m_StepFrame; } //!< @details :private
110     // キャッシュには書き込まないといけないのでconstではない
GetCacheBuffer()111     void* GetCacheBuffer() { return m_CacheBuf; } //!< @details :private
IsDirty()112     bool IsDirty() const { return m_IsDirty; } //!< @details :private
SetDirtyFlag(bool isDirty)113     void SetDirtyFlag(bool isDirty) { m_IsDirty = isDirty; } //!< @details :private
114 
115 private:
SetAnimData(const anim::ResAnimData * animData)116     void SetAnimData(const anim::ResAnimData* animData)
117     {
118         m_AnimData = anim::ResAnim(animData);
119     }
120 
AllocBuffer(int cacheBufferSize)121     bool AllocBuffer(int cacheBufferSize)
122     {
123         // バッファの確保ができなかった場合はfalseを返し、生成の成否を判断する
124         if (0 < cacheBufferSize)
125         {
126             NW_ASSERT(m_CacheBuf == NULL);
127             m_CacheBuf = GetAllocator().Alloc(cacheBufferSize);
128             return (m_CacheBuf != NULL);
129         }
130 
131         return false;
132     }
133 
SharedAnimCache(os::IAllocator * allocator)134     explicit SharedAnimCache(os::IAllocator* allocator)
135     : GfxObject(allocator),
136       m_CacheBuf(NULL),
137       m_AnimData(NULL),
138       m_Frame(0.0f),
139       m_StepFrame(0.0f),
140       m_IsDirty(true)
141     {
142     }
143 
DestroyCache()144     NW_INLINE void DestroyCache()
145     {
146         if (m_CacheBuf != NULL)
147         {
148             os::SafeFree(m_CacheBuf, &GetAllocator());
149         }
150     }
151 
152     void* m_CacheBuf;
153     // キャッシュのインデックスはAnimEvaluatorのCachePtrを使うので持たない。
154     // このクラスが持つのは、フレーム、データのポインタなど、アニメの状態を一意に決定する情報。
155     anim::ResAnim m_AnimData;
156     f32 m_Frame;
157     f32 m_StepFrame;
158     bool m_IsDirty;
159 };
160 
161 } // namespace gfx
162 } // namespace nw
163 
164 #endif //  NW_GFX_SHAREDANIMCACHE_H_
165