1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: fslow_HandleTable.h 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 46347 $ 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