00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #pragma once
00018
00019 #include "AIErrorHandler.h"
00020 #include <memory>
00021
00024 namespace ai
00025 {
00026
00081 template <typename Attribute_t, typename Bit_t>
00082 class BooleanAttributeCache
00083 {
00084 public:
00085
00086
00087 bool GetValue(Attribute_t inAttr, bool& outValue) const AINOEXCEPT
00088 {
00089 const auto initialized = IsInitialized(inAttr);
00090 if (initialized)
00091 {
00092 outValue = ((fAttrBits & AttributeToBits(inAttr)) ? true : false);
00093 }
00094 return initialized;
00095 }
00096 void SetValue(Attribute_t inAttr, const bool inValue) AINOEXCEPT
00097 {
00098 const auto flagBit = AttributeToBits(inAttr);
00099 if (inValue)
00100 {
00101 fAttrBits |= flagBit;
00102 }
00103 else
00104 {
00105 fAttrBits &= ~flagBit;
00106 }
00107 fInitBits |= flagBit;
00108 }
00109 void Clear() AINOEXCEPT
00110 {
00111 fInitBits = fAttrBits = 0;
00112 }
00113
00114 private:
00115 bool IsInitialized(Attribute_t inAttr) const AINOEXCEPT
00116 {
00117 return ((fInitBits & AttributeToBits(inAttr)) ? true : false);
00118 }
00119 Bit_t AttributeToBits(Attribute_t inAttr) const AINOEXCEPT
00120 {
00121 return (1 << static_cast<Bit_t>(inAttr));
00122 }
00123
00124 private:
00125 Bit_t fAttrBits{ 0 }, fInitBits{ 0 };
00126 };
00127
00128
00145 template <typename Cache_t>
00146 class CacheScopeManager
00147 {
00148 public:
00149 CacheScopeManager() : CacheScopeManager{ false } {}
00150 virtual ~CacheScopeManager()
00151 {
00152 try
00153 {
00154 if (fSuppressor)
00155 {
00156 if (CacheSuppressCount() == 1 && CacheRefCount() != 0)
00157 {
00158 Cache() = std::make_unique<Cache_t>();
00159 --CacheSuppressCount();
00160 }
00161 }
00162 else
00163 {
00164 if (CacheSuppressCount() == 0 && CacheRefCount() == 1)
00165 {
00166 Cache().reset();
00167 --CacheRefCount();
00168 }
00169 }
00170 }
00171 AI_CATCH_ASSERT_NO_RETURN
00172 }
00173
00174 static bool IsCacheValid() AINOEXCEPT
00175 {
00176 return GetCache() != nullptr;
00177 }
00178
00179 static Cache_t* GetCache() AINOEXCEPT
00180 {
00181 return Cache().get();
00182 }
00183
00184 protected:
00185 CacheScopeManager(bool suppressor) : fSuppressor{ suppressor }
00186 {
00187 if (fSuppressor)
00188 {
00189 if (CacheSuppressCount() == 0 && CacheRefCount() != 0)
00190 {
00191 Cache().reset();
00192 ++CacheSuppressCount();
00193 }
00194 }
00195 else
00196 {
00197 if (CacheSuppressCount() == 0 && CacheRefCount() == 0)
00198 {
00199 Cache() = std::make_unique<Cache_t>();
00200 ++CacheRefCount();
00201 }
00202 }
00203 }
00204
00205 private:
00206 static std::unique_ptr <Cache_t>& Cache()
00207 {
00208 static std::unique_ptr <Cache_t> sCache;
00209 return sCache;
00210 }
00211
00212 static size_t& CacheRefCount() AINOEXCEPT
00213 {
00214 static size_t sCacheRefCount{ 0 };
00215 return sCacheRefCount;
00216 }
00217
00218 static size_t& CacheSuppressCount() AINOEXCEPT
00219 {
00220 static size_t sCacheSuppressCount{ 0 };
00221 return sCacheSuppressCount;
00222 }
00223
00224 private:
00225 const bool fSuppressor;
00226 };
00227
00244 template <typename Cache_t>
00245 class CacheScopeSuppressor : public CacheScopeManager <Cache_t>
00246 {
00247 public:
00248 CacheScopeSuppressor() : CacheScopeManager <Cache_t> { true } {}
00249 };
00250
00251 }