1 #pragma once 2 3 #ifdef DEBUG 4 5 #include <cxxabi.h> 6 7 #include <iostream> 8 #include <string> 9 10 #ifdef ANDROID 11 #include <android/log.h> 12 #endif 13 14 namespace reanimated { 15 16 // This is a class that counts how many instances of a different class there 17 // are. It is meant only to be used with classes that should only have one 18 // instance. 19 20 template <class T> 21 class SingleInstanceChecker { 22 public: 23 SingleInstanceChecker(); 24 ~SingleInstanceChecker(); 25 26 private: 27 void assertWithMessage(bool condition, std::string message) { 28 if (!condition) { 29 #ifdef ANDROID 30 __android_log_print( 31 ANDROID_LOG_WARN, "Reanimated", "%s", message.c_str()); 32 #else 33 std::cerr << "[Reanimated] " << message << std::endl; 34 #endif 35 36 #ifdef IS_REANIMATED_EXAMPLE_APP 37 assert(false); 38 #endif 39 } 40 } 41 42 // A static field will exist separately for every class template. 43 // This has to be inline for automatic initialization. 44 inline static volatile int instanceCount_; 45 }; 46 47 template <class T> 48 SingleInstanceChecker<T>::SingleInstanceChecker() { 49 int status = 0; 50 std::string className = 51 __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); 52 53 // Only one instance should exist, but it is possible for two instances 54 // to co-exist during a reload. 55 assertWithMessage( 56 instanceCount_ <= 1, 57 "More than one instance of " + className + 58 " present. This may indicate a memory leak due to a retain cycle."); 59 60 instanceCount_++; 61 } 62 63 template <class T> 64 SingleInstanceChecker<T>::~SingleInstanceChecker() { 65 instanceCount_--; 66 } 67 68 } // namespace reanimated 69 70 #endif // DEBUG 71