1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: fslow_HandleTable.h 4 5 Copyright 2010 Nintendo. All rights reserved. 6 These coded instructions, statements, and computer programs contain 7 proprietary information of Nintendo of America Inc. and/or Nintendo 8 Company Ltd., and are protected by Federal copyright law. They may 9 not be disclosed to third parties or copied or duplicated in any form, 10 in whole or in part, without the prior written consent of Nintendo. 11 $Rev: 20673 $ 12 *--------------------------------------------------------------------------- 13 14 */ 15 16 #ifndef NN_FSLOW_FSLOW_HANDLETABLE_H_ 17 #define NN_FSLOW_FSLOW_HANDLETABLE_H_ 18 19 #include <nn.h> 20 #include <nn/util/util_Int64.h> 21 22 23 namespace nn { namespace fslow { 24 25 typedef nn::util::Int64<bit64> HandleValue; 26 27 /*---------------------------------------------------------------------------* 28 * File handle 29 * - <w0[0:7]>fixed value, <w0[8]> enable flag, <w0[9:31],w1[0:31]> incrementable 30 *---------------------------------------------------------------------------*/ 31 class Handle 32 { 33 protected: 34 HandleValue m_Data; 35 36 static const bit32 FIXED_VALUE_MASK = 0x0FF; 37 static const bit32 VALID_FLAG_MASK = 0x100; 38 static const bit32 INCREMENT_VALUE = 0x200; 39 40 public: Handle()41 Handle() 42 { 43 m_Data.lo = 0; 44 m_Data.hi = 0; 45 } 46 Handle(bit8 fixedValue)47 Handle(bit8 fixedValue) 48 { 49 m_Data.lo = fixedValue + INCREMENT_VALUE; 50 m_Data.hi = 0; 51 } 52 Handle(const HandleValue & value)53 Handle(const HandleValue& value) 54 { 55 m_Data.lo = value.lo; 56 m_Data.hi = value.hi; 57 } 58 Initialize(bit8 fixedValue)59 void Initialize(bit8 fixedValue) 60 { 61 NN_TASSERT_(!IsInitialized()); 62 m_Data.lo = fixedValue + INCREMENT_VALUE; 63 } 64 Finalize()65 void Finalize() 66 { 67 m_Data.lo = 0; 68 m_Data.hi = 0; 69 } 70 Validate()71 void Validate() 72 { 73 NN_TASSERT_(IsInitialized()); 74 m_Data.lo |= VALID_FLAG_MASK; 75 } 76 Invalidate()77 void Invalidate() 78 { 79 NN_TASSERT_(IsInitialized()); 80 m_Data.lo &= ~VALID_FLAG_MASK; 81 Increment(); 82 } 83 GetFixedValue()84 bit8 GetFixedValue() const { return static_cast<bit8>(m_Data.lo & FIXED_VALUE_MASK); } IsInitialized()85 bool IsInitialized() const { return (m_Data.lo != 0) || (m_Data.hi != 0); } IsValid()86 bool IsValid() const { return (m_Data.lo & VALID_FLAG_MASK) != 0; } 87 HandleValue()88 operator HandleValue() const { return m_Data; } 89 operator const HandleValue&() const { return m_Data; } 90 operator bool() const { return IsValid(); } 91 92 bool operator!() const { return !IsValid(); } 93 bool operator==(const HandleValue& rhs) const { return (m_Data.lo == rhs.lo) && (m_Data.hi == rhs.hi); } 94 bool operator!=(const HandleValue& rhs) const { return (m_Data.lo != rhs.lo) || (m_Data.hi != rhs.hi); } 95 96 protected: Increment()97 void Increment() 98 { 99 m_Data.lo += INCREMENT_VALUE; 100 if (((m_Data.lo & ~FIXED_VALUE_MASK) == 0) && (++m_Data.hi == 0)) 101 { 102 m_Data.lo += INCREMENT_VALUE; 103 } 104 } 105 }; 106 107 /*---------------------------------------------------------------------------* 108 * Handle table entry 109 *---------------------------------------------------------------------------*/ 110 template<class T> 111 class HandleTableEntry 112 { 113 public: HandleTableEntry()114 HandleTableEntry() {} HandleTableEntry(bit8 fixedValue)115 HandleTableEntry(bit8 fixedValue) { Initialize(fixedValue); } ~HandleTableEntry()116 ~HandleTableEntry() {} 117 118 // Initialization Initialize(bit8 fixedValue)119 void Initialize(bit8 fixedValue) 120 { 121 NN_TASSERT_(!IsInitialized()); 122 m_Handle.Initialize(fixedValue); 123 } 124 125 // Register an object that is tied to this entry Register(const T & object)126 const HandleValue& Register(const T& object) 127 { 128 NN_TASSERT_(!m_Handle.IsValid()); 129 m_Object = object; 130 m_Handle.Validate(); 131 return m_Handle; 132 } 133 134 // Unregister (invalidate the handle) Unregister()135 void Unregister() 136 { 137 NN_TASSERT_(m_Handle.IsValid()); 138 m_Handle.Invalidate(); 139 } 140 GetHandle()141 const HandleValue& GetHandle() const { return m_Handle; } GetObject()142 const T& GetObject() const { return m_Object; } IsInitialized()143 bool IsInitialized() const { return m_Handle.IsInitialized(); } IsValid()144 bool IsValid() const { return m_Handle.IsValid(); } HasHandle(HandleValue value)145 bool HasHandle(HandleValue value) const { return IsValid() && (m_Handle == value); } 146 147 private: 148 Handle m_Handle; 149 T m_Object; 150 }; 151 152 /*---------------------------------------------------------------------------* 153 * Handle table 154 *---------------------------------------------------------------------------*/ 155 template<class T, size_t TNumEntry> 156 class HandleTable 157 { 158 typedef HandleTableEntry<T> TEntry; 159 160 public: HandleTable()161 HandleTable() {} HandleTable(nn::WithInitialize)162 HandleTable(nn::WithInitialize) { Initialize(); } ~HandleTable()163 ~HandleTable() {} 164 165 // Initialization 166 // - Pass index as unique handle value Initialize()167 void Initialize() 168 { 169 for(s32 i = 0; i < TNumEntry; ++i) 170 { 171 m_Entry[i].Initialize(i); 172 } 173 } 174 175 // Register object Register(const T & object)176 const HandleValue& Register(const T& object) 177 { 178 TEntry* pEntry = FindFreeEntry(); 179 NN_TASSERT_(pEntry); 180 return pEntry->Register(object); 181 } 182 183 // Delete object Unregister(const HandleValue & value)184 void Unregister(const HandleValue& value) 185 { 186 TEntry* pEntry = const_cast<TEntry*>(FindEntryFromHandle(value)); 187 NN_TASSERT_(pEntry); 188 pEntry->Unregister(); 189 } 190 191 // Return the object that is tied to the specified handle GetObject(const HandleValue & value)192 const T& GetObject(const HandleValue& value) const 193 { 194 const TEntry* pEntry = FindEntryFromHandle(value); 195 NN_TASSERT_(pEntry); 196 return pEntry->GetObject(); 197 } 198 TryGetObject(T * pObject,const HandleValue & value)199 bool TryGetObject(T* pObject, const HandleValue& value) const 200 { 201 const TEntry* pEntry = FindEntryFromHandle(value); 202 if(pEntry) 203 { 204 *pObject = pEntry->GetObject(); 205 return true; 206 } 207 return false; 208 } 209 210 private: 211 TEntry m_Entry[TNumEntry]; 212 213 // Search for unused entry FindFreeEntry()214 TEntry* FindFreeEntry() 215 { 216 for(s32 i = 0; i < TNumEntry; ++i) 217 { 218 if(!m_Entry[i].IsValid()) 219 { 220 return m_Entry + i; 221 } 222 } 223 return 0; 224 } 225 226 // Search for entries that were registered to the specified handle FindEntryFromHandle(const HandleValue & value)227 const TEntry* FindEntryFromHandle(const HandleValue& value) const 228 { 229 // Index is inserted into the fixed portion, so use it 230 Handle handle(value); 231 s32 index = handle.GetFixedValue(); 232 233 if(index < TNumEntry) 234 { 235 return m_Entry[index].HasHandle(value) ? (m_Entry + index) : 0; 236 } 237 return 0; 238 } 239 }; 240 241 }} 242 243 #endif // #ifndef NN_FSLOW_FSLOW_HANDLETABLE_H_ 244