void InputLabel::closeKeyboard(EventCustom* event) { CCDictionary* infos = (CCDictionary*)event->getUserData(); if((isKindOfClass(infos->objectForKey("Sender"), CCInteger) && TOINT(infos->objectForKey("Sender")) == identifier) || (isKindOfClass(infos->objectForKey("Target"), CCInteger) && TOINT(infos->objectForKey("Target")) == identifier)) { CCLOG("Close InputLabel keyboard"); delegate->detachWithIME(); delegate->closeKeyboard(); //Force close the keyboard } }
void InputLabel::openKeyboard(EventCustom* event) { CCDictionary* infos = (CCDictionary*)event->getUserData(); if(locks.size() == 0 && ((isKindOfClass(infos->objectForKey("Sender"), CCInteger) && TOINT(infos->objectForKey("Sender")) == identifier) || (isKindOfClass(infos->objectForKey("Target"), CCInteger) && TOINT(infos->objectForKey("Target")) == identifier))) { CCLOG("Open InputLabel keyboard"); delegate->touchDownAction(this, cocos2d::ui::Widget::TouchEventType::ENDED);//open keyboard by simulating a touch inside isOpened = true; } }
Scene::~Scene() { for(Pausable* obj : updateList) { if(isKindOfClass(obj, Ref)) { dynamic_cast<Ref*>(obj)->release(); } } updateList.clear(); if(touchListener != NULL) { Director::getInstance()->getEventDispatcher()->removeEventListener(touchListener); touchListener->release(); touchListener = NULL; } if(keyboardListener != NULL) { Director::getInstance()->getEventDispatcher()->removeEventListener(keyboardListener); keyboardListener->release(); keyboardListener = NULL; } Director::getInstance()->getEventDispatcher()->removeEventListener(tapListener); Director::getInstance()->getEventDispatcher()->removeEventListener(appWillResignListener); parameters->release(); delegate->release(); linker->release(); }
void Scene::stop() { touchListener->setEnabled(false); keyboardListener->setEnabled(false); Director::getInstance()->getNotificationNode()->stopAllActions(); this->unscheduleUpdate(); for(Pausable* obj : updateList) { obj->stop(); if(isKindOfClass(obj, Ref)) { dynamic_cast<Ref*>(obj)->release(); } } updateList.clear(); for(GenericRecognizer* obj : touchReceiversList) { obj->cleanTouches(); } touchReceiversList.clear(); delegate->removeChild(this, false); delegate->removeChild(Director::getInstance()->getNotificationNode(), false); //Clean Renderer because commands may rely on a Node, which was removed after the update, but before the render, which causes a crash //For example, without this command, updating a RenderTexture during the same update will crash during SceneSwitch Director::getInstance()->getRenderer()->clean(); }
void Scene::removeUpdatable(Pausable* obj) { if(obj != NULL && std::find(updateList.begin(), updateList.end(), obj) != updateList.end() && std::find(updatablesToRemove.begin(), updatablesToRemove.end(), obj) == updatablesToRemove.end()) { updatablesToRemove.push_back(obj); if(isKindOfClass(obj, Ref)) { dynamic_cast<Ref*>(obj)->retain(); } } }
void SynchronousReleaser::emptyReleasePool() { #if VERBOSE_DEALLOC for(Ref* obj : releasePool) { if(obj->getReferenceCount() != 1) { const char* name = isKindOfClass(obj, RawObject) ? ((RawObject*)obj)->getName() : "Unknown"; CCLOG("!!Warning!! before releasing from ReleasePool, obj %s have retainCount %d", name, obj->getReferenceCount()); } } #endif releasePool.clear(); }
void arrayRemoveStringFromOther(CCArray* list, CCArray* other) { Ref* obj; CCArray* objectsToRemove = Acreate(); CCARRAY_FOREACH(list, obj) { if(isKindOfClass(obj, CCString) && arrayContainsString(other, (CCString*)obj)) { objectsToRemove->addObject(obj); } } list->removeObjectsInArray(objectsToRemove); }
void Image::textureLoaded(CCObject* obj) { if(isKindOfClass(obj, CCTexture2D) && !loadingImageFile.empty()) { this->replaceTexture(loadingImageFile.c_str(), loadingKeepExactSize, false, loadingKeepRatio); loadingImageFile = ""; isLoadingTexture = false; } #if VERBOSE_WARNING else { CCLog("Warning : Problem with asset : %s loaded asynchronously, texture not replaced", loadingImageFile.c_str()); } #endif }
Value Object::invoke(const char * key,InvokeArgs * args){ if(strcmp(key, "isKindOfClass") == 0){ const char * className = ValueToString(InvokeArgsValue(args, 0), NULL); if(className){ Context * ctx = Context::current(); if(ctx){ Class * clazz = ctx->getClass(className); if(clazz){ return Value(isKindOfClass(clazz)); } else { Log("Not Found Class %s",className); } } } return Value(false); } return Value(); }
CCDictionary* getProductsInfos() { JniMethodInfo minfo, minfo2; bool functionExist = JniHelper::getStaticMethodInfo(minfo,CLASS_NAME,"getProductsIds", "()[Ljava/lang/String;"); CCAssert(functionExist, "Function doesn't exist"); CCLOG("Starting getProductsInfos ..."); jobjectArray productsIdNative = (jobjectArray)minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); minfo.env->DeleteLocalRef(minfo.classID); CCArray* productsId = CCArrayFromjobjectArray(minfo.env, productsIdNative); minfo.env->DeleteLocalRef(productsIdNative); if(productsInfos == NULL) { productsInfos = new CCDictionary(); } if(productsId == NULL) { return productsInfos; } functionExist = JniHelper::getStaticMethodInfo(minfo2,CLASS_NAME,"getProductsInfos", "(Ljava/lang/String;)[Ljava/lang/String;"); CCAssert(functionExist, "Function doesn't exist"); for(int i = 0; i < productsId->count(); i++) { CCString* productId = (CCString*)productsId->objectAtIndex(i); if(!isKindOfClass(productsId->objectAtIndex(i), CCString)) { CCLOG("Warning : wrong type of product Id at index %d, will crash", i); } CCLOG("getting product \"%s\" infos", productId->getCString()); jstring jproductID = minfo2.env->NewStringUTF(productId->getCString()); jobjectArray nativeArray = (jobjectArray)minfo2.env->CallStaticObjectMethod(minfo2.classID, minfo2.methodID, jproductID); minfo2.env->DeleteLocalRef(jproductID); CCDictionary* infos = CCDictionaryFromjobjectArray(minfo.env, nativeArray); minfo2.env->DeleteLocalRef(nativeArray); productsInfos->setObject(infos, productId->getCString()); } minfo2.env->DeleteLocalRef(minfo2.classID); CCLOG("Returning product infos successfully"); return productsInfos; }
//note : keys have to be passed as CCString, unfortunately. Must be NULL terminated CCDictionary* createDictionaryWithParameters(CCObject* firstObject, ... ) { CCObject* eachObject; va_list argumentList; bool key = true; CCObject* object; if (firstObject) // The first argument isn't part of the varargs list, { // so we'll handle it separately. //put all parameters in a Dictionary to access them as key/value pairs CCDictionary* values = CCDictionary::create(); object = firstObject; va_start(argumentList, firstObject); // Start scanning for arguments after firstObject. while ((eachObject = va_arg(argumentList, CCObject*)) != NULL) // As many times as we can get an argument of type "id" { if(key) { //keys should be Strings if(!isKindOfClass(eachObject, CCString)) { CCLOG("Warning : not a key, value ignored"); } else { CCString* key = (CCString*)eachObject; values->setObject(object, key->m_sString); } } else { object = eachObject; } key = !key; } va_end(argumentList); return values; } else {
DelayedDispatcher* DelayedDispatcher::getInstance() { //A DelayedDispatcher must be linked to a scene to keep old behavior (delayed funcs/events don't last more than the scene they were created on) if(SceneSwitcher::sharedSwitcher()->getCurrentScene() == NULL) { if(temporaryInstance != NULL && temporaryInstanceScene == None) return temporaryInstance; //Hack around the fact that DelayedDispatcher can be called during Scene init: create a temporaryInstance that will be added to the Scene when the switch ends temporaryInstance = new DelayedDispatcher(); temporaryInstanceScene = None; temporaryListener = Director::getInstance()->getEventDispatcher()->addCustomEventListener("SceneSwitched", [](EventCustom*) { SceneSwitcher::sharedSwitcher()->getCurrentScene()->addUpdatable(temporaryInstance); Director::getInstance()->getEventDispatcher()->removeEventListener(temporaryListener); temporaryInstance->release(); temporaryListener = NULL; temporaryInstance = NULL; }); return temporaryInstance; } const std::vector<Pausable*>& candidates = SceneSwitcher::sharedSwitcher()->getCurrentScene()->getUpdateList(); for(Pausable* candidate : candidates) { if(isKindOfClass(candidate, DelayedDispatcher)) { temporaryInstance = NULL; return (DelayedDispatcher*)candidate; } } //Hack around the fact the addUpdatable is not instant, it is necessary to avoid recreating several DelayedDispatcher until it's accessible using getUpdateList if(temporaryInstance != NULL && temporaryInstanceScene == SceneSwitcher::sharedSwitcher()->getCurrentSceneName()) return temporaryInstance; DelayedDispatcher* newInstance = new DelayedDispatcher(); SceneSwitcher::sharedSwitcher()->getCurrentScene()->addUpdatable(newInstance); newInstance->release(); temporaryInstance = newInstance; temporaryInstanceScene = SceneSwitcher::sharedSwitcher()->getCurrentSceneName(); return newInstance; }
jobjectArray AnalyticXStringUtilAndroid::jobjectArrayFromCCDictionary(cocos2d::JniMethodInfo minfo, cocos2d::CCDictionary * ccDictionary) { if (ccDictionary == NULL) { return NULL; } else if (ccDictionary->allKeys() == NULL) { return NULL; } else if (ccDictionary->allKeys()->count() <= 0) { return NULL; } JNIEnv *pEnv = minfo.env; jclass jStringCls = 0; jStringCls = pEnv->FindClass("java/lang/String"); jobjectArray result; result = pEnv->NewObjectArray( 2 * ccDictionary->allKeys()->count(), jStringCls, NULL); if (result == NULL) { cocos2d::CCLog("failed to create a new jobjectArray"); return NULL; } for (int i = 0; i < ccDictionary->allKeys()->count(); i++) { cocos2d::CCObject* obj = ccDictionary->objectForKey(((cocos2d::CCString *)ccDictionary->allKeys()->objectAtIndex(i))->getCString()); cocos2d::CCString* value; if(isKindOfClass(obj, cocos2d::CCDictionary)) { value = cocos2d::CCString::create("Dictionary"); } else if(isKindOfClass(obj, cocos2d::CCArray)) { value = cocos2d::CCString::create("Array"); } else if (isKindOfClass(obj, cocos2d::CCString)) { value = (cocos2d::CCString*)obj; } else if (isKindOfClass(obj, cocos2d::CCInteger)) { value = cocos2d::CCString::createWithFormat("%d", ((cocos2d::CCInteger*)obj)->getValue()); } else { value = cocos2d::CCString::create("Unknown Object"); } jstring keyString = minfo.env->NewStringUTF(((cocos2d::CCString *)ccDictionary->allKeys()->objectAtIndex(i))->getCString()); jstring objectString = minfo.env->NewStringUTF(value->getCString()); pEnv->SetObjectArrayElement(result, i * 2, keyString); pEnv->SetObjectArrayElement(result, i * 2 + 1, objectString); } return result; }
void Scene::update(float deltaTime) { frameNumber++; #if VERBOSE_PERFORMANCE_TIME timeval startTime; if(frameNumber <= 3) gettimeofday(&startTime, NULL); #endif currentTime += deltaTime; #if VERBOSE_GENERAL_INFO CCLOG("Begin scene update"); #endif for(Pausable* obj : updateList) { //CCLOG("Updating object of type: %s", typeid(*obj).name()); obj->update(deltaTime); } #if VERBOSE_GENERAL_INFO CCLOG("scene update: second part"); #endif SceneSwitcher::sharedSwitcher()->trySceneSwitch(deltaTime); if(updatablesToRemove.size() > 0) { //CCLOG("Removing %d updatables", updatablesToRemove->count()); //Manual release for updateList Ref* for(Pausable* obj : updatablesToRemove) { if(isKindOfClass(obj, Ref)) { dynamic_cast<Ref*>(obj)->release(); } } updateList.erase(std::remove_if(updateList.begin(), updateList.end(), [&](Pausable* obj) { return std::find(updatablesToRemove.begin(), updatablesToRemove.end(), obj) != updatablesToRemove.end(); }), updateList.end()); updatablesToRemove.clear(); } if(updatablesToAdd.size() > 0) { //CCLOG("Removing %d updatables", updatablesToAdd->count()); //Manual retain for updateList Ref* for(Pausable* obj : updatablesToAdd) { updateList.push_back(obj); } updatablesToAdd.clear(); } if(receiversToRemove.size() > 0) { //CCLOG("Removing %d updatables", updatablesToRemove->count()); for(GenericRecognizer* recognizer : receiversToRemove) { touchReceiversList.eraseObject(recognizer); } receiversToRemove.clear(); } if(receiversToAdd.size() > 0) { //CCLOG("Removing %d updatables", updatablesToAdd->count()); for(GenericRecognizer* newReceiver : receiversToAdd) { newReceiver->setLinker(linker); } touchReceiversList.pushBack(receiversToAdd); receiversToAdd.clear(); } SynchronousReleaser::sharedReleaser()->emptyReleasePool(); #if VERBOSE_GENERAL_INFO CCLOG("end scene update"); #endif #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) if(frameNumber == 3) { //The first 2 frames are left for scene creation and defered label/image loading runGarbageCollector(); } #endif #if VERBOSE_PERFORMANCE_TIME timeval endTime; if(frameNumber <= 3) { gettimeofday(&endTime, NULL); CCLOG("Frame %d of scene %s loaded in %f ms", frameNumber, formatSceneToString(sceneName), getTimeDifferenceMS(startTime, endTime)); } #endif }