Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00025
00028
00029 #ifndef THOR_OWNERSHIPMODELS_HPP
00030 #define THOR_OWNERSHIPMODELS_HPP
00031
00032 #include <Thor/Config.hpp>
00033
00034 #include <Aurora/Meta/Templates.hpp>
00035
00036 #include <memory>
00037 #include <cassert>
00038
00039
00040 namespace thor
00041 {
00042
00045
00046 namespace Resources
00047 {
00048
00056 struct CentralOwner {};
00057
00064 struct RefCounted {};
00065
00066 }
00067
00069
00070
00071
00072
00073 namespace detail
00074 {
00075
00076 template <typename Map>
00077 struct ElementRef
00078 {
00079 Map* map;
00080 typename Map::iterator itr;
00081 };
00082
00083 template <typename Map>
00084 ElementRef<Map> makeElementRef(Map& map, typename Map::iterator itr)
00085 {
00086
00087 ElementRef<Map> ref = {&map, itr};
00088 return ref;
00089 }
00090
00091 template <typename R, typename Map>
00092 struct TrackingDeleter
00093 {
00094 void operator() (R* pointer)
00095 {
00096
00097 if (!tracker.expired())
00098 {
00099
00100 assert(element.map->find(element.itr->first) != element.map->end());
00101 element.map->erase(element.itr);
00102 }
00103
00104
00105 AURORA_REQUIRE_COMPLETE_TYPE(R);
00106 delete pointer;
00107 }
00108
00109 ElementRef<Map> element;
00110 std::weak_ptr<char> tracker;
00111 };
00112
00113
00114 template <typename Model, typename R>
00115 struct OwnershipModel;
00116
00117
00118 template <typename R>
00119 struct OwnershipModel<Resources::CentralOwner, R>
00120 {
00121 typedef R& Returned;
00122 typedef const R& ConstReturned;
00123 typedef std::unique_ptr<R> Loaded;
00124 typedef std::unique_ptr<R> Stored;
00125
00126 static Returned makeReturned(const std::unique_ptr<R>& initialOrStorage)
00127 {
00128 return *initialOrStorage;
00129 }
00130
00131 template <typename Map>
00132 static std::unique_ptr<R> makeLoaded(std::unique_ptr<R>&& resource, ElementRef<Map>&&)
00133 {
00134 return std::move(resource);
00135 }
00136
00137 static std::unique_ptr<R> makeStored(std::unique_ptr<R>&& loaded)
00138 {
00139 return std::move(loaded);
00140 }
00141 };
00142
00143
00144 template <typename R>
00145 struct OwnershipModel<Resources::RefCounted, R>
00146 {
00147 typedef std::shared_ptr<R> Returned;
00148 typedef std::shared_ptr<const R> ConstReturned;
00149
00150
00151
00152 struct Loaded
00153 {
00154 std::shared_ptr<char> tracked;
00155 std::shared_ptr<R> resource;
00156 };
00157
00158
00159
00160 struct Stored
00161 {
00162 std::shared_ptr<char> tracked;
00163 std::weak_ptr<R> resource;
00164 };
00165
00166 static std::shared_ptr<R> makeReturned(const Loaded& loaded)
00167 {
00168 return loaded.resource;
00169 }
00170
00171 static std::shared_ptr<R> makeReturned(const Stored& stored)
00172 {
00173 assert(!stored.resource.expired());
00174 return std::shared_ptr<R>(stored.resource);
00175 }
00176
00177 template <typename Map>
00178 static Loaded makeLoaded(std::unique_ptr<R>&& resource, ElementRef<Map>&& element)
00179 {
00180
00181
00182 auto tracked = std::make_shared<char>();
00183
00184
00185
00186 TrackingDeleter<R, Map> deleter;
00187 deleter.tracker = tracked;
00188 deleter.element = element;
00189
00190
00191 Loaded loaded;
00192 loaded.tracked = std::move(tracked);
00193 loaded.resource = std::shared_ptr<R>(resource.release(), deleter);
00194 return loaded;
00195 }
00196
00197 static Stored makeStored(Loaded&& loaded)
00198 {
00199 Stored stored;
00200 stored.tracked = std::move(loaded.tracked);
00201 stored.resource = std::weak_ptr<R>(loaded.resource);
00202 return stored;
00203 }
00204 };
00205
00206 }
00207 }
00208
00209 #endif // THOR_OWNERSHIPMODELS_HPP