// // ScriptingCore.cpp // testmonkey // // Created by Rolando Abarca on 3/14/12. // Copyright (c) 2012 Zynga Inc. All rights reserved. // #include #include "cocos2d.h" #include "ScriptingCore.h" #include "cocos2d_generated.hpp" #include "cocos_denshion_generated.hpp" using namespace cocos2d; static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS }; ScriptingCore::ScriptingCore() { this->rt = JS_NewRuntime(8 * 1024 * 1024); this->cx = JS_NewContext(rt, 8192); JS_SetOptions(this->cx, JSOPTION_VAROBJFIX); JS_SetVersion(this->cx, JSVERSION_LATEST); JS_SetErrorReporter(this->cx, ScriptingCore::reportError); global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); if (!JS_InitStandardClasses(cx, global)) { CCLog("js error"); } // create the cocos namespace JSObject *cocos = JS_NewObject(cx, NULL, NULL, NULL); jsval cocosVal = OBJECT_TO_JSVAL(cocos); JS_SetProperty(cx, global, "cc", &cocosVal); // register the internal classes S_CCPoint::jsCreateClass(this->cx, cocos, "Point"); S_CCSize::jsCreateClass(this->cx, cocos, "Size"); S_CCRect::jsCreateClass(this->cx, cocos, "Rect"); S__ccGridSize::jsCreateClass(this->cx, cocos, "GridSize"); S_CCSet::jsCreateClass(this->cx, cocos, "Set"); S_CCTouch::jsCreateClass(this->cx, cocos, "Touch"); S_CCDirector::jsCreateClass(this->cx, cocos, "Director"); S_CCNode::jsCreateClass(this->cx, cocos, "Node"); S_CCTextureAtlas::jsCreateClass(this->cx, cocos, "TextureAtlas"); S_CCSpriteBatchNode::jsCreateClass(this->cx, cocos, "SpriteBatchNode"); S_CCScene::jsCreateClass(this->cx, cocos, "Scene"); S_CCLayer::jsCreateClass(this->cx, cocos, "Layer"); S_CCSprite::jsCreateClass(this->cx, cocos, "Sprite"); S_CCRenderTexture::jsCreateClass(this->cx, cocos, "RenderTexture"); S_CCMenu::jsCreateClass(this->cx, cocos, "Menu"); S_CCMenuItem::jsCreateClass(this->cx, cocos, "MenuItem"); S_CCMenuItemLabel::jsCreateClass(this->cx, cocos, "MenuItemLabel"); S_CCMenuItemSprite::jsCreateClass(this->cx, cocos, "MenuItemSprite"); S_CCMenuItemImage::jsCreateClass(this->cx, cocos, "MenuItemImage"); S_CCSpriteFrame::jsCreateClass(this->cx, cocos, "SpriteFrame"); S_CCSpriteFrameCache::jsCreateClass(this->cx, cocos, "SpriteFrameCache"); S_CCAnimation::jsCreateClass(this->cx, cocos, "Animation"); S_CCAction::jsCreateClass(this->cx, cocos, "Action"); S_CCActionInterval::jsCreateClass(this->cx, cocos, "ActionInterval"); S_CCFiniteTimeAction::jsCreateClass(this->cx, cocos, "FiniteTimeAction"); S_CCActionInstant::jsCreateClass(this->cx, cocos, "ActionInstant"); S_CCDelayTime::jsCreateClass(this->cx, cocos, "DelayTime"); S_CCAnimate::jsCreateClass(this->cx, cocos, "Animate"); S_CCMoveTo::jsCreateClass(this->cx, cocos, "MoveTo"); S_CCMoveBy::jsCreateClass(this->cx, cocos, "MoveBy"); S_CCRotateBy::jsCreateClass(this->cx, cocos, "RotateBy"); S_CCRotateTo::jsCreateClass(this->cx, cocos, "RotateTo"); S_CCActionEase::jsCreateClass(this->cx, cocos, "ActionEase"); S_CCEaseRateAction::jsCreateClass(this->cx, cocos, "EaseRateAction"); S_CCEaseIn::jsCreateClass(this->cx, cocos, "EaseIn"); S_CCEaseOut::jsCreateClass(this->cx, cocos, "EaseOut"); S_CCEaseInOut::jsCreateClass(this->cx, cocos, "EaseInOut"); S_CCEaseBackInOut::jsCreateClass(this->cx, cocos, "EaseBackInOut"); S_CCEaseBackOut::jsCreateClass(this->cx, cocos, "EaseBackOut"); S_CCEaseElasticIn::jsCreateClass(this->cx, cocos, "EaseElasticIn"); S_CCEaseElastic::jsCreateClass(this->cx, cocos, "EaseElastic"); S_CCEaseElasticOut::jsCreateClass(this->cx, cocos, "EaseElasticOut"); S_CCEaseElasticInOut::jsCreateClass(this->cx, cocos, "EaseElasticInOut"); S_CCEaseBounce::jsCreateClass(this->cx, cocos, "EaseBounce"); S_CCEaseBounceIn::jsCreateClass(this->cx, cocos, "EaseBounceIn"); S_CCEaseBounceInOut::jsCreateClass(this->cx, cocos, "EaseBounceInOut"); S_CCEaseBackIn::jsCreateClass(this->cx, cocos, "EaseBackIn"); S_CCEaseBounceOut::jsCreateClass(this->cx, cocos, "EaseBounceOut"); S_CCEaseExponentialIn::jsCreateClass(this->cx, cocos, "EaseExponentialIn"); S_CCEaseExponentialOut::jsCreateClass(this->cx, cocos, "EaseExponentialOut"); S_CCEaseExponentialInOut::jsCreateClass(this->cx, cocos, "EaseExponentialInOut"); S_CCEaseSineIn::jsCreateClass(this->cx, cocos, "EaseSineIn"); S_CCEaseSineOut::jsCreateClass(this->cx, cocos, "EaseSineOut"); S_CCEaseSineInOut::jsCreateClass(this->cx, cocos, "EaseSineInOut"); S_CCRepeatForever::jsCreateClass(this->cx, cocos, "RepeatForever"); S_CCSequence::jsCreateClass(this->cx, cocos, "Sequence"); S_CCLabelTTF::jsCreateClass(this->cx, cocos, "LabelTTF"); S_CCParticleSystem::jsCreateClass(this->cx, cocos, "ParticleSystem"); S_CCFileUtils::jsCreateClass(this->cx, cocos, "FileUtils"); S_CCTexture2D::jsCreateClass(this->cx, cocos, "Texture2D"); S_CCTextureCache::jsCreateClass(this->cx, cocos, "TextureCache"); S_CCParallaxNode::jsCreateClass(this->cx, cocos, "ParallaxNode"); S_CCTintBy::jsCreateClass(this->cx, cocos, "TintBy"); S_CCTintTo::jsCreateClass(this->cx, cocos, "TintTo"); S_CCLayerColor::jsCreateClass(this->cx, cocos, "LayerColor"); S_CCBlink::jsCreateClass(this->cx, cocos, "Blink"); S_CCSpeed::jsCreateClass(this->cx, cocos, "Speed"); S_CCGridAction::jsCreateClass(this->cx, cocos, "GridAction"); S_CCGrid3DAction::jsCreateClass(this->cx, cocos, "Grid3DAction"); S_CCWaves3D::jsCreateClass(this->cx, cocos, "Waves3D"); S_CCTransitionScene::jsCreateClass(this->cx, cocos, "TransitionScene"); S_CCTransitionSceneOriented::jsCreateClass(this->cx, cocos, "TransitionSceneOriented"); S_CCTransitionRotoZoom::jsCreateClass(this->cx, cocos, "TransitionRotoZoom"); S_CCTransitionFadeDown::jsCreateClass(this->cx, cocos, "TransitionFadeDown"); S_CCTransitionJumpZoom::jsCreateClass(this->cx, cocos, "TransitionJumpZoom"); S_CCTransitionMoveInL::jsCreateClass(this->cx, cocos, "TransitionMoveInL"); S_CCTransitionMoveInR::jsCreateClass(this->cx, cocos, "TransitionMoveInR"); S_CCTransitionMoveInT::jsCreateClass(this->cx, cocos, "TransitionMoveInT"); S_CCTransitionMoveInB::jsCreateClass(this->cx, cocos, "TransitionMoveInB"); S_CCTransitionSlideInL::jsCreateClass(this->cx, cocos, "TransitionSlideInL"); S_CCTransitionSlideInR::jsCreateClass(this->cx, cocos, "TransitionSlideInR"); S_CCTransitionSlideInB::jsCreateClass(this->cx, cocos, "TransitionSlideInB"); S_CCTransitionSlideInT::jsCreateClass(this->cx, cocos, "TransitionSlideInT"); S_CCTransitionShrinkGrow::jsCreateClass(this->cx, cocos, "TransitionShrinkGrow"); S_CCTransitionFlipX::jsCreateClass(this->cx, cocos, "TransitionFlipX"); S_CCTransitionFlipY::jsCreateClass(this->cx, cocos, "TransitionFlipY"); S_CCTransitionFlipAngular::jsCreateClass(this->cx, cocos, "TransitionFlipAngular"); S_CCTransitionZoomFlipX::jsCreateClass(this->cx, cocos, "TransitionZoomFlipX"); S_CCTransitionZoomFlipY::jsCreateClass(this->cx, cocos, "TransitionZoomFlipY"); S_CCTransitionZoomFlipAngular::jsCreateClass(this->cx, cocos, "TransitionZoomFlipAngular"); S_CCTransitionFade::jsCreateClass(this->cx, cocos, "TransitionFade"); S_CCTransitionCrossFade::jsCreateClass(this->cx, cocos, "TransitionCrossFade"); S_CCTransitionTurnOffTiles::jsCreateClass(this->cx, cocos, "TransitionTurnOffTiles"); S_CCTransitionSplitCols::jsCreateClass(this->cx, cocos, "TransitionSplitCols"); S_CCTransitionSplitRows::jsCreateClass(this->cx, cocos, "TransitionSplitRows"); S_CCTransitionFadeTR::jsCreateClass(this->cx, cocos, "TransitionFadeTR"); S_CCTransitionFadeBL::jsCreateClass(this->cx, cocos, "TransitionFadeBL"); S_CCTransitionFadeUp::jsCreateClass(this->cx, cocos, "TransitionFadeUp"); S_CCFadeOutBLTiles::jsCreateClass(this->cx, cocos, "FadeOutBLTiles"); S_CCProgressFromTo::jsCreateClass(this->cx, cocos, "ProgressFromTo"); S_CCFadeOutUpTiles::jsCreateClass(this->cx, cocos, "FadeOutUpTiles"); S_CCAnimationCache::jsCreateClass(this->cx, cocos, "AnimationCache"); S_CCPlace::jsCreateClass(this->cx, cocos, "Place"); S_CCLabelBMFont::jsCreateClass(this->cx, cocos, "LabelBMFont"); S_CCReverseTime::jsCreateClass(this->cx, cocos, "ReverseTime"); S_CCFadeOutTRTiles::jsCreateClass(this->cx, cocos, "FadeOutTRTiles"); S_CCCamera::jsCreateClass(this->cx, cocos, "Camera"); S_CCProgressTo::jsCreateClass(this->cx, cocos, "ProgressTo"); S_CCWavesTiles3D::jsCreateClass(this->cx, cocos, "WavesTiles3D"); S_CCMotionStreak::jsCreateClass(this->cx, cocos, "MotionStreak"); S_CCTransitionProgressRadialCCW::jsCreateClass(this->cx, cocos, "TransitionRadialProgressCCW"); S_CCFadeOutDownTiles::jsCreateClass(this->cx, cocos, "FadeOutDownTiles"); S_CCTurnOffTiles::jsCreateClass(this->cx, cocos, "TurnOffTiles"); S_CCDeccelAmplitude::jsCreateClass(this->cx, cocos, "DeccelAmplitude"); S_CCProgressTimer::jsCreateClass(this->cx, cocos, "ProgressTimer"); S_CCReuseGrid::jsCreateClass(this->cx, cocos, "ReuseGrid"); S_CCStopGrid::jsCreateClass(this->cx, cocos, "StopGrid"); S_CCTwirl::jsCreateClass(this->cx, cocos, "Twirl"); S_CCShakyTiles3D::jsCreateClass(this->cx, cocos, "ShakyTiles3D"); S_CCTransitionProgressRadialCW::jsCreateClass(this->cx, cocos, "TransitionProgressRadialCW"); S_CCAtlasNode::jsCreateClass(this->cx, cocos, "AtlasNode"); S_CCWaves::jsCreateClass(this->cx, cocos, "Waves"); S_CCShow::jsCreateClass(this->cx, cocos, "Show"); S_CCOrbitCamera::jsCreateClass(this->cx, cocos, "OrbitCamera"); S_CCShatteredTiles3D::jsCreateClass(this->cx, cocos, "ShatteredTiles3D"); S_CCHide::jsCreateClass(this->cx, cocos, "Hide"); S_CCToggleVisibility::jsCreateClass(this->cx, cocos, "ToggleVisibility"); S_CCActionCamera::jsCreateClass(this->cx, cocos, "ActionCamera"); S_CCShuffleTiles::jsCreateClass(this->cx, cocos, "ShuffleTiles"); S_CCLayerGradient::jsCreateClass(this->cx, cocos, "LayerGradient"); S_CCFlipX::jsCreateClass(this->cx, cocos, "FlipX"); S_CCRepeat::jsCreateClass(this->cx, cocos, "Repeat"); S_CCFlipY::jsCreateClass(this->cx, cocos, "FlipY"); S_CCBezierBy::jsCreateClass(this->cx, cocos, "BezierBy"); S_CCPageTurn3D::jsCreateClass(this->cx, cocos, "PageTurn3D"); S_CCLens3D::jsCreateClass(this->cx, cocos, "Lens3D"); S_CCRipple3D::jsCreateClass(this->cx, cocos, "Ripple3D"); S_CCApplication::jsCreateClass(this->cx, cocos, "Application"); S_CCFlipX3D::jsCreateClass(this->cx, cocos, "FlipX3D"); S_CCJumpTo::jsCreateClass(this->cx, cocos, "JumpTo"); S_CCTransitionPageTurn::jsCreateClass(this->cx, cocos, "TransitionPageTurn"); S_CCFlipY3D::jsCreateClass(this->cx, cocos, "FlipY3D"); S_CCLiquid::jsCreateClass(this->cx, cocos, "Liquid"); S_CCTiledGrid3DAction::jsCreateClass(this->cx, cocos, "TiledGrid3DAction"); S_CCJumpBy::jsCreateClass(this->cx, cocos, "JumpBy"); S_CCFollow::jsCreateClass(this->cx, cocos, "Follow"); S_CCSkewBy::jsCreateClass(this->cx, cocos, "SkewBy"); S_CCAccelDeccelAmplitude::jsCreateClass(this->cx, cocos, "AccelDeccelAmplitude"); S_CCLabelAtlas::jsCreateClass(this->cx, cocos, "LabelAtlas"); S_CCAccelAmplitude::jsCreateClass(this->cx, cocos, "AccelAmplitude"); S_CCSkewTo::jsCreateClass(this->cx, cocos, "SkewTo"); S_CCShaky3D::jsCreateClass(this->cx, cocos, "Shaky3D"); S_CCSplitCols::jsCreateClass(this->cx, cocos, "SplitCols"); S_CCFadeOut::jsCreateClass(this->cx, cocos, "FadeOut"); S_CCTileMapAtlas::jsCreateClass(this->cx, cocos, "TileMapAtlas"); S_CCFadeTo::jsCreateClass(this->cx, cocos, "FadeTo"); S_CCJumpTiles3D::jsCreateClass(this->cx, cocos, "JumpTiles3D"); S_CCFadeIn::jsCreateClass(this->cx, cocos, "FadeIn"); S_CCSplitRows::jsCreateClass(this->cx, cocos, "SplitRows"); S_CCScaleBy::jsCreateClass(this->cx, cocos, "ScaleBy"); S_CCScaleTo::jsCreateClass(this->cx, cocos, "ScaleTo"); S_CCBezierTo::jsCreateClass(this->cx, cocos, "BezierTo"); S_CCTMXTiledMap::jsCreateClass(this->cx, cocos, "TMXTiledMap"); S_CCTMXLayer::jsCreateClass(this->cx, cocos, "TMXLayer"); S_SimpleAudioEngine::jsCreateClass(this->cx, cocos, "SimpleAudioEngine"); // register some global functions JS_DefineFunction(this->cx, global, "require", ScriptingCore::executeScript, 0, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(this->cx, cocos, "log", ScriptingCore::log, 0, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(this->cx, cocos, "executeScript", ScriptingCore::executeScript, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(this->cx, cocos, "addGCRootObject", ScriptingCore::addRootJS, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(this->cx, cocos, "removeGCRootObject", ScriptingCore::removeRootJS, 1, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(this->cx, cocos, "forceGC", ScriptingCore::forceGC, 0, JSPROP_READONLY | JSPROP_PERMANENT); } bool ScriptingCore::evalString(const char *string, jsval *outVal) { jsval rval; JSString *str; JSBool ok; const char *filename = "noname"; uint32_t lineno = 0; if (outVal == NULL) { outVal = &rval; } ok = JS_EvaluateScript(cx, global, string, strlen(string), filename, lineno, outVal); if (ok == JS_FALSE) { CCLog("error evaluating script:\n%s", string); } str = JS_ValueToString(cx, rval); return ok; } void ScriptingCore::runScript(const char *path) { #ifdef DEBUG /** * dpath should point to the parent directory of the "JS" folder. If this is * set to "" (as it is now) then it will take the scripts from the app bundle. * By setting the absolute path you can iterate the development only by * modifying those scripts and reloading from the simulator (no recompiling/ * relaunching) */ // std::string dpath("/Users/rabarca/Desktop/testjs/testjs/"); std::string dpath(""); dpath += path; const char *realPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(dpath.c_str()); #else const char *realPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(path); #endif const char* content = CCString::createWithContentsOfFile(realPath)->getCString(); if (content && strlen(content) > 0) { JSBool ok; jsval rval; ok = JS_EvaluateScript(this->cx, this->global, (char *)content, strlen(content), path, 1, &rval); if (ok == JS_FALSE) { CCLog("error evaluating script:\n%s", content); } } } ScriptingCore::~ScriptingCore() { JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); }