前面的文章中讲过,在游戏启动时,会调用大量的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 51CTO博客,原文链接:http://blog.51cto.com/goldlion/1357617,如需转载请自行联系原作者

【cocos2d-x从c++到js】14:注册函数相关推荐

  1. 【cocos2d-x从c++到js】注册函数

    前面的文章中讲过,在游戏启动时,会调用大量的addRegisterCallback函数,向SpiderMonkey注册Cocos2d-x引擎的函数. 1 2 3 4 5 6 7 8 9 10 11 1 ...

  2. node.js在注册表删除_Node.JS 11年:时间表和重要贡献

    node.js在注册表删除 Do you know 你知道吗 Node.js在2020年5月27日已满11岁 (Node.js has turned 11 on 27th May 2020) ? Ca ...

  3. node JS獲取GPS_Node.js 14 正式发布:V8 引擎升级,新增异步本地存储 API

    Node.js 14 版本于近日正式发布, 此版本包含的亮点如下: 对诊断功能的改进 升级 v8 引擎 新增实验性的异步本地存储 API 强化流 API 移除实验性模块中的警告 移除一部分早期版本中废 ...

  4. Node.js 14 发布,改进了诊断功能

    Node.js 14 版本现已发布.新版本的亮点内容包括有:改进的诊断功能.V8 的升级.实验性的 Async Local Storage API.streams APIs 的强化.实验模块警告的删除 ...

  5. 马云盖茨入选最伟大25名抗疫领袖;周鸿祎卸任360金服;Node.js 14发布 | 极客头条...

    整理 | 郭芮 头图 | CSDN 下载自东方 IC 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦 ...

  6. 解决Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 14.x

    今天在新的开发环境检出nodejs的前端项目,运行npm run serve启动项目后报: > Node Sass could not find a binding for your curre ...

  7. uestudio 14 注册机 绿色免费版

    uestudio 14 注册机 绿色免费版 软件大小:172KB 软件语言:简体中文 软件性质:常用软件 软件授权:免费版 更新时间:2014-06-30 应用平台:/Win8/Win7/WinXP ...

  8. 银河麒麟桌面操作系统V10上安装使用Node.js 14.15.1 LTS版本并构建一个electronjs桌面应用

    前言 本文介绍银河麒麟桌面操作系统V10上下载安装官方网站Node.js 14.15.1 LTS版本,并编译一个electronjs应用. Node.js 是一个基于 Chrome V8 引擎的 Ja ...

  9. Node.js实践----注册-登录-个人中心(更换密码、头像)接口实现(包含mysql数据库)

    项目结构目录如下 1.初始化 1.1创建项目 1.2 配置cors跨域 1.3配置解析表单数据 1.4初始化路由 1.5抽离用户路由模块中的处理函数 2.注册登录 2.1新建ev_user表 2.3注 ...

最新文章

  1. 新书预告 | 你肯定想读的一本Python好作品
  2. Oracle KFED 和 KFOD 工具说明
  3. T511K表之工资常量SIINS的用途
  4. pb 修改数据窗口种指定字段位置_第三章 Python数据类型 容器
  5. linux内核 块驱动程序,linux – 为什么内核使用默认的块驱动程序而不是我的驱动程序代码?...
  6. 编程算法/面试 - K链表翻转
  7. 9.打开ZF的错误提示
  8. 收款码三合一制作微信小程序源码下载多模板选择
  9. 不租服务器,自建个人商业网站(如何购买域名)
  10. Windows蓝屏漏洞(利用多种途径与分析)
  11. 情人节 礼物TOP10
  12. IDEA 中使用 Big Data Tools 连接大数据组件
  13. 如何使用Axis 1.x 的WSDL2Java生成客户端
  14. Android开发人口流动管理,Android轻松搞定流动布局
  15. Abaqus硅胶管拉伸仿真
  16. 案例C语言在金融工程中应用,成功案例——跨专业申请美国金融工程硕士
  17. Springboot之邮件发送(内附源码)
  18. hive常用函数(一)
  19. 树的结构比图更加严格,那么具体在哪几个点严格呢?
  20. 30_java之DButils工具类

热门文章

  1. UVa 129 - Krypton Factor(回溯法)
  2. Linux报错:/etc/sudoers is world writable
  3. python try语句相关(try/except/else/finally)
  4. kali 安装使用记录
  5. WPF xml配置文件里面的大于小于号转义
  6. RT-Thread 学习笔记(四)——添加RTGUI组件
  7. 第三章 深入分析Java Web中的中文编码问题
  8. 《架构之美》学习随笔:设计第一步
  9. trie树和后缀树的应用
  10. 配置silverlight 2的开发环境