Last active
August 29, 2015 13:55
-
-
Save ignisan/8710717 to your computer and use it in GitHub Desktop.
cocos2d::Objectを継承しているとintrusive_ptrになる。そうでない場合はshared_ptrになる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include<memory> | |
#include<type_traits> | |
#include"cocos2d.h" | |
#include"IsBaseOf.hpp" | |
static void intrusive_ptr_add_ref(cocos2d::Object* p) { | |
p->retain(); | |
// std::cout << "retain:" << p << "," << p->getReferenceCount() << std::endl; | |
} | |
static void intrusive_ptr_release(cocos2d::Object* p) { | |
p->release(); | |
// std::cout << "release:" << p << "," << p->getReferenceCount() << std::endl; | |
} | |
#include<boost/intrusive_ptr.hpp> | |
namespace ignis { | |
namespace detail { | |
template<typename T,bool> | |
struct cocosptr { | |
typedef boost::intrusive_ptr<T> type; | |
} ; | |
template<typename T> | |
struct cocosptr<T,false> { | |
typedef std::shared_ptr<T> type; | |
}; | |
template<typename T, typename... Types> | |
typename cocosptr<T,true>::type | |
make_cocosptr(std::true_type, Types... args) { | |
return typename cocosptr<T,true>::type(new T(args...), false); | |
} | |
template<typename T, typename... Types> | |
typename cocosptr<T,false>::type | |
make_cocosptr(std::false_type, Types... args) { | |
return std::make_shared<T>(args...); | |
} | |
} | |
template<typename T> | |
using cocosptr = typename detail::cocosptr<T,IsBaseOf<cocos2d::Object,T>::value>::type; | |
template<typename T, typename... Types> | |
cocosptr<T> make_cocosptr(Types... args) { | |
using integral_type = typename IsBaseOf<cocos2d::Object,T>::type; | |
return detail::make_cocosptr<T>(integral_type(),args...); | |
} | |
namespace detail { | |
template<typename T> | |
typename cocosptr<T,true>::type // intrusive_ptr | |
convert_from(std::true_type, T* ptr) { | |
if(cocos2d::PoolManager::getInstance()->getCurrentPool()->contains(ptr)) { | |
return typename cocosptr<T,true>::type(ptr, true); | |
} | |
else { | |
return typename cocosptr<T,true>::type(ptr, true); | |
} | |
} | |
template<typename T> | |
typename cocosptr<T,false>::type // shared_ptr | |
convert_from(std::false_type, T* ptr) { | |
return typename cocosptr<T,false>::type(ptr); | |
} | |
} | |
template<typename T> | |
cocosptr<T> convert_from(T* ptr) { | |
using integral_type = typename IsBaseOf<cocos2d::Object,T>::type; | |
return detail::convert_from(integral_type(), ptr); | |
} | |
template<typename T, typename... Types> | |
cocosptr<T> create(Types... args) { | |
return convert_from(T::create(args...)); | |
} | |
} | |
/* | |
class CocosClass : public cocos2d::Object { | |
public: | |
ignis::cocosptr<CocosClass> func() | |
{ | |
auto p = ignis::cocosptr<CocosClass>(new CocosClass,false); | |
return p; | |
} | |
CocosClass() | |
{ | |
CCLOG("new CocosClass, %d",getReferenceCount()); | |
} | |
~CocosClass() | |
{ | |
CCLOG("delete CocosClass, %d",getReferenceCount()); | |
} | |
}; | |
class SomeClass { | |
public: | |
SomeClass() { | |
CCLOG("new SomeClass"); | |
} | |
~SomeClass() { | |
CCLOG("delete SomeClass"); | |
} | |
}; | |
void func() { | |
auto p = ignis::cocosptr<SomeClass>(new SomeClass); | |
p = ignis::make_cocosptr<SomeClass>(); | |
auto cocos_p = ignis::cocosptr<CocosClass>(new CocosClass,false); | |
cocos_p = ignis::make_cocosptr<CocosClass>(); | |
} | |
*/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include<type_traits> | |
namespace ignis { | |
namespace detail { | |
// ref) http://stackoverflow.com/questions/2910979/how-is-base-of-works | |
template<typename Base, typename Derived> | |
struct is_base_of_helper { | |
operator Base*() const; | |
operator Derived*(); | |
}; | |
template<typename Base, typename Derived> | |
struct is_base_of_check { | |
private: | |
typedef char (&yes)[1]; | |
typedef char (&no)[2]; | |
template<typename T> | |
static yes check(Derived*, T); | |
static no check(Base*, int); | |
public: | |
static const bool value = | |
sizeof(check(is_base_of_helper<Base,Derived>(), int()))==sizeof(yes); | |
}; | |
template<typename Type> | |
struct is_base_of_check<Type,Type> { | |
static const bool value = true; | |
}; | |
} // detail namespace | |
template<typename Base,typename Derived> | |
struct IsBaseOf : | |
std::integral_constant<bool, | |
detail::is_base_of_check< | |
typename std::remove_cv<Base>::type, | |
typename std::remove_cv<Derived>::type>::value> | |
{ }; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment