Cocos2d-x 3.1.1 source code reading process comments
Cocos2d-x 3.1.1 source code reading process comments
Evernote link: http://app.yinxiang.com/l/AAU8F1mKiN9BIqFopReAU3ZbTcgGOULycQo/RefThe base class of each class is the Ref, that is, the following function inherited by the 2.0 CCObject call.
Class CC_DLL Ref {public:/** reference count + 1 */void retain (); {CCASSERT (_ referenceCount> 0, "reference count shold greater than 0 "); + _ referenceCount;}/** reference count-1 */void release (); {CCASSERT (_ referenceCount> 0, "reference count shocould greater than 0 "); -- _ referenceCount; if (_ referenceCount = 0) {# if defined (COCOS2D_DEBUG) & (COCOS2D_DEBUG> 0) auto poolManager = PoolManager: getInstance (); if (! PoolManager-> getCurrentPool ()-> isClearing () & poolManager-> isObjectInPools (this) {// error instance 1: // auto obj = Node: create (); // obj-> autorelease (); // the create FUNCTION encapsulates autorelease // The error instance 2: // auto obj = Node: create (); // obj-> release (); // Wrong: obj is an autorelsponref, it will be released when clearing current pool.
CCASSERT (false, "The reference shouldn't be 0 because it is still in autorelease pool.") ;}# endif
# If CC_USE_MEM_LEAK_DETECTION untrackRef (this); # endif delete this ;} /*** automatic release means that the current AutoReleasePool is called and the engine has an AutoReleasePool */Ref * autorelease (); {PoolManager: getInstance () -> getCurrentPool ()-> addObject (this); return this;}/*** return reference quantity */unsigned int getReferenceCount () const;
Protected:/*** after being constructed, the reference count is 1 !!!!! */Ref (): _ referenceCount (1) // when the Ref is created, the reference count of it is 1 {# if CC_ENABLE_SCRIPT_BINDING static unsigned int uObjectCount = 0; _ luaID = 0; _ ID = ++ uObjectCount; # endif # if CC_USE_MEM_LEAK_DETECTION trackRef (this); # endif}
Public: virtual ~ Ref (); protected: // count of references unsigned int _ referenceCount; friend class AutoreleasePool; # if CC_ENABLE_SCRIPT_BINDINGpublic: // object id, scriptSupport need public _ ID unsigned int _ ID; // Lua reference id int _ luaID; # endif # if CC_USE_MEM_LEAK_DETECTIONpublic: static void printLeaks (); # endif };
Parse the PoolManager class: class CC_DLL PoolManager {public: // This indicates that CC_DEPRECATED_ATTRIBUTE static PoolManager * sharedPoolManager () {return getInstance ();} will be discarded in the future ();}
/** It is also very important that only one single-instance PoolManager is added when PoolManager is initialized. */static PoolManager * getInstance (); {if (s_singleInstance = nullptr) {s_singleInstance = new PoolManager (); // Add the first auto release pool s_singleInstance-> _ curReleasePool = new AutoreleasePool ("cocos2d autorelease pool "); s_singleInstance-> _ releasePoolStack. push_back (s_singleInstance-> _ curReleasePool);} return s_singleInstance ;}
CC_DEPRECATED_ATTRIBUTE static void purgePoolManager () {destroyInstance ();} static void destroyInstance ();/*** get the current release pool, the engine creates an autoreleasePool *. you can create your own release pool and put it in the variable of the automatic release pool */AutoreleasePool * getCurrentPool () const; {return _ curReleasePool ;} bool isObjectInPools (Ref * obj) const;
Friend class AutoreleasePool; private: PoolManager ();~ PoolManager (); void push (AutoreleasePool * pool); {_ releasePoolStack. push_back (pool); _ curReleasePool = pool;} void pop (); {// if it is the first CC_ASSERT (_ releasePoolStack. size ()> = 1); _ releasePoolStack. pop_back (); // update _ curReleasePool if (_ releasePoolStack. size ()> 1) {_ curReleasePool = _ releasePoolStack. back ();}}
Static PoolManager * s_singleInstance; // single-instance mode std: deque <AutoreleasePool *> _ releasePoolStack; // AutoreleasePool * _ curReleasePool used to manage user-created automatic release pools; // The current automatic release pool };
AutoreleasePoolclass CC_DLL AutoreleasePool {public:/*** prompt: the automatically released pool object must be created in the stack and cannot be created in the stack *. It will be automatically pushed to the PoolManager */AutoreleasePool (); {_ managedObjectArray. reserve (150); // vector expanded capacity PoolManager: getInstance ()-> push (this );} /*** is created by reference for debugging */AutoreleasePool (const std: string & name); {_ managedObjectArray. reserve (150); PoolManager: getInstance ()-> push (this );}
// Enumerate each obj added to the object pool to call release and clear ~ AutoreleasePool (); {CCLOGINFO ("deallocing AutoreleasePool: % p", this); clear (); // PoolManager: getInstance ()-> pop ();} /*** add an object to the object pool * when the object pool is destroyed, */void addObject (Ref * object) is called; {_ managedObjectArray. push_back (object );}
/** Clear the Destructor call of the Object pool */void clear (); {# if defined (COCOS2D_DEBUG) & (COCOS2D_DEBUG> 0) _ isClearing = true; # endif for (const auto & obj: _ managedObjectArray) {// enumerate each obj added to the object pool to call release obj-> release ();}
// Empty the vector _ managedObjectArray. clear (); # if defined (COCOS2D_DEBUG) & (COCOS2D_DEBUG> 0) _ isClearing = false; # endif}
# If defined (COCOS2D_DEBUG) & (COCOS2D_DEBUG> 0)/*** Whether the pool is doing 'clear' operation. */bool isClearing () const {return _ isClearing;}; # endif/*** check whether * enumeration is included in the vector */bool contains (Ref * object) const; {for (const auto & obj: _ managedObjectArray) {if (obj = object) return true;} return false ;}
/*** For debugging **/void dump (); {CCLOG ("autorelease pool: % s, number of managed object % d \ n", _ name. c_str (), static_cast (_ ManagedObjectArray. size (); CCLOG ("% 20 s % 20 s % 20 s", "Object pointer", "Object id", "reference count "); for (const auto & obj: _ managedObjectArray) {CC_UNUSED_PARAM (obj); CCLOG ("% 20 p % 20u \ n", obj, obj-> getReferenceCount ());}}
Private:/*** The underlying array of object managed by the pool. ** Although Array retains the object once when an object is added, proper * Ref: release () is called outside the array to make sure that the pool * does not affect the managed object's reference count. so an object can * be destructed properly by calling Ref: release () even if the object * is in the pool. */std: vector <Ref *> _ managedObjectArray; std: string _ name; # if defined (COCOS2D_DEBUG) & (COCOS2D_DEBUG> 0) /*** The flag for checking whether the pool is doing 'clear' operation. */bool _ isClearing; # endif };
The following figure shows the inheritance diagram of the class graph found on the Internet: