Read cocos2d-x source code


1.cocos2dx(using IOS platform) uses clean opengles project.


in main.m:
int retVal = UIApplicationMain(argc, argv, nil, @"PlantLinkAppController");

or the run system will create the appController from the *.xib files.
 As PlantLinkAppControllercreated by the run system, the system will callPlantLinkAppController::didFinishLaunchingWithOptions,and do following things:
 1).create UIWindow
 2).create EAGLView
 3).addSubview
 
 also create CCApplication derived class AppDelegate
in PlantLinkAppController.mm
//cocos2d application instance
staticAppDelegates_sharedApplication;
 then call
cocos2d::CCApplication::sharedApplication().run();
 then call
boolAppDelegate::initInstance()
 then call
boolAppDelegate::applicationDidFinishLaunching(), to do following things:
1).initialize director
in IOS, the CCDirector class is implemented in fileCCDirector_mobile.cpp 
inner, cocos2dx use CCDisplayLinkDirector, (notice, CCDisplayLinkDirector does not wrap IOS SDKCADisplayLinkjust indicate, and in cocos2d, it support 4 types of CCDirector, but in IOS cocos2dx, only supportCCDisplayLinkDirector, that means your app can only run in the ios device whose version bigger than 3.1!)
CCDirector::init(void)
call
//create autorelease pool
CCPoolManager::getInstance()->push();
2).set display mode
3).set FPS
4).set frame rate(in CCDisplayLinkDirector)
then call 
[[CCDirectorCallersharedDirectorCaller]startMainLoop]; this is the real IOS SDK related class which will create aCADisplayLinkclass, and start a loop.
call 
cocos2d::CCDirector::sharedDirector()->mainLoop(); so we finally start our maintop.

2. the autorelease in C++


Class:
CCAutoreleasePool
CCPoolManager
1)In CCDirector::init(void)
CCPoolManager::getInstance()->push();
2)In CCDisplayLinkDirector::mainLoop(void), so the engine release the objects every loop, notice that the pool only call the CCObject's release method, the release method itself judge if the reference count is less then or equal 0, it delete itself.
//release the objects
  CCPoolManager::getInstance()->pop();
3)so you will notice that if has no pool to pop, the answer is that the CCObject's autorelease method will call 
CCPoolManager::getCurReleasePool(),
  and it will push a new pool if no current pool, so from above you may calculate the memory efficiency.

3.EAGLView


cocos2dx use CCEGLView to wrap EAGLView
in CCDirector::setOpenGLView(), set touch dispatcher
CCTouchDispatcher *pTouchDispatcher = CCTouchDispatcher::sharedDispatcher();
m_pobOpenGLView->setTouchDelegate(pTouchDispatcher);
pTouchDispatcher->setDispatchEvents(true);

4. about the Touch


the run system dispatch the Touch Events to instance of EAGLView.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
cocos2d::CCDirector::sharedDirector()->getOpenGLView()->touchesBegan(&set);
}

so EAGLView -> CCEGLView -> CCTouchDispatcher, then dispatch to the registered objects.
to every object inherited from CCNode will implement CCTouchDelegate(CCTargetedTouchDelegate, CCStandardTouchDelegate, which has 4 pure visual functions must be implemented by child class), when the object first in scene theOnEnter() will be called, then itself should register the touch dispatcher like:
void CCMenu::registerWithTouchDispatcher()
{
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, kCCMenuTouchPriority, true);
}

cocos2dx use CCTouchHandler(CCStandardTouchHandler, CCTargetedTouchHandler)to deal, it has thePriority to indicate the order of who should receive the touch event first, the shorter value the early the object receive the touch event.
also the CCTouchDispatcher has a member varm_bLockedwhich will be set true when dispatching the touch event, if some object register touch then, the request will be stored, and be dealled in next touch event. the same as remove register request.
the touch dispatcher dispatch the points given by system one by one first to targeted touches, if them_bSwallowsTouchesis true, just jump to next point, then dispatch to standard touches.
the handler just not check if the point is in CCNode's region, the CCNode(or inherited class) should judge itself.

5.how to implement @selector()


Create a class named SelectorProtocol, every class who want to use it need to inherit it.

6.how to implement objc @property functions

#define CC_PROPERTY_READONLY(varType, varName, funName)\
protected: varType varName;\
public: virtual varType get##funName(void);

#define CC_PROPERTY(varType, varName, funName)\
protected: varType varName;\
public: virtual varType get##funName(void);\
public: virtual void set##funName(varType var);

#define CC_SYNTHESIZE(varType, varName, funName)\
protected: varType varName;\
public: inline varType get##funName(void) const { return varName; }\
public: inline void set##funName(varType var){ varName = var; }

7.CCScheduler


the CCScheduler has two types of scheduler
 1) update
 2) custom selector
the CCScheduler use CCTimer to deal with custom selector, CCTimer's update is invoke every frame in CCScheduler's tick. and in CCTimer's update it calculate the custom time.
CCNode,
-scheduleUpdate(), add the itself to the 'update' list in CCScheduler
-schedule(SEL_SCHEDULE selector, ccTime interval), add custom selector
the tick() is invoked by CCDirector::drawScene(), every frame
CCScheduler::sharedScheduler()->tick(m_fDeltaTime);

8.actions management


CCObject
|
CCAction
|                        |
other type
cocos2dx use tHashElementto store the object
typedef struct _hashElement
{
struct _ccArray             *actions; //the actions under a ccobject
CCObject	 *target;	 //the ccobject
unsigned int	 actionIndex;	 //
CCAction	 *currentAction;	 //
bool	 currentActionSalvaged;	 //
bool	 paused;	 //to control the action
UT_hash_handle	 hh;	 //list hash table node
} tHashElement;

use CCActionManager to manage all the actions, theCCActionManagerwill be add to the CCScheduler's p0 list.