【cocos2d-x從c++到js】14:註冊函數

前面的文章中講過,在遊戲啓動時,會調用大量的addRegisterCallback函數,向SpiderMonkey註冊Cocos2d-x引擎的函數。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_all_cocos2dx);
sc->addRegisterCallback(register_all_cocos2dx_extension);
sc->addRegisterCallback(register_cocos2dx_js_extensions);
sc->addRegisterCallback(register_all_cocos2dx_extension_manual);
sc->addRegisterCallback(jsb_register_chipmunk);
sc->addRegisterCallback(JSB_register_opengl);
sc->addRegisterCallback(jsb_register_system);
sc->addRegisterCallback(MinXmlHttpRequest::_js_register);
sc->addRegisterCallback(register_jsb_websocket);
sc->addRegisterCallback(register_all_cocos2dx_builder);
sc->addRegisterCallback(register_CCBuilderReader);
sc->addRegisterCallback(register_all_cocos2dx_gui);
sc->addRegisterCallback(register_all_cocos2dx_gui_manual);
sc->addRegisterCallback(register_all_cocos2dx_studio);
sc->addRegisterCallback(register_all_cocos2dx_studio_manual);
sc->addRegisterCallback(register_all_cocos2dx_spine);
sc->start();


以register_all_cocos2dx註冊函數爲例,跳轉到實現代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
void register_all_cocos2dx(JSContext* cx, JSObject* obj) {
    // first, try to get the ns
    JS::RootedValue nsval(cx);
    JSObject *ns;
    JS_GetProperty(cx, obj, "cc", &nsval);
    if (nsval == JSVAL_VOID) {
        ns = JS_NewObject(cx, NULL, NULL, NULL);
        nsval = OBJECT_TO_JSVAL(ns);
        JS_SetProperty(cx, obj, "cc", nsval);
    else {
        JS_ValueToObject(cx, nsval, &ns);
    }
    obj = ns;
    js_register_cocos2dx_Action(cx, obj);
    js_register_cocos2dx_FiniteTimeAction(cx, obj);
    js_register_cocos2dx_ActionInstant(cx, obj);
    js_register_cocos2dx_Hide(cx, obj);
    js_register_cocos2dx_Node(cx, obj);
    js_register_cocos2dx_Scene(cx, obj);
    js_register_cocos2dx_TransitionScene(cx, obj);
    js_register_cocos2dx_TransitionEaseScene(cx, obj);
    js_register_cocos2dx_TransitionMoveInL(cx, obj);
    js_register_cocos2dx_TransitionMoveInB(cx, obj);
    js_register_cocos2dx_Layer(cx, obj);
    js_register_cocos2dx___LayerRGBA(cx, obj);
    js_register_cocos2dx_AtlasNode(cx, obj);
    js_register_cocos2dx_TileMapAtlas(cx, obj);
    js_register_cocos2dx_TransitionMoveInT(cx, obj);
    js_register_cocos2dx_TransitionMoveInR(cx, obj);
    js_register_cocos2dx_ParticleSystem(cx, obj);
    js_register_cocos2dx_ParticleSystemQuad(cx, obj);
    js_register_cocos2dx_ParticleSnow(cx, obj);
    js_register_cocos2dx_ActionInterval(cx, obj);
    js_register_cocos2dx_ActionCamera(cx, obj);
    js_register_cocos2dx_ProgressFromTo(cx, obj);
    js_register_cocos2dx_MoveBy(cx, obj);
    js_register_cocos2dx_MoveTo(cx, obj);
    js_register_cocos2dx_JumpBy(cx, obj);
    js_register_cocos2dx_ActionEase(cx, obj);
    js_register_cocos2dx_EaseBounce(cx, obj);
    js_register_cocos2dx_EaseBounceIn(cx, obj);
    js_register_cocos2dx_TransitionRotoZoom(cx, obj);
    js_register_cocos2dx_Director(cx, obj);
    js_register_cocos2dx_Texture2D(cx, obj);
    js_register_cocos2dx_EaseElastic(cx, obj);
    js_register_cocos2dx_EaseElasticOut(cx, obj);
    js_register_cocos2dx_EaseBackOut(cx, obj);
    js_register_cocos2dx_TransitionSceneOriented(cx, obj);
    js_register_cocos2dx_TransitionFlipX(cx, obj);
    js_register_cocos2dx_Spawn(cx, obj);
    js_register_cocos2dx_SimpleAudioEngine(cx, obj);
    js_register_cocos2dx_SkewTo(cx, obj);
    js_register_cocos2dx_SkewBy(cx, obj);
    js_register_cocos2dx_TransitionProgress(cx, obj);
    js_register_cocos2dx_TransitionProgressVertical(cx, obj);
    js_register_cocos2dx_TMXTiledMap(cx, obj);
    js_register_cocos2dx_GridAction(cx, obj);
    js_register_cocos2dx_Grid3DAction(cx, obj);
    js_register_cocos2dx_FadeIn(cx, obj);
    js_register_cocos2dx_AnimationCache(cx, obj);
    js_register_cocos2dx_FlipX3D(cx, obj);
    js_register_cocos2dx_FlipY3D(cx, obj);
    js_register_cocos2dx_EaseSineInOut(cx, obj);
    js_register_cocos2dx_TransitionFlipAngular(cx, obj);
    js_register_cocos2dx_EGLViewProtocol(cx, obj);
    js_register_cocos2dx_EGLView(cx, obj);
    js_register_cocos2dx_EaseElasticInOut(cx, obj);
    js_register_cocos2dx_Show(cx, obj);
    js_register_cocos2dx_FadeOut(cx, obj);
    js_register_cocos2dx_CallFunc(cx, obj);
    js_register_cocos2dx_Waves3D(cx, obj);
    js_register_cocos2dx_ParticleFireworks(cx, obj);
    js_register_cocos2dx_MenuItem(cx, obj);
    js_register_cocos2dx_MenuItemSprite(cx, obj);
    js_register_cocos2dx_MenuItemImage(cx, obj);
    js_register_cocos2dx_ParticleFire(cx, obj);
    js_register_cocos2dx_TransitionZoomFlipAngular(cx, obj);
    js_register_cocos2dx_EaseRateAction(cx, obj);
    js_register_cocos2dx_EaseIn(cx, obj);
    js_register_cocos2dx_EaseExponentialInOut(cx, obj);
    js_register_cocos2dx_EaseBackInOut(cx, obj);
    js_register_cocos2dx_EaseExponentialOut(cx, obj);
    js_register_cocos2dx_SpriteBatchNode(cx, obj);
    js_register_cocos2dx_Label(cx, obj);
    js_register_cocos2dx_Application(cx, obj);
    js_register_cocos2dx_DelayTime(cx, obj);
    js_register_cocos2dx_LabelAtlas(cx, obj);
    js_register_cocos2dx_LabelBMFont(cx, obj);
    js_register_cocos2dx_TransitionFadeTR(cx, obj);
    js_register_cocos2dx_TransitionFadeBL(cx, obj);
    js_register_cocos2dx_EaseElasticIn(cx, obj);
    js_register_cocos2dx_ParticleSpiral(cx, obj);
    js_register_cocos2dx_TiledGrid3DAction(cx, obj);
    js_register_cocos2dx_FadeOutTRTiles(cx, obj);
    js_register_cocos2dx_FadeOutUpTiles(cx, obj);
    js_register_cocos2dx_FadeOutDownTiles(cx, obj);
    js_register_cocos2dx_TextureCache(cx, obj);
    js_register_cocos2dx_ActionTween(cx, obj);
    js_register_cocos2dx_TransitionFadeDown(cx, obj);
    js_register_cocos2dx_ParticleSun(cx, obj);
    js_register_cocos2dx_TransitionProgressHorizontal(cx, obj);
    js_register_cocos2dx_TMXObjectGroup(cx, obj);
    js_register_cocos2dx_TMXLayer(cx, obj);
    js_register_cocos2dx_FlipX(cx, obj);
    js_register_cocos2dx_FlipY(cx, obj);
    js_register_cocos2dx_TransitionSplitCols(cx, obj);
    js_register_cocos2dx_Timer(cx, obj);
    js_register_cocos2dx_FadeTo(cx, obj);
    js_register_cocos2dx_Repeat(cx, obj);
    js_register_cocos2dx_Place(cx, obj);
    js_register_cocos2dx_GLProgram(cx, obj);
    js_register_cocos2dx_EaseBounceOut(cx, obj);
    js_register_cocos2dx_RenderTexture(cx, obj);
    js_register_cocos2dx_TintBy(cx, obj);
    js_register_cocos2dx_TransitionShrinkGrow(cx, obj);
    js_register_cocos2dx_Sprite(cx, obj);
    js_register_cocos2dx_LabelTTF(cx, obj);
    js_register_cocos2dx_ClippingNode(cx, obj);
    js_register_cocos2dx_ParticleFlower(cx, obj);
    js_register_cocos2dx_ParticleSmoke(cx, obj);
    js_register_cocos2dx_LayerMultiplex(cx, obj);
    js_register_cocos2dx_Blink(cx, obj);
    js_register_cocos2dx_ShaderCache(cx, obj);
    js_register_cocos2dx_JumpTo(cx, obj);
    js_register_cocos2dx_ParticleExplosion(cx, obj);
    js_register_cocos2dx_TransitionJumpZoom(cx, obj);
    js_register_cocos2dx_Touch(cx, obj);
    js_register_cocos2dx_AnimationFrame(cx, obj);
    js_register_cocos2dx_NodeGrid(cx, obj);
    js_register_cocos2dx_TMXLayerInfo(cx, obj);
    js_register_cocos2dx_TMXTilesetInfo(cx, obj);
    js_register_cocos2dx_GridBase(cx, obj);
    js_register_cocos2dx_TiledGrid3D(cx, obj);
    js_register_cocos2dx_ParticleGalaxy(cx, obj);
    js_register_cocos2dx_Twirl(cx, obj);
    js_register_cocos2dx_MenuItemLabel(cx, obj);
    js_register_cocos2dx_LayerColor(cx, obj);
    js_register_cocos2dx_FadeOutBLTiles(cx, obj);
    js_register_cocos2dx_LayerGradient(cx, obj);
    js_register_cocos2dx_TargetedAction(cx, obj);
    js_register_cocos2dx_RepeatForever(cx, obj);
    js_register_cocos2dx_CardinalSplineTo(cx, obj);
    js_register_cocos2dx_CardinalSplineBy(cx, obj);
    js_register_cocos2dx_TransitionFlipY(cx, obj);
    js_register_cocos2dx_TurnOffTiles(cx, obj);
    js_register_cocos2dx_TintTo(cx, obj);
    js_register_cocos2dx_CatmullRomTo(cx, obj);
    js_register_cocos2dx_ToggleVisibility(cx, obj);
    js_register_cocos2dx_DrawNode(cx, obj);
    js_register_cocos2dx_TransitionTurnOffTiles(cx, obj);
    js_register_cocos2dx_RotateTo(cx, obj);
    js_register_cocos2dx_TransitionSplitRows(cx, obj);
    js_register_cocos2dx_TransitionProgressRadialCCW(cx, obj);
    js_register_cocos2dx_ScaleTo(cx, obj);
    js_register_cocos2dx_TransitionPageTurn(cx, obj);
    js_register_cocos2dx_BezierBy(cx, obj);
    js_register_cocos2dx_BezierTo(cx, obj);
    js_register_cocos2dx_Menu(cx, obj);
    js_register_cocos2dx_SpriteFrame(cx, obj);
    js_register_cocos2dx_ActionManager(cx, obj);
    js_register_cocos2dx_TransitionFade(cx, obj);
    js_register_cocos2dx_TransitionZoomFlipX(cx, obj);
    js_register_cocos2dx_SpriteFrameCache(cx, obj);
    js_register_cocos2dx_TransitionCrossFade(cx, obj);
    js_register_cocos2dx_Ripple3D(cx, obj);
    js_register_cocos2dx_TransitionSlideInL(cx, obj);
    js_register_cocos2dx_TransitionSlideInT(cx, obj);
    js_register_cocos2dx_StopGrid(cx, obj);
    js_register_cocos2dx_ShakyTiles3D(cx, obj);
    js_register_cocos2dx_PageTurn3D(cx, obj);
    js_register_cocos2dx_Grid3D(cx, obj);
    js_register_cocos2dx_TransitionProgressInOut(cx, obj);
    js_register_cocos2dx_EaseBackIn(cx, obj);
    js_register_cocos2dx_SplitRows(cx, obj);
    js_register_cocos2dx_Follow(cx, obj);
    js_register_cocos2dx_Animate(cx, obj);
    js_register_cocos2dx_ShuffleTiles(cx, obj);
    js_register_cocos2dx_ProgressTimer(cx, obj);
    js_register_cocos2dx_ParticleMeteor(cx, obj);
    js_register_cocos2dx_EaseInOut(cx, obj);
    js_register_cocos2dx_TransitionZoomFlipY(cx, obj);
    js_register_cocos2dx_ScaleBy(cx, obj);
    js_register_cocos2dx_Lens3D(cx, obj);
    js_register_cocos2dx_Animation(cx, obj);
    js_register_cocos2dx_TMXMapInfo(cx, obj);
    js_register_cocos2dx_EaseExponentialIn(cx, obj);
    js_register_cocos2dx_ReuseGrid(cx, obj);
    js_register_cocos2dx_MenuItemAtlasFont(cx, obj);
    js_register_cocos2dx_Liquid(cx, obj);
    js_register_cocos2dx_OrbitCamera(cx, obj);
    js_register_cocos2dx_ParticleBatchNode(cx, obj);
    js_register_cocos2dx_Component(cx, obj);
    js_register_cocos2dx_TextFieldTTF(cx, obj);
    js_register_cocos2dx_ParticleRain(cx, obj);
    js_register_cocos2dx_Waves(cx, obj);
    js_register_cocos2dx_EaseOut(cx, obj);
    js_register_cocos2dx_MenuItemFont(cx, obj);
    js_register_cocos2dx_TransitionFadeUp(cx, obj);
    js_register_cocos2dx_EaseSineOut(cx, obj);
    js_register_cocos2dx_JumpTiles3D(cx, obj);
    js_register_cocos2dx_MenuItemToggle(cx, obj);
    js_register_cocos2dx_RemoveSelf(cx, obj);
    js_register_cocos2dx_SplitCols(cx, obj);
    js_register_cocos2dx_MotionStreak(cx, obj);
    js_register_cocos2dx_RotateBy(cx, obj);
    js_register_cocos2dx_FileUtils(cx, obj);
    js_register_cocos2dx_ProgressTo(cx, obj);
    js_register_cocos2dx_TransitionProgressOutIn(cx, obj);
    js_register_cocos2dx_CatmullRomBy(cx, obj);
    js_register_cocos2dx_Sequence(cx, obj);
    js_register_cocos2dx_Shaky3D(cx, obj);
    js_register_cocos2dx_TransitionProgressRadialCW(cx, obj);
    js_register_cocos2dx_EaseBounceInOut(cx, obj);
    js_register_cocos2dx_TransitionSlideInR(cx, obj);
    js_register_cocos2dx___NodeRGBA(cx, obj);
    js_register_cocos2dx_ParallaxNode(cx, obj);
    js_register_cocos2dx_Scheduler(cx, obj);
    js_register_cocos2dx_EaseSineIn(cx, obj);
    js_register_cocos2dx_WavesTiles3D(cx, obj);
    js_register_cocos2dx_TransitionSlideInB(cx, obj);
    js_register_cocos2dx_Speed(cx, obj);
    js_register_cocos2dx_ShatteredTiles3D(cx, obj);
}

首先看到的是從根對象中獲取一個“cc”屬性(如果獲取不到,就新建一個),因爲JS中沒有名字空間的概念,所以我們使用一個cc對象來表示類似的功能。所有的類型和函數都是這個cc對象下面的屬性。在Cocos2d-x 3.0中,C++層面,類名去掉了CC的前綴,和js保持一致。


然後就是一大堆子函數,每個函數都負責註冊一個對應的類。打開js_register_cocos2dx_Sprite,這個函數負責註冊Sprite類。


打開js_register_cocos2dx_Sprite的實現代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
void js_register_cocos2dx_Sprite(JSContext *cx, JSObject *global) {
    jsb_cocos2d_Sprite_class = (JSClass *)calloc(1, sizeof(JSClass));
    jsb_cocos2d_Sprite_class->name = "Sprite";
    jsb_cocos2d_Sprite_class->addProperty = JS_PropertyStub;
    jsb_cocos2d_Sprite_class->delProperty = JS_DeletePropertyStub;
    jsb_cocos2d_Sprite_class->getProperty = JS_PropertyStub;
    jsb_cocos2d_Sprite_class->setProperty = JS_StrictPropertyStub;
    jsb_cocos2d_Sprite_class->enumerate = JS_EnumerateStub;
    jsb_cocos2d_Sprite_class->resolve = JS_ResolveStub;
    jsb_cocos2d_Sprite_class->convert = JS_ConvertStub;
    jsb_cocos2d_Sprite_class->finalize = js_cocos2d_Sprite_finalize;
    jsb_cocos2d_Sprite_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
    static JSPropertySpec properties[] = {
        {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
    };
    static JSFunctionSpec funcs[] = {
        JS_FN("setSpriteFrame", js_cocos2dx_Sprite_setSpriteFrame, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setTexture", js_cocos2dx_Sprite_setTexture, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getTexture", js_cocos2dx_Sprite_getTexture, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setFlippedY", js_cocos2dx_Sprite_setFlippedY, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setFlippedX", js_cocos2dx_Sprite_setFlippedX, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getBatchNode", js_cocos2dx_Sprite_getBatchNode, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getOffsetPosition", js_cocos2dx_Sprite_getOffsetPosition, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("removeAllChildrenWithCleanup", js_cocos2dx_Sprite_removeAllChildrenWithCleanup, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("updateQuadVertices", js_cocos2dx_Sprite_updateQuadVertices, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("updateTransform", js_cocos2dx_Sprite_updateTransform, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setTextureRect", js_cocos2dx_Sprite_setTextureRect, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("isFrameDisplayed", js_cocos2dx_Sprite_isFrameDisplayed, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getAtlasIndex", js_cocos2dx_Sprite_getAtlasIndex, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setBatchNode", js_cocos2dx_Sprite_setBatchNode, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setDisplayFrameWithAnimationName", js_cocos2dx_Sprite_setDisplayFrameWithAnimationName, 2, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setTextureAtlas", js_cocos2dx_Sprite_setTextureAtlas, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getSpriteFrame", js_cocos2dx_Sprite_getSpriteFrame, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("isDirty", js_cocos2dx_Sprite_isDirty, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setAtlasIndex", js_cocos2dx_Sprite_setAtlasIndex, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setDirty", js_cocos2dx_Sprite_setDirty, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("isTextureRectRotated", js_cocos2dx_Sprite_isTextureRectRotated, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getTextureRect", js_cocos2dx_Sprite_getTextureRect, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("getTextureAtlas", js_cocos2dx_Sprite_getTextureAtlas, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("isFlippedX", js_cocos2dx_Sprite_isFlippedX, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("isFlippedY", js_cocos2dx_Sprite_isFlippedY, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("setVertexRect", js_cocos2dx_Sprite_setVertexRect, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("ctor", js_cocos2d_Sprite_ctor, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FS_END
    };
    static JSFunctionSpec st_funcs[] = {
        JS_FN("create", js_cocos2dx_Sprite_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("createWithTexture", js_cocos2dx_Sprite_createWithTexture, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("createWithSpriteFrameName", js_cocos2dx_Sprite_createWithSpriteFrameName, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FN("createWithSpriteFrame", js_cocos2dx_Sprite_createWithSpriteFrame, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
        JS_FS_END
    };
    jsb_cocos2d_Sprite_prototype = JS_InitClass(
        cx, global,
        jsb_cocos2d_Node_prototype,
        jsb_cocos2d_Sprite_class,
        dummy_constructor<cocos2d::Sprite>, 0, // no constructor
        properties,
        funcs,
        NULL, // no static properties
        st_funcs);
    // make the class enumerable in the registered namespace
    JSBool found;
    JS_SetPropertyAttributes(cx, global, "Sprite", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
    // add the proto and JSClass to the type->js info hash table
    TypeTest<cocos2d::Sprite> t;
    js_type_class_t *p;
    std::string typeName = t.s_name();
    if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
    {
        p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
        p->jsclass = jsb_cocos2d_Sprite_class;
        p->proto = jsb_cocos2d_Sprite_prototype;
        p->parentProto = jsb_cocos2d_Node_prototype;
        _js_global_type_map.insert(std::make_pair(typeName, p));
    }
}


看起來比較長,其實很簡單,我們一段一段分析。


1
2
3
4
5
6
7
8
9
10
11
jsb_cocos2d_Sprite_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_cocos2d_Sprite_class->name = "Sprite";
jsb_cocos2d_Sprite_class->addProperty = JS_PropertyStub;
jsb_cocos2d_Sprite_class->delProperty = JS_DeletePropertyStub;
jsb_cocos2d_Sprite_class->getProperty = JS_PropertyStub;
jsb_cocos2d_Sprite_class->setProperty = JS_StrictPropertyStub;
jsb_cocos2d_Sprite_class->enumerate = JS_EnumerateStub;
jsb_cocos2d_Sprite_class->resolve = JS_ResolveStub;
jsb_cocos2d_Sprite_class->convert = JS_ConvertStub;
jsb_cocos2d_Sprite_class->finalize = js_cocos2d_Sprite_finalize;
jsb_cocos2d_Sprite_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);

首先,我們構造了一個JSClass對象,這個對象保存了一部分Sprite類的相關信息(注意,只是一部分而已)。其中包括類名,還有大量函數的佔位符JS_XXXStub,這些函數是在一定情況下被調用的,如:添加刪除屬性,查看修改屬性等等。這塊其實不用特別關注,因爲使用的都是SpiderMonkey自帶的缺省實現。Cocos2d-x引擎只是在最後把finalize函數替換成自己的函數了。最後那個參數表示這個類,有幾個Reserved Slots槽,這東西我們在之前講回調函數的時候見過。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
static JSPropertySpec properties[] = {
    {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
};
static JSFunctionSpec funcs[] = {
    JS_FN("setSpriteFrame", js_cocos2dx_Sprite_setSpriteFrame, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setTexture", js_cocos2dx_Sprite_setTexture, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getTexture", js_cocos2dx_Sprite_getTexture, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setFlippedY", js_cocos2dx_Sprite_setFlippedY, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setFlippedX", js_cocos2dx_Sprite_setFlippedX, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getBatchNode", js_cocos2dx_Sprite_getBatchNode, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getOffsetPosition", js_cocos2dx_Sprite_getOffsetPosition, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("removeAllChildrenWithCleanup", js_cocos2dx_Sprite_removeAllChildrenWithCleanup, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("updateQuadVertices", js_cocos2dx_Sprite_updateQuadVertices, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("updateTransform", js_cocos2dx_Sprite_updateTransform, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setTextureRect", js_cocos2dx_Sprite_setTextureRect, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("isFrameDisplayed", js_cocos2dx_Sprite_isFrameDisplayed, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getAtlasIndex", js_cocos2dx_Sprite_getAtlasIndex, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setBatchNode", js_cocos2dx_Sprite_setBatchNode, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setDisplayFrameWithAnimationName", js_cocos2dx_Sprite_setDisplayFrameWithAnimationName, 2, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setTextureAtlas", js_cocos2dx_Sprite_setTextureAtlas, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getSpriteFrame", js_cocos2dx_Sprite_getSpriteFrame, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("isDirty", js_cocos2dx_Sprite_isDirty, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setAtlasIndex", js_cocos2dx_Sprite_setAtlasIndex, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setDirty", js_cocos2dx_Sprite_setDirty, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("isTextureRectRotated", js_cocos2dx_Sprite_isTextureRectRotated, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getTextureRect", js_cocos2dx_Sprite_getTextureRect, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("getTextureAtlas", js_cocos2dx_Sprite_getTextureAtlas, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("isFlippedX", js_cocos2dx_Sprite_isFlippedX, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("isFlippedY", js_cocos2dx_Sprite_isFlippedY, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("setVertexRect", js_cocos2dx_Sprite_setVertexRect, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("ctor", js_cocos2d_Sprite_ctor, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FS_END
};
static JSFunctionSpec st_funcs[] = {
    JS_FN("create", js_cocos2dx_Sprite_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("createWithTexture", js_cocos2dx_Sprite_createWithTexture, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("createWithSpriteFrameName", js_cocos2dx_Sprite_createWithSpriteFrameName, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FN("createWithSpriteFrame", js_cocos2dx_Sprite_createWithSpriteFrame, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
    JS_FS_END
};

然後是填寫大量的參數,包括屬性,靜態屬性,函數,靜態函數。注意,因爲Cocos2d-x的類完全使用Setter和Getter,所以一般是沒有屬性和靜態屬性的。比較重要的是靜態函數和普通函數。我們看一下宏函數JS_FN。他的第一個參數是函數名,這個和C++層的函數命名是一致的,第二個參數在SpiderMonkey調用JS層對應的C++函數時的回調函數,這個函數我們之前的文章中分析過。第三個參數是函數調用時的參數個數。最後一個參數,是一些訪問特性,JSPROP_PERMANENT表示不可刪除,JSPROP_ENUMERATE表示在枚舉時可見(JS的for遍歷)。


1
2
3
4
5
6
7
8
9
10
11
12
jsb_cocos2d_Sprite_prototype = JS_InitClass(
    cx, global,
    jsb_cocos2d_Node_prototype,
    jsb_cocos2d_Sprite_class,
    dummy_constructor<cocos2d::Sprite>, 0, // no constructor
    properties,
    funcs,
    NULL, // no static properties
    st_funcs);
// make the class enumerable in the registered namespace
JSBool found;
JS_SetPropertyAttributes(cx, global, "Sprite", JSPROP_ENUMERATE | JSPROP_READONLY, &found);

因爲JS使用的是原型繼承,那麼我們需要構造一個原型,需要的參數也很多,都是我們上面配置好的,上下文,父對象,原型,JSClass對象,各種屬性和函數。然後,會自動把這個原型設置爲global(就是之前的cc對象)的一個屬性。最後,設置好訪問特性。


1
2
3
4
5
6
7
8
9
10
11
TypeTest<cocos2d::Sprite> t;
    js_type_class_t *p;
    std::string typeName = t.s_name();
    if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
    {
        p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
        p->jsclass = jsb_cocos2d_Sprite_class;
        p->proto = jsb_cocos2d_Sprite_prototype;
        p->parentProto = jsb_cocos2d_Node_prototype;
        _js_global_type_map.insert(std::make_pair(typeName, p));
    }

最後這段代碼是Cocos2d-x引擎自己做的一個設計,把類型信息存到一個map裏,這個設計以後會經常見到。可以用來查詢,另外在JS虛擬機清空時,也用來遍歷刪除對應的類型信息。做法是先放到一個map裏,然後cleanup時遍歷這個map即可。就不贅述了。











本文出自 “做遊戲的老G” 博客,請務必保留此出處http://goldlion.blog.51cto.com/4127613/1357617

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章