Merge branch 'develop' into develop_migrate_math_lib_merge

This commit is contained in:
Huabing.Xu 2014-04-10 10:52:15 +08:00
commit 07ac817a7c
46 changed files with 913 additions and 1526 deletions

View File

@ -809,6 +809,12 @@ Developers:
mgcL mgcL
A potential memory leak fix in value's default constructor A potential memory leak fix in value's default constructor
Added ScriptHandlerMgr::destroyInstance to avoid memory leak Added ScriptHandlerMgr::destroyInstance to avoid memory leak
Mazyod
Fixed a bug that HTTPClient reports 2xx status codes as errors
iSevenDays
Fixed a bug that the result of 'malloc' is incompatible with type 'unsigned char *' in Image::saveImageToPNG
Retired Core Developers: Retired Core Developers:
WenSheng Yang WenSheng Yang

View File

@ -1 +1 @@
b78af2958c35d67fd0d06f1ca9fd7fce58799235 334022fee8065e04cd3ba41672900023d8b45e35

View File

@ -351,6 +351,7 @@ void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive
if (listener->getSceneGraphPriority() == target) if (listener->getSceneGraphPriority() == target)
{ {
listener->setSceneGraphPriority(nullptr); // Ensure no dangling ptr to the target node.
listener->setRegistered(false); listener->setRegistered(false);
listener->release(); listener->release();
iter = _toAddedListeners.erase(iter); iter = _toAddedListeners.erase(iter);

View File

@ -237,7 +237,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
bool existNewLetter = false; bool existNewLetter = false;
int bottomHeight = _commonLineHeight - _fontAscender; int bottomHeight = _commonLineHeight - _fontAscender;
float startX = _currentPageOrigX;
float startY = _currentPageOrigY; float startY = _currentPageOrigY;
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i)
@ -268,7 +268,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
auto data = _currentPageData + CacheTextureWidth * (int)startY; auto data = _currentPageData + CacheTextureWidth * (int)startY;
_atlasTextures[_currentPage]->updateWithData(data, 0, startY, _atlasTextures[_currentPage]->updateWithData(data, 0, startY,
CacheTextureWidth, CacheTextureHeight - startY); CacheTextureWidth, CacheTextureHeight - startY);
startX = 0.0f;
startY = 0.0f; startY = 0.0f;
_currentPageOrigY = 0; _currentPageOrigY = 0;

View File

@ -497,7 +497,7 @@ void FontFreeType::renderCharAt(unsigned char *dest,int posX, int posY, unsigned
{ {
long bitmap_y = y * bitmapWidth; long bitmap_y = y * bitmapWidth;
for (int x = 0; x < bitmapWidth; ++x) for (long x = 0; x < bitmapWidth; ++x)
{ {
/* Dual channel 16-bit output (more complicated, but good precision and range) */ /* Dual channel 16-bit output (more complicated, but good precision and range) */
/*int index = (iX + ( iY * destSize )) * 3; /*int index = (iX + ( iY * destSize )) * 3;

View File

@ -1081,15 +1081,17 @@ void Label::drawTextSprite(Renderer *renderer, bool parentTransformUpdated)
if (_shadowEnabled && _shadowNode == nullptr) if (_shadowEnabled && _shadowNode == nullptr)
{ {
_shadowNode = Sprite::createWithTexture(_textSprite->getTexture()); _shadowNode = Sprite::createWithTexture(_textSprite->getTexture());
if (_shadowNode && _blendFuncDirty) if (_shadowNode)
{ {
_shadowNode->setBlendFunc(_blendFunc); if (_blendFuncDirty)
_shadowNode->setBlendFunc(_blendFunc);
_shadowNode->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
_shadowNode->setColor(_shadowColor);
_shadowNode->setOpacity(_shadowOpacity * _displayedOpacity);
_shadowNode->setPosition(_shadowOffset.width, _shadowOffset.height);
Node::addChild(_shadowNode,0,Node::INVALID_TAG);
} }
_shadowNode->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
_shadowNode->setColor(_shadowColor);
_shadowNode->setOpacity(_shadowOpacity * _displayedOpacity);
_shadowNode->setPosition(_shadowOffset.width, _shadowOffset.height);
Node::addChild(_shadowNode,0,Node::INVALID_TAG);
} }
if (_shadowNode) if (_shadowNode)
{ {
@ -1240,7 +1242,7 @@ void Label::computeStringNumLines()
{ {
int quantityOfLines = 1; int quantityOfLines = 1;
unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1; int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
if (stringLen < 1) if (stringLen < 1)
{ {
_currNumLines = stringLen; _currNumLines = stringLen;
@ -1248,7 +1250,7 @@ void Label::computeStringNumLines()
} }
// count number of lines // count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i) for (int i = 0; i < stringLen - 1; ++i)
{ {
if (_currentUTF16String[i] == '\n') if (_currentUTF16String[i] == '\n')
{ {

View File

@ -108,7 +108,7 @@ void NodeGrid::visit(Renderer *renderer, const Matrix &parentTransform, bool par
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
Director::Projection beforeProjectionType; Director::Projection beforeProjectionType = Director::Projection::DEFAULT;
if(_nodeGrid && _nodeGrid->isActive()) if(_nodeGrid && _nodeGrid->isActive())
{ {
beforeProjectionType = Director::getInstance()->getProjection(); beforeProjectionType = Director::getInstance()->getProjection();

View File

@ -483,6 +483,7 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
{ {
memset(tmpQuads+oldCapactiy, 0, (_capacity - oldCapactiy)*sizeof(_quads[0]) ); memset(tmpQuads+oldCapactiy, 0, (_capacity - oldCapactiy)*sizeof(_quads[0]) );
} }
_quads = nullptr;
} }
if (_indices == nullptr) if (_indices == nullptr)
@ -492,7 +493,6 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
{ {
memset( tmpIndices, 0, _capacity * 6 * sizeof(_indices[0]) ); memset( tmpIndices, 0, _capacity * 6 * sizeof(_indices[0]) );
} }
} }
else else
{ {
@ -501,6 +501,7 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
{ {
memset( tmpIndices+oldCapactiy, 0, (_capacity-oldCapactiy) * 6 * sizeof(_indices[0]) ); memset( tmpIndices+oldCapactiy, 0, (_capacity-oldCapactiy) * 6 * sizeof(_indices[0]) );
} }
_indices = nullptr;
} }
if( ! ( tmpQuads && tmpIndices) ) { if( ! ( tmpQuads && tmpIndices) ) {

View File

@ -274,6 +274,6 @@ It should work same as apples CFSwapInt32LittleToHost(..)
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__) #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__) #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__) #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 ##__VA_ARGS__) #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
#endif // __CCMACROS_H__ #endif // __CCMACROS_H__

View File

@ -500,7 +500,9 @@ void FileUtils::purgeCachedEntries()
static Data getData(const std::string& filename, bool forString) static Data getData(const std::string& filename, bool forString)
{ {
CCASSERT(!filename.empty(), "Invalid filename!"); // getData is used indirectly in Image::initWithImageFileThreadSafe(), but CCASSERT is not thread-safe
// CCASSERT(!filename.empty(), "Invalid filename!");
assert(!(filename.empty()));
Data ret; Data ret;
unsigned char* buffer = nullptr; unsigned char* buffer = nullptr;

View File

@ -250,7 +250,6 @@ void GLViewProtocol::handleTouchesBegin(int num, intptr_t ids[], float xs[], flo
y = ys[i]; y = ys[i];
auto iter = g_touchIdReorderMap.find(id); auto iter = g_touchIdReorderMap.find(id);
unusedIndex = 0;
// it is a new touch // it is a new touch
if (iter == g_touchIdReorderMap.end()) if (iter == g_touchIdReorderMap.end())

View File

@ -1552,7 +1552,7 @@ bool Image::initWithTGAData(tImageTGA* tgaData)
} }
else else
{ {
if (tgaData->imageData != nullptr) if (tgaData && tgaData->imageData != nullptr)
{ {
free(tgaData->imageData); free(tgaData->imageData);
_data = nullptr; _data = nullptr;
@ -2023,7 +2023,7 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
{ {
if (isToRGB) if (isToRGB)
{ {
unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char*))); unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char)));
if (nullptr == pTempData) if (nullptr == pTempData)
{ {
fclose(fp); fclose(fp);

View File

@ -24,7 +24,6 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
package org.cocos2dx.lib; package org.cocos2dx.lib;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Locale; import java.util.Locale;
import java.lang.Runnable; import java.lang.Runnable;
@ -61,7 +60,6 @@ public class Cocos2dxHelper {
private static String sFileDirectory; private static String sFileDirectory;
private static Activity sActivity = null; private static Activity sActivity = null;
private static Cocos2dxHelperListener sCocos2dxHelperListener; private static Cocos2dxHelperListener sCocos2dxHelperListener;
private static ConcurrentLinkedQueue<Runnable> jobs = new ConcurrentLinkedQueue<Runnable>();
/** /**
* Optional meta-that can be in the manifest for this component, specifying * Optional meta-that can be in the manifest for this component, specifying
@ -75,18 +73,8 @@ public class Cocos2dxHelper {
// Constructors // Constructors
// =========================================================== // ===========================================================
public static void dispatchPendingRunnables() {
for (int i = RUNNABLES_PER_FRAME; i > 0; i--) {
Runnable job = jobs.poll();
if (job == null) {
return;
}
job.run();
}
}
public static void runOnGLThread(final Runnable r) { public static void runOnGLThread(final Runnable r) {
jobs.add(r); ((Cocos2dxActivity)sActivity).runOnGLThread(r);
} }
private static boolean sInited = false; private static boolean sInited = false;

View File

@ -65,6 +65,7 @@ public class Cocos2dxSound {
private Semaphore mSemaphore; private Semaphore mSemaphore;
private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5; private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5;
private static final int MAX_SIMULTANEOUS_STREAMS_I9100 = 3;
private static final float SOUND_RATE = 1.0f; private static final float SOUND_RATE = 1.0f;
private static final int SOUND_PRIORITY = 1; private static final int SOUND_PRIORITY = 1;
private static final int SOUND_QUALITY = 5; private static final int SOUND_QUALITY = 5;
@ -83,7 +84,13 @@ public class Cocos2dxSound {
} }
private void initData() { private void initData() {
this.mSoundPool = new SoundPool(Cocos2dxSound.MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, Cocos2dxSound.SOUND_QUALITY); if (Cocos2dxHelper.getDeviceModel().indexOf("GT-I9100") != -1) {
this.mSoundPool = new SoundPool(Cocos2dxSound.MAX_SIMULTANEOUS_STREAMS_I9100, AudioManager.STREAM_MUSIC, Cocos2dxSound.SOUND_QUALITY);
}
else {
this.mSoundPool = new SoundPool(Cocos2dxSound.MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, Cocos2dxSound.SOUND_QUALITY);
}
this.mSoundPool.setOnLoadCompleteListener(new OnLoadCompletedListener()); this.mSoundPool.setOnLoadCompleteListener(new OnLoadCompletedListener());
this.mLeftVolume = 0.5f; this.mLeftVolume = 0.5f;

View File

@ -52,7 +52,6 @@ public:
//TODO use material to decide if it is translucent //TODO use material to decide if it is translucent
inline bool isTranslucent() const { return true; } inline bool isTranslucent() const { return true; }
void generateMaterialID();
inline uint32_t getMaterialID() const { return _materialID; } inline uint32_t getMaterialID() const { return _materialID; }
inline GLuint getTextureID() const { return _textureID; } inline GLuint getTextureID() const { return _textureID; }
@ -67,6 +66,9 @@ public:
inline const Matrix& getModelView() const { return _mv; } inline const Matrix& getModelView() const { return _mv; }
private:
void generateMaterialID();
protected: protected:
uint32_t _materialID; uint32_t _materialID;

View File

@ -110,8 +110,6 @@ Renderer::Renderer()
RenderQueue defaultRenderQueue; RenderQueue defaultRenderQueue;
_renderGroups.push_back(defaultRenderQueue); _renderGroups.push_back(defaultRenderQueue);
RenderStackElement elelment = {DEFAULT_RENDER_QUEUE, 0};
_renderStack.push(elelment);
_batchedQuadCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE); _batchedQuadCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
} }
@ -260,6 +258,58 @@ int Renderer::createRenderQueue()
return (int)_renderGroups.size() - 1; return (int)_renderGroups.size() - 1;
} }
void Renderer::visitRenderQueue(const RenderQueue& queue)
{
ssize_t size = queue.size();
for (auto index = 0; index < size; ++index)
{
auto command = queue[index];
auto commandType = command->getType();
if(RenderCommand::Type::QUAD_COMMAND == commandType)
{
auto cmd = static_cast<QuadCommand*>(command);
//Batch quads
if(_numQuads + cmd->getQuadCount() > VBO_SIZE)
{
CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command");
//Draw batched quads if VBO is full
drawBatchedQuads();
}
_batchedQuadCommands.push_back(cmd);
memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView());
_numQuads += cmd->getQuadCount();
}
else if(RenderCommand::Type::GROUP_COMMAND == commandType)
{
flush();
int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();
visitRenderQueue(_renderGroups[renderQueueID]);
}
else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)
{
flush();
auto cmd = static_cast<CustomCommand*>(command);
cmd->execute();
}
else if(RenderCommand::Type::BATCH_COMMAND == commandType)
{
flush();
auto cmd = static_cast<BatchCommand*>(command);
cmd->execute();
}
else
{
CCLOGERROR("Unknown commands in renderQueue");
}
}
}
void Renderer::render() void Renderer::render()
{ {
//Uncomment this once everything is rendered by new renderer //Uncomment this once everything is rendered by new renderer
@ -278,87 +328,9 @@ void Renderer::render()
{ {
renderqueue.sort(); renderqueue.sort();
} }
visitRenderQueue(_renderGroups[0]);
while(!_renderStack.empty()) flush();
{
RenderQueue currRenderQueue = _renderGroups[_renderStack.top().renderQueueID];
size_t len = currRenderQueue.size();
//Process RenderQueue
for(size_t i = _renderStack.top().currentIndex; i < len; i++)
{
_renderStack.top().currentIndex = i;
auto command = currRenderQueue[i];
auto commandType = command->getType();
if(commandType == RenderCommand::Type::QUAD_COMMAND)
{
auto cmd = static_cast<QuadCommand*>(command);
CCASSERT(nullptr!= cmd, "Illegal command for RenderCommand Taged as QUAD_COMMAND");
//Batch quads
if(_numQuads + cmd->getQuadCount() > VBO_SIZE)
{
CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command");
//Draw batched quads if VBO is full
drawBatchedQuads();
}
_batchedQuadCommands.push_back(cmd);
memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView());
_numQuads += cmd->getQuadCount();
}
else if(commandType == RenderCommand::Type::CUSTOM_COMMAND)
{
flush();
auto cmd = static_cast<CustomCommand*>(command);
cmd->execute();
}
else if(commandType == RenderCommand::Type::BATCH_COMMAND)
{
flush();
auto cmd = static_cast<BatchCommand*>(command);
cmd->execute();
}
else if(commandType == RenderCommand::Type::GROUP_COMMAND)
{
flush();
auto cmd = static_cast<GroupCommand*>(command);
_renderStack.top().currentIndex = i + 1;
//push new renderQueue to renderStack
RenderStackElement element = {cmd->getRenderQueueID(), 0};
_renderStack.push(element);
//Exit current loop
break;
}
else
{
CCASSERT(true, "Invalid command");
flush();
}
}
//Draw the batched quads
drawBatchedQuads();
currRenderQueue = _renderGroups[_renderStack.top().renderQueueID];
len = currRenderQueue.size();
//If pop the render stack if we already processed all the commands
if(_renderStack.top().currentIndex + 1 >= len)
{
_renderStack.pop();
}
}
} }
clean(); clean();
} }
@ -379,15 +351,6 @@ void Renderer::clean()
_batchedQuadCommands.clear(); _batchedQuadCommands.clear();
_numQuads = 0; _numQuads = 0;
// Clear the stack incase gl view hasn't been initialized yet
while(!_renderStack.empty())
{
_renderStack.pop();
}
// Reset render stack
RenderStackElement element = {DEFAULT_RENDER_QUEUE, 0};
_renderStack.push(element);
_lastMaterialID = 0; _lastMaterialID = 0;
} }

View File

@ -123,12 +123,13 @@ protected:
//Draw the previews queued quads and flush previous context //Draw the previews queued quads and flush previous context
void flush(); void flush();
void visitRenderQueue(const RenderQueue& queue);
void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView); void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView);
std::stack<int> _commandGroupStack; std::stack<int> _commandGroupStack;
std::stack<RenderStackElement> _renderStack;
std::vector<RenderQueue> _renderGroups; std::vector<RenderQueue> _renderGroups;
uint32_t _lastMaterialID; uint32_t _lastMaterialID;

View File

@ -7,8 +7,7 @@ LOCAL_MODULE_FILENAME := libcocosdenshion
LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \ LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
ccdandroidUtils.cpp \ ccdandroidUtils.cpp \
jni/cddandroidAndroidJavaEngine.cpp \ jni/cddandroidAndroidJavaEngine.cpp
opensl/cddandroidOpenSLEngine.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include

View File

@ -33,41 +33,6 @@ USING_NS_CC;
namespace CocosDenshion { namespace CocosDenshion {
namespace android { namespace android {
#define I9100_MODEL "GT-I9100"
#define LOG_TAG "Device Model"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"
#define METHOD_NAME "getDeviceModel"
bool is_buggy_device(void) {
JniMethodInfo methodInfo;
jstring jstr;
if (JniHelper::getStaticMethodInfo(methodInfo,
CLASS_NAME,
METHOD_NAME,
"()Ljava/lang/String;")) {
jstr = (jstring)methodInfo.env->CallStaticObjectMethod(methodInfo.classID,
methodInfo.methodID);
}
const char* deviceModel = methodInfo.env->GetStringUTFChars(jstr, NULL);
if (NULL == deviceModel) {
return false;
}
LOGD("deviceModel = %s", deviceModel);
methodInfo.env->ReleaseStringUTFChars(jstr, deviceModel);
methodInfo.env->DeleteLocalRef(jstr);
if (strcmp(I9100_MODEL, deviceModel) == 0) {
LOGD("i9100 model\nSwitch to OpenSLES");
return true;
}
return false;
}
std::string getFullPathWithoutAssetsPrefix(const char* pszFilename) { std::string getFullPathWithoutAssetsPrefix(const char* pszFilename) {
// Changing file path to full path // Changing file path to full path
std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(pszFilename); std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(pszFilename);

View File

@ -29,7 +29,6 @@ THE SOFTWARE.
namespace CocosDenshion { namespace CocosDenshion {
namespace android { namespace android {
bool is_buggy_device(void);
std::string getFullPathWithoutAssetsPrefix(const char* pszFilename); std::string getFullPathWithoutAssetsPrefix(const char* pszFilename);
} }
} }

View File

@ -25,7 +25,6 @@ THE SOFTWARE.
#include "SimpleAudioEngine.h" #include "SimpleAudioEngine.h"
#include "jni/cddandroidAndroidJavaEngine.h" #include "jni/cddandroidAndroidJavaEngine.h"
#include "opensl/cddandroidOpenSLEngine.h"
#include "ccdandroidUtils.h" #include "ccdandroidUtils.h"
namespace CocosDenshion { namespace CocosDenshion {
@ -34,12 +33,7 @@ namespace CocosDenshion {
SimpleAudioEngine* SimpleAudioEngine::getInstance() { SimpleAudioEngine* SimpleAudioEngine::getInstance() {
if (! s_pEngine) { if (! s_pEngine) {
// if (CocosDenshion::android::is_buggy_device()) { s_pEngine = new CocosDenshion::android::AndroidJavaEngine();
// use the Java Audio implementation until compatibility is confirmed
s_pEngine = new CocosDenshion::android::AndroidJavaEngine();
// } else {
// s_pEngine = new CocosDenshion::android::OpenSLEngine();
// }
} }
return s_pEngine; return s_pEngine;

View File

@ -1,739 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "OpenSLEngine.h"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"OPENSL_ENGINE.CPP", __VA_ARGS__)
using namespace std;
OpenSLEngine::OpenSLEngine()
:_musicVolume(0),
_effectVolume(0)
{}
OpenSLEngine::~OpenSLEngine()
{
closeEngine();
}
/**********************************************************************************
* jni
**********************************************************************************/
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"
typedef struct JniMethodInfo_
{
JNIEnv * env;
jclass classID;
jmethodID methodID;
} JniMethodInfo;
extern "C" {
static JNIEnv* getJNIEnv(void)
{
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
if (NULL == jvm) {
LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL");
return NULL;
}
JNIEnv *env = NULL;
// get jni environment
jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4);
switch (ret) {
case JNI_OK :
// Success!
return env;
case JNI_EDETACHED :
// Thread not attached
// TODO : If calling AttachCurrentThread() on a native thread
// must call DetachCurrentThread() in future.
// see: http://developer.android.com/guide/practices/design/jni.html
if (jvm->AttachCurrentThread(&env, NULL) < 0)
{
LOGD("Failed to get the environment using AttachCurrentThread()");
return NULL;
} else {
// Success : Attached and obtained JNIEnv!
return env;
}
case JNI_EVERSION :
// Cannot recover from this error
LOGD("JNI interface version 1.4 not supported");
default :
LOGD("Failed to get the environment using GetEnv()");
return NULL;
}
}
static jclass getClassID(JNIEnv *pEnv)
{
jclass ret = pEnv->FindClass(CLASS_NAME);
if (! ret)
{
LOGD("Failed to find class of %s", CLASS_NAME);
}
return ret;
}
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *methodName, const char *paramCode)
{
jmethodID methodID = 0;
JNIEnv *pEnv = 0;
bool bRet = false;
do
{
pEnv = getJNIEnv();
if (! pEnv)
{
break;
}
jclass classID = getClassID(pEnv);
methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode);
if (! methodID)
{
LOGD("Failed to find static method id of %s", methodName);
break;
}
methodinfo.classID = classID;
methodinfo.env = pEnv;
methodinfo.methodID = methodID;
bRet = true;
} while (0);
return bRet;
}
};
/*********************************************************************************
* helper
********************************************************************************/
#define PLAYSTATE_UNKNOWN 0
#define FILE_NOT_FOUND -1
#define ASSET_MANAGER_GETTER "getAssetManager"
#define LIBANDROID "libandroid.so"
#define MIN_VOLUME_MILLIBEL -4000
#define MAX_VOLUME_MILLIBEL 0
#define RANGE_VOLUME_MILLIBEL 4000
class AudioPlayer
{
public:
SLDataSource audioSrc;
SLObjectItf fdPlayerObject;
SLPlayItf fdPlayerPlay;
SLSeekItf fdPlayerSeek;
SLVolumeItf fdPlayerVolume;
SLPlaybackRateItf fdPlaybackRate;
/// Applies global effects volume, takes effect gain into account.
/// @param volume In range 0..1.
void applyEffectsVolume(float volume)
{
SLmillibel finalVolume = int (RANGE_VOLUME_MILLIBEL * (volume * _gain)) + MIN_VOLUME_MILLIBEL;
SLresult result = (*fdPlayerVolume)->SetVolumeLevel(fdPlayerVolume, finalVolume);
assert(SL_RESULT_SUCCESS == result);
}
void applyParameters(bool isLooping, float pitch, float pan, float gain, float effectsVolume)
{
SLresult result = (*fdPlayerSeek)->SetLoop(fdPlayerSeek, (SLboolean) isLooping, 0, SL_TIME_UNKNOWN);
assert(SL_RESULT_SUCCESS == result);
SLpermille stereo = SLpermille(1000 * pan);
result = (*fdPlayerVolume)->EnableStereoPosition(fdPlayerVolume, SL_BOOLEAN_TRUE);
assert(SL_RESULT_SUCCESS == result);
result = (*fdPlayerVolume)->SetStereoPosition(fdPlayerVolume, stereo);
assert(SL_RESULT_SUCCESS == result);
SLpermille playbackRate = SLpermille(1000 * pitch);
if (fdPlaybackRate)
result = (*fdPlaybackRate)->SetRate(fdPlaybackRate, playbackRate);
assert(SL_RESULT_SUCCESS == result);
_gain = gain;
applyEffectsVolume(effectsVolume);
}
private:
float _gain;
};
static AudioPlayer s_musicPlayer; /* for background music */
typedef map<unsigned int, vector<AudioPlayer*>* > EffectList;
typedef pair<unsigned int, vector<AudioPlayer*>* > Effect;
void* s_pAndroidHandle = NULL;
void* s_pOpenSLESHandle = NULL;
static EffectList& sharedList()
{
static EffectList s_List;
return s_List;
}
unsigned int _Hash(const char *key)
{
unsigned int len = strlen(key);
const char *end=key+len;
unsigned int hash;
for (hash = 0; key < end; key++)
{
hash *= 16777619;
hash ^= (unsigned int) (unsigned char) toupper(*key);
}
return (hash);
}
SLInterfaceID getInterfaceID(const char *value)
{
// clear the error stack
dlerror();
SLInterfaceID* IID = (SLInterfaceID*)dlsym(s_pOpenSLESHandle, value);
const char* errorInfo = dlerror();
if (errorInfo)
{
LOGD("Get interface id: %s from OpenSL failed", errorInfo);
IID = NULL;
}
return *IID;
}
void* getFuncPtr(const char *value)
{
// clear the error stack
dlerror();
void* funcPtr = dlsym(s_pOpenSLESHandle, value);
const char* errorInfo = dlerror();
if (errorInfo)
{
LOGD("Get function from OpenSL failed: %s", errorInfo);
funcPtr = NULL;
}
return funcPtr;
}
int getFileDescriptor(const char * filename, off_t & start, off_t & length)
{
JniMethodInfo methodInfo;
if (! getStaticMethodInfo(methodInfo, ASSET_MANAGER_GETTER, "()Landroid/content/res/AssetManager;"))
{
methodInfo.env->DeleteLocalRef(methodInfo.classID);
return FILE_NOT_FOUND;
}
jobject assetManager = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
AAssetManager* (*AAssetManager_fromJava)(JNIEnv* env, jobject assetManager);
AAssetManager_fromJava = (AAssetManager* (*)(JNIEnv* env, jobject assetManager))
dlsym(s_pAndroidHandle, "AAssetManager_fromJava");
AAssetManager* mgr = AAssetManager_fromJava(methodInfo.env, assetManager);
assert(NULL != mgr);
AAsset* (*AAssetManager_open)(AAssetManager* mgr, const char* filename, int mode);
AAssetManager_open = (AAsset* (*)(AAssetManager* mgr, const char* filename, int mode))
dlsym(s_pAndroidHandle, "AAssetManager_open");
AAsset* Asset = AAssetManager_open(mgr, filename, AASSET_MODE_UNKNOWN);
if (NULL == Asset)
{
//LOGD("file not found! Stop preload file: %s", filename);
return FILE_NOT_FOUND;
}
// open asset as file descriptor
int (*AAsset_openFileDescriptor)(AAsset* asset, off_t* outStart, off_t* outLength);
AAsset_openFileDescriptor = (int (*)(AAsset* asset, off_t* outStart, off_t* outLength))
dlsym(s_pAndroidHandle, "AAsset_openFileDescriptor");
int fd = AAsset_openFileDescriptor(Asset, &start, &length);
assert(0 <= fd);
void (*AAsset_close)(AAsset* asset);
AAsset_close = (void (*)(AAsset* asset))
dlsym(s_pAndroidHandle, "AAsset_close");
AAsset_close(Asset);
return fd;
}
/**********************************************************************************
* engine
**********************************************************************************/
static SLObjectItf s_pEngineObject = NULL;
static SLEngineItf s_pEngineEngine = NULL;
static SLObjectItf s_pOutputMixObject = NULL;
bool createAudioPlayerBySource(AudioPlayer* player)
{
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, s_pOutputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[3] = {
getInterfaceID("SL_IID_SEEK"), getInterfaceID("SL_IID_MUTESOLO"), getInterfaceID("SL_IID_VOLUME")};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
SLresult result = (*s_pEngineEngine)->CreateAudioPlayer(s_pEngineEngine, &(player->fdPlayerObject), &(player->audioSrc), &audioSnk, 3, ids, req);
if (SL_RESULT_MEMORY_FAILURE == result)
{
return false;
}
// realize the player
result = (*(player->fdPlayerObject))->Realize(player->fdPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the play interface
result = (*(player->fdPlayerObject))->GetInterface(player->fdPlayerObject, getInterfaceID("SL_IID_PLAY"), &(player->fdPlayerPlay));
assert(SL_RESULT_SUCCESS == result);
// get the volume interface
result = (*(player->fdPlayerObject))->GetInterface(player->fdPlayerObject, getInterfaceID("SL_IID_VOLUME"), &(player->fdPlayerVolume));
assert(SL_RESULT_SUCCESS == result);
// get the seek interface
result = (*(player->fdPlayerObject))->GetInterface(player->fdPlayerObject, getInterfaceID("SL_IID_SEEK"), &(player->fdPlayerSeek));
assert(SL_RESULT_SUCCESS == result);
// get the playback rate interface, if available
(*(player->fdPlayerObject))->GetInterface(player->fdPlayerObject, getInterfaceID("SL_IID_PLAYBACKRATE"), &(player->fdPlaybackRate));
return true;
}
bool initAudioPlayer(AudioPlayer* player, const char* filename)
{
// configure audio source
off_t start, length;
int fd = getFileDescriptor(filename, start, length);
if (FILE_NOT_FOUND == fd)
{
FILE* fp = fopen(filename , "rb");
if(fp){
SLDataLocator_URI loc_fd = {SL_DATALOCATOR_URI , (SLchar*)filename};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
player->audioSrc.pLocator = &loc_fd;
player->audioSrc.pFormat = &format_mime;
return createAudioPlayerBySource(player);
}
LOGD("file not found! Stop preload file: %s", filename);
return false;
}
SLDataLocator_AndroidFD loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
player->audioSrc.pLocator = &loc_fd;
player->audioSrc.pFormat = &format_mime;
return createAudioPlayerBySource(player);
}
void destroyAudioPlayer(AudioPlayer * player)
{
if (player && player->fdPlayerObject != NULL)
{
SLresult result;
result = (*(player->fdPlayerPlay))->SetPlayState(player->fdPlayerPlay, SL_PLAYSTATE_STOPPED);
assert(SL_RESULT_SUCCESS == result);
(*(player->fdPlayerObject))->Destroy(player->fdPlayerObject);
player->fdPlayerObject = NULL;
player->fdPlayerPlay = NULL;
player->fdPlayerSeek = NULL;
player->fdPlayerVolume = NULL;
player->fdPlaybackRate = NULL;
}
}
void OpenSLEngine::createEngine(void* pHandle)
{
assert(pHandle != NULL);
s_pOpenSLESHandle = pHandle;
// clear the error stack
dlerror();
s_pAndroidHandle = dlopen(LIBANDROID, RTLD_LAZY);
const char* errorInfo = dlerror();
if (errorInfo)
{
LOGD("%s", errorInfo);
return;
}
SLresult result;
if (s_pEngineObject == NULL)
{
// create engine
SLresult (*slCreateEngine)(SLObjectItf *pEngine, SLuint32 numOptions, const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean * pInterfaceRequired );
slCreateEngine = (SLresult (*)(SLObjectItf *pEngine, SLuint32 numOptions, const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean * pInterfaceRequired ))
getFuncPtr("slCreateEngine");
result = slCreateEngine(&s_pEngineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
// realize the engine
result = (*s_pEngineObject)->Realize(s_pEngineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the engine interface, which is needed in order to create other objects
result = (*s_pEngineObject)->GetInterface(s_pEngineObject, getInterfaceID("SL_IID_ENGINE"), &s_pEngineEngine);
assert(SL_RESULT_SUCCESS == result);
// create output mix
const SLInterfaceID ids[1] = {getInterfaceID("SL_IID_ENVIRONMENTALREVERB")};
const SLboolean req[1] = {SL_BOOLEAN_FALSE};
result = (*s_pEngineEngine)->CreateOutputMix(s_pEngineEngine, &s_pOutputMixObject, 1, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the output mix object in sync. mode
result = (*s_pOutputMixObject)->Realize(s_pOutputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
}
}
void OpenSLEngine::closeEngine()
{
// destroy background players
destroyAudioPlayer(&s_musicPlayer);
// destroy effect players
vector<AudioPlayer*>* vec;
EffectList::iterator p = sharedList().begin();
while (p != sharedList().end())
{
vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
destroyAudioPlayer(*iter);
}
vec->clear();
p++;
}
sharedList().clear();
// destroy output mix interface
if (s_pOutputMixObject)
{
(*s_pOutputMixObject)->Destroy(s_pOutputMixObject);
s_pOutputMixObject = NULL;
}
// destroy opensl engine
if (s_pEngineObject)
{
(*s_pEngineObject)->Destroy(s_pEngineObject);
s_pEngineObject = NULL;
s_pEngineEngine = NULL;
}
LOGD("engine destory");
}
/**********************************************************************************
* sound effect
**********************************************************************************/
typedef struct _CallbackContext
{
vector<AudioPlayer*>* vec;
AudioPlayer* player;
} CallbackContext;
void PlayOverEvent(SLPlayItf caller, void* pContext, SLuint32 playEvent)
{
CallbackContext* context = (CallbackContext*)pContext;
if (playEvent == SL_PLAYEVENT_HEADATEND)
{
vector<AudioPlayer*>::iterator iter;
for (iter = (context->vec)->begin() ; iter != (context->vec)->end() ; ++ iter)
{
if (*iter == context->player)
{
(context->vec)->erase(iter);
break;
}
}
destroyAudioPlayer(context->player);
free(context);
}
}
int getSingleEffectState(AudioPlayer * player)
{
SLuint32 state = 0;
SLresult result;
result = (*(player->fdPlayerPlay))->GetPlayState(player->fdPlayerPlay, &state);
assert(result == SL_RESULT_SUCCESS);
return (int)state;
}
void setSingleEffectState(AudioPlayer * player, int state)
{
SLresult result;
if (player->fdPlayerPlay != NULL)
{
// don't set to PAUSED state if it's already set to STOPPED state
int oldState = getSingleEffectState(player);
if (oldState == SL_PLAYSTATE_STOPPED && state == SL_PLAYSTATE_PAUSED)
{
return;
}
result = (*(player->fdPlayerPlay))->SetPlayState(player->fdPlayerPlay, state);
assert(SL_RESULT_SUCCESS == result);
}
}
void resumeSingleEffect(AudioPlayer * player)
{
int state = getSingleEffectState(player);
// only resume the effect that has been paused
if (state == SL_PLAYSTATE_PAUSED)
{
setSingleEffectState(player, SL_PLAYSTATE_PLAYING);
}
}
bool OpenSLEngine::recreatePlayer(const char* filename)
{
unsigned int effectID = _Hash(filename);
EffectList::iterator p = sharedList().find(effectID);
vector<AudioPlayer*>* vec = p->second;
AudioPlayer* newPlayer = new AudioPlayer();
if (!initAudioPlayer(newPlayer, filename))
{
LOGD("failed to recreate");
return false;
}
vec->push_back(newPlayer);
// set callback
SLresult result;
CallbackContext* context = new CallbackContext();
context->vec = vec;
context->player = newPlayer;
result = (*(newPlayer->fdPlayerPlay))->RegisterCallback(newPlayer->fdPlayerPlay, PlayOverEvent, (void*)context);
assert(SL_RESULT_SUCCESS == result);
result = (*(newPlayer->fdPlayerPlay))->SetCallbackEventsMask(newPlayer->fdPlayerPlay, SL_PLAYEVENT_HEADATEND);
assert(SL_RESULT_SUCCESS == result);
// set volume
newPlayer->applyEffectsVolume(_effectVolume);
setSingleEffectState(newPlayer, SL_PLAYSTATE_STOPPED);
setSingleEffectState(newPlayer, SL_PLAYSTATE_PLAYING);
// LOGD("vec count is %d of effectID %d", vec->size(), effectID);
return true;
}
unsigned int OpenSLEngine::preloadEffect(const char * filename)
{
unsigned int nID = _Hash(filename);
// if already exists
EffectList::iterator p = sharedList().find(nID);
if (p != sharedList().end())
{
return nID;
}
AudioPlayer* player = new AudioPlayer();
if (!initAudioPlayer(player, filename))
{
free(player);
return FILE_NOT_FOUND;
}
// set the new player's volume as others'
player->applyEffectsVolume(_effectVolume);
vector<AudioPlayer*>* vec = new vector<AudioPlayer*>;
vec->push_back(player);
sharedList().insert(Effect(nID, vec));
return nID;
}
void OpenSLEngine::unloadEffect(const char * filename)
{
unsigned int nID = _Hash(filename);
EffectList::iterator p = sharedList().find(nID);
if (p != sharedList().end())
{
vector<AudioPlayer*>* vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
destroyAudioPlayer(*iter);
}
vec->clear();
sharedList().erase(nID);
}
}
int OpenSLEngine::getEffectState(unsigned int effectID)
{
int state = PLAYSTATE_UNKNOWN;
EffectList::iterator p = sharedList().find(effectID);
if (p != sharedList().end())
{
vector<AudioPlayer*>* vec = p->second;
// get the last player's state
vector<AudioPlayer*>::reverse_iterator r_iter = vec->rbegin();
state = getSingleEffectState(*r_iter);
}
return state;
}
void OpenSLEngine::setEffectState(unsigned int effectID, int state, bool isClear)
{
EffectList::iterator p = sharedList().find(effectID);
if (p != sharedList().end())
{
vector<AudioPlayer*>* vec = p->second;
if (state == SL_PLAYSTATE_STOPPED || state == SL_PLAYSTATE_PAUSED)
{
// if stopped, clear the recreated players which are unused
if (isClear)
{
setSingleEffectState(*(vec->begin()), state);
vector<AudioPlayer*>::reverse_iterator r_iter = vec->rbegin();
for (int i = 1, size = vec->size() ; i < size ; ++ i)
{
destroyAudioPlayer(*r_iter);
r_iter ++;
vec->pop_back();
}
}
else
{
vector<AudioPlayer*>::iterator iter;
for (iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
setSingleEffectState(*iter, state);
}
}
}
else
{
setSingleEffectState(*(vec->rbegin()), state);
}
}
}
void OpenSLEngine::setAllEffectState(int state)
{
EffectList::iterator p;
for (p = sharedList().begin(); p != sharedList().end(); p ++)
{
vector<AudioPlayer*>* vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
setSingleEffectState(*iter, state);
}
}
}
void OpenSLEngine::resumeEffect(unsigned int effectID)
{
EffectList::iterator p = sharedList().find(effectID);
if (p != sharedList().end())
{
vector<AudioPlayer*>* vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
resumeSingleEffect(*iter);
}
}
}
void OpenSLEngine::resumeAllEffects()
{
int state;
EffectList::iterator p;
for (p = sharedList().begin(); p != sharedList().end() ; ++ p)
{
vector<AudioPlayer*>* vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
resumeSingleEffect(*iter);
}
}
}
void OpenSLEngine::setEffectParameters(unsigned int effectID, bool isLooping,
float pitch, float pan, float gain)
{
vector<AudioPlayer*>* vec = sharedList()[effectID];
assert(NULL != vec);
// get the first effect player that to be set loop config
vector<AudioPlayer*>::iterator iter = vec->begin();
AudioPlayer * player = *iter;
if (player && player->fdPlayerSeek)
{
player->applyParameters(isLooping, pitch, pan, gain, _effectVolume);
}
}
void OpenSLEngine::setEffectsVolume(float volume)
{
assert(volume <= 1.0f && volume >= 0.0f);
_effectVolume = volume;
EffectList::iterator p;
AudioPlayer * player;
for (p = sharedList().begin() ; p != sharedList().end() ; ++ p)
{
vector<AudioPlayer*>* vec = p->second;
for (vector<AudioPlayer*>::iterator iter = vec->begin() ; iter != vec->end() ; ++ iter)
{
player = *iter;
player->applyEffectsVolume(_effectVolume);
}
}
}
float OpenSLEngine::getEffectsVolume()
{
float volume = (_effectVolume - MIN_VOLUME_MILLIBEL) / (1.0f * RANGE_VOLUME_MILLIBEL);
return volume;
}

View File

@ -1,100 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _OPENSL_ENGINE_H_
#define _OPENSL_ENGINE_H_
#include <assert.h>
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <map>
#include <vector>
#include <dlfcn.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <sys/types.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <jni/JniHelper.h>
#include <dlfcn.h>
class OpenSLEngine
{
public:
OpenSLEngine();
~OpenSLEngine();
void createEngine(void * pHandle);
void closeEngine();
bool preloadBackgroundMusic(const char * filename);
void setBackgroundMusicState(int state);
int getBackgroundMusicState();
void rewindBackgroundMusic();
void setBackgroundMusicLooping(bool isLooping);
void setBackgroundVolume(int volume);
int getBackgroundVolume();
bool recreatePlayer(const char* filename);
unsigned int preloadEffect(const char * filename);
void unloadEffect(const char * filename);
int getEffectState(unsigned int effectID);
void setEffectState(unsigned int effectID, int state, bool isClear = false);
void setAllEffectState(int state);
void resumeEffect(unsigned int effectID);
void resumeAllEffects();
void setEffectParameters(unsigned int effectID, bool isLooping, float pitch, float pan, float gain);
void setEffectsVolume(float volume);
float getEffectsVolume();
private:
SLmillibel _musicVolume;
float _effectVolume;
};
#endif

View File

@ -1,178 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "SimpleAudioEngineOpenSL.h"
#include <dlfcn.h>
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"SIMPLEAUDIOENGINE_OPENSL", __VA_ARGS__)
#define LIBOPENSLES "libOpenSLES.so"
#define PLAYSTATE_UNKNOWN 0
#define PLAYSTATE_STOPPED 1
#define PLAYSTATE_PAUSED 2
#define PLAYSTATE_PLAYING 3
#define FILE_NOT_FOUND -1
static void * s_pHandle = 0;
static OpenSLEngine * s_pOpenSL = 0;
static SimpleAudioEngineOpenSL * s_pEngine = 0;
SimpleAudioEngineOpenSL::SimpleAudioEngineOpenSL()
{
}
SimpleAudioEngineOpenSL::~SimpleAudioEngineOpenSL()
{
end();
}
bool SimpleAudioEngineOpenSL::initEngine()
{
bool bRet = false;
do
{
if (s_pOpenSL == NULL)
{
// clear the error stack
dlerror();
s_pHandle = dlopen(LIBOPENSLES, RTLD_LAZY);
const char* errorInfo = dlerror();
if (errorInfo)
{
LOGD("%s", errorInfo);
bRet = false;
break;
}
s_pOpenSL = new OpenSLEngine();
s_pOpenSL->createEngine(s_pHandle);
bRet = true;
}
} while (0);
return bRet;
}
SimpleAudioEngineOpenSL* SimpleAudioEngineOpenSL::sharedEngine()
{
if (s_pEngine == NULL)
{
s_pEngine = new SimpleAudioEngineOpenSL();
}
s_pEngine->initEngine();
return s_pEngine;
}
void SimpleAudioEngineOpenSL::end()
{
if (s_pOpenSL)
{
s_pOpenSL->closeEngine();
delete s_pOpenSL;
s_pOpenSL = NULL;
dlclose(s_pHandle);
s_pHandle = NULL;
}
}
float SimpleAudioEngineOpenSL::getEffectsVolume()
{
return s_pOpenSL->getEffectsVolume();
}
void SimpleAudioEngineOpenSL::setEffectsVolume(float volume)
{
if (volume < 0.0f) volume = 0.0f;
if (volume > 1.0f) volume = 1.0f;
s_pOpenSL->setEffectsVolume(volume);
}
unsigned int SimpleAudioEngineOpenSL::playEffect(const char* pszFilePath, bool bLoop,
float pitch, float pan, float gain)
{
unsigned int soundID = s_pOpenSL->preloadEffect(pszFilePath);
if (soundID != FILE_NOT_FOUND)
{
if (s_pOpenSL->getEffectState(soundID) == PLAYSTATE_PLAYING)
{
// recreate an effect player.
if (s_pOpenSL->recreatePlayer(pszFilePath))
{
s_pOpenSL->setEffectParameters(soundID, bLoop, pitch, pan, gain);
}
}
else
{
s_pOpenSL->setEffectState(soundID, PLAYSTATE_STOPPED);
s_pOpenSL->setEffectState(soundID, PLAYSTATE_PLAYING);
s_pOpenSL->setEffectParameters(soundID, bLoop, pitch, pan, gain);
}
}
return soundID;
}
void SimpleAudioEngineOpenSL::pauseEffect(unsigned int nSoundId)
{
s_pOpenSL->setEffectState(nSoundId, PLAYSTATE_PAUSED);
}
void SimpleAudioEngineOpenSL::pauseAllEffects()
{
s_pOpenSL->setAllEffectState(PLAYSTATE_PAUSED);
}
void SimpleAudioEngineOpenSL::resumeEffect(unsigned int nSoundId)
{
s_pOpenSL->resumeEffect(nSoundId);
}
void SimpleAudioEngineOpenSL::resumeAllEffects()
{
s_pOpenSL->resumeAllEffects();
}
void SimpleAudioEngineOpenSL::stopEffect(unsigned int nSoundId)
{
s_pOpenSL->setEffectState(nSoundId, PLAYSTATE_STOPPED, true);
}
void SimpleAudioEngineOpenSL::stopAllEffects()
{
s_pOpenSL->setAllEffectState(PLAYSTATE_STOPPED);
}
void SimpleAudioEngineOpenSL::preloadEffect(const char* pszFilePath)
{
s_pOpenSL->preloadEffect(pszFilePath);
}
void SimpleAudioEngineOpenSL::unloadEffect(const char* pszFilePath)
{
s_pOpenSL->unloadEffect(pszFilePath);
}

View File

@ -1,66 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _SIMPLE_AUDIO_ENGINE_OPENSL_H_
#define _SIMPLE_AUDIO_ENGINE_OPENSL_H_
#include "OpenSLEngine.h"
class SimpleAudioEngineOpenSL
{
public:
SimpleAudioEngineOpenSL();
~SimpleAudioEngineOpenSL();
bool initEngine();
static SimpleAudioEngineOpenSL* sharedEngine();
static void end();
float getEffectsVolume();
void setEffectsVolume(float volume);
unsigned int playEffect(const char* pszFilePath, bool bLoop, float pitch, float pan, float gain);
void pauseEffect(unsigned int nSoundId);
void pauseAllEffects();
void resumeEffect(unsigned int nSoundId);
void resumeAllEffects();
void stopEffect(unsigned int nSoundId);
void stopAllEffects();
void preloadEffect(const char* pszFilePath);
void unloadEffect(const char* pszFilePath);
};
#endif

View File

@ -1,59 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "cddandroidOpenSLEngine.h"
namespace CocosDenshion {
namespace android {
OpenSLEngine::~OpenSLEngine() {
}
void OpenSLEngine::preloadBackgroundMusic(const char* pszFilePath) { }
void OpenSLEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop) { }
void OpenSLEngine::stopBackgroundMusic(bool bReleaseData) { }
void OpenSLEngine::pauseBackgroundMusic() { }
void OpenSLEngine::resumeBackgroundMusic() { }
void OpenSLEngine::rewindBackgroundMusic() { }
bool OpenSLEngine::willPlayBackgroundMusic() { }
bool OpenSLEngine::isBackgroundMusicPlaying() { }
float OpenSLEngine::getBackgroundMusicVolume() { }
void OpenSLEngine::setBackgroundMusicVolume(float volume) { }
float OpenSLEngine::getEffectsVolume() { }
void OpenSLEngine::setEffectsVolume(float volume) { }
unsigned int OpenSLEngine::playEffect(const char* pszFilePath,
bool bLoop,
float pitch, float pan,
float gain) {
}
void OpenSLEngine::pauseEffect(unsigned int nSoundId) { }
void OpenSLEngine::pauseAllEffects() { }
void OpenSLEngine::resumeEffect(unsigned int nSoundId) { }
void OpenSLEngine::resumeAllEffects() { }
void OpenSLEngine::stopEffect(unsigned int nSoundId) { }
void OpenSLEngine::stopAllEffects() { }
void OpenSLEngine::preloadEffect(const char* pszFilePath) { }
void OpenSLEngine::unloadEffect(const char* pszFilePath) { }
}
}

View File

@ -1,63 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CDDANDROIDOPENSLENGINE_H__
#define __CDDANDROIDOPENSLENGINE_H__
#include "SimpleAudioEngine.h"
namespace CocosDenshion {
namespace android {
class OpenSLEngine : public SimpleAudioEngine {
~OpenSLEngine();
void preloadBackgroundMusic(const char* pszFilePath);
void playBackgroundMusic(const char* pszFilePath, bool bLoop);
void stopBackgroundMusic(bool bReleaseData);
void pauseBackgroundMusic();
void resumeBackgroundMusic();
void rewindBackgroundMusic();
bool willPlayBackgroundMusic();
bool isBackgroundMusicPlaying();
float getBackgroundMusicVolume();
void setBackgroundMusicVolume(float volume);
float getEffectsVolume();
void setEffectsVolume(float volume);
unsigned int playEffect(const char* pszFilePath,
bool bLoop = false,
float pitch = 1.0f, float pan = 0.0f,
float gain = 1.0f);
void pauseEffect(unsigned int nSoundId);
void pauseAllEffects();
void resumeEffect(unsigned int nSoundId);
void resumeAllEffects();
void stopEffect(unsigned int nSoundId);
void stopAllEffects();
void preloadEffect(const char* pszFilePath);
void unloadEffect(const char* pszFilePath);
};
}
}
#endif //__CDDANDROIDOPENSLENGINE_H__

View File

@ -462,7 +462,7 @@ void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{ {
ALuint buffer = AL_NONE; ALuint buffer = AL_NONE;
ALuint source = AL_NONE; ALuint source = AL_NONE;
soundData *data = new soundData;
checkALError("preloadEffect:init"); checkALError("preloadEffect:init");
OpenALFile file; OpenALFile file;
@ -472,7 +472,7 @@ void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
fprintf(stderr, "Cannot read file: '%s'\n", fullPath.data()); fprintf(stderr, "Cannot read file: '%s'\n", fullPath.data());
return; return;
} }
bool success = false; bool success = false;
const std::vector<OpenALDecoder *> &decoders = OpenALDecoder::getDecoders(); const std::vector<OpenALDecoder *> &decoders = OpenALDecoder::getDecoders();
for (size_t i = 0, n = decoders.size(); !success && i < n; ++i) for (size_t i = 0, n = decoders.size(); !success && i < n; ++i)
@ -489,7 +489,8 @@ void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
alSourcei(source, AL_BUFFER, buffer); alSourcei(source, AL_BUFFER, buffer);
checkALError("preloadEffect:alSourcei"); checkALError("preloadEffect:alSourcei");
soundData *data = new soundData;
data->isLooped = false; data->isLooped = false;
data->buffer = buffer; data->buffer = buffer;
data->source = source; data->source = source;

View File

@ -414,13 +414,13 @@ void Console::commandHelp(int fd, const std::string &args)
for(auto it=_commands.begin();it!=_commands.end();++it) for(auto it=_commands.begin();it!=_commands.end();++it)
{ {
auto cmd = it->second; auto cmd = it->second;
mydprintf(fd, "\t%s", cmd.name); mydprintf(fd, "\t%s", cmd.name.c_str());
ssize_t tabs = strlen(cmd.name) / 8; ssize_t tabs = strlen(cmd.name.c_str()) / 8;
tabs = 3 - tabs; tabs = 3 - tabs;
for(int j=0;j<tabs;j++){ for(int j=0;j<tabs;j++){
mydprintf(fd, "\t"); mydprintf(fd, "\t");
} }
mydprintf(fd,"%s\n", cmd.help); mydprintf(fd,"%s\n", cmd.help.c_str());
} }
} }
@ -765,6 +765,8 @@ void Console::commandTouch(int fd, const std::string& args)
} }
} }
static char invalid_filename_char[] = {':', '/', '\\', '?', '%', '*', '<', '>', '"', '|', '\r', '\n', '\t'};
void Console::commandUpload(int fd) void Console::commandUpload(int fd)
{ {
ssize_t n, rc; ssize_t n, rc;
@ -775,11 +777,20 @@ void Console::commandUpload(int fd)
{ {
if( (rc = recv(fd, &c, 1, 0)) ==1 ) if( (rc = recv(fd, &c, 1, 0)) ==1 )
{ {
*ptr++ = c; for(char x : invalid_filename_char)
{
if(c == x)
{
const char err[] = "upload: invalid file name!\n";
send(fd, err, sizeof(err),0);
return;
}
}
if(c == ' ') if(c == ' ')
{ {
break; break;
} }
*ptr++ = c;
} }
else if( rc == 0 ) else if( rc == 0 )
{ {
@ -875,10 +886,10 @@ bool Console::parseCommand(int fd)
} }
else else
{ {
const char err[] = "Unknown Command!\n"; const char err[] = "upload: invalid args! Type 'help' for options\n";
sendPrompt(fd);
send(fd, err, sizeof(err),0); send(fd, err, sizeof(err),0);
return false; sendPrompt(fd);
return true;
} }
} }
@ -909,7 +920,7 @@ bool Console::parseCommand(int fd)
const char err[] = "Unknown command. Type 'help' for options\n"; const char err[] = "Unknown command. Type 'help' for options\n";
send(fd, err, sizeof(err),0); send(fd, err, sizeof(err),0);
sendPrompt(fd); sendPrompt(fd);
return false; return true;
} }
auto it = _commands.find(trim(args[0])); auto it = _commands.find(trim(args[0]));

View File

@ -74,8 +74,8 @@ class CC_DLL Console
{ {
public: public:
struct Command { struct Command {
const char* name; std::string name;
const char* help; std::string help;
std::function<void(int, const std::string&)> callback; std::function<void(int, const std::string&)> callback;
}; };

View File

@ -339,7 +339,7 @@ public:
if (CURLE_OK != curl_easy_perform(_curl)) if (CURLE_OK != curl_easy_perform(_curl))
return false; return false;
CURLcode code = curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, responseCode); CURLcode code = curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, responseCode);
if (code != CURLE_OK || *responseCode != 200) { if (code != CURLE_OK || !(*responseCode >= 200 && *responseCode < 300)) {
CCLOGERROR("Curl curl_easy_getinfo failed: %s", curl_easy_strerror(code)); CCLOGERROR("Curl curl_easy_getinfo failed: %s", curl_easy_strerror(code));
return false; return false;
} }

View File

@ -1 +1 @@
99f00c770c5e8962571ec10047eb65f8fa1d5db0 48b548727f5f4ae9112bdb75069ad09641dcf643

View File

@ -1002,7 +1002,7 @@ const Rect& Layout::getClippingRect()
float scissorHeight = _size.height*t.d; float scissorHeight = _size.height*t.d;
Rect parentClippingRect; Rect parentClippingRect;
Layout* parent = this; Layout* parent = this;
bool firstClippingParentFounded = false;
while (parent) while (parent)
{ {
parent = dynamic_cast<Layout*>(parent->getParent()); parent = dynamic_cast<Layout*>(parent->getParent());
@ -1010,12 +1010,8 @@ const Rect& Layout::getClippingRect()
{ {
if (parent->isClippingEnabled()) if (parent->isClippingEnabled())
{ {
if (!firstClippingParentFounded) _clippingParent = parent;
{ break;
_clippingParent = parent;
firstClippingParentFounded = true;
break;
}
} }
} }
} }

View File

@ -31,7 +31,7 @@ cpArrayNew(int size)
arr->num = 0; arr->num = 0;
arr->max = (size ? size : 4); arr->max = (size ? size : 4);
arr->arr = (void **)cpcalloc(arr->max, sizeof(void**)); arr->arr = (void **)cpcalloc(arr->max, sizeof(void*));
return arr; return arr;
} }

View File

@ -69,7 +69,8 @@ class SetEnvVar(object):
RESULT_UPDATED = 1 RESULT_UPDATED = 1
RESULT_ADDED = 2 RESULT_ADDED = 2
UNIX_CHECK_FILES = [ '.bash_profile', '.bash_login', '.profile' ] MAC_CHECK_FILES = [ '.bash_profile', '.bash_login', '.profile' ]
LINUX_CHECK_FILES = [ '.bashrc' ]
RE_FORMAT = r'^export[ \t]+%s=(.+)' RE_FORMAT = r'^export[ \t]+%s=(.+)'
def __init__(self): def __init__(self):
@ -84,20 +85,33 @@ class SetEnvVar(object):
def _isLinux(self): def _isLinux(self):
return sys.platform.startswith('linux') return sys.platform.startswith('linux')
def _is_mac(self):
return sys.platform == 'darwin'
def _get_filepath_for_setup(self): def _get_filepath_for_setup(self):
file_list = None
if self._isLinux():
file_list = SetEnvVar.LINUX_CHECK_FILES
elif self._is_mac():
file_list = SetEnvVar.MAC_CHECK_FILES
file_to_write = None
if file_list is None:
return ''
home = os.path.expanduser('~') home = os.path.expanduser('~')
if os.path.exists(os.path.join(home, '.bash_profile')): for file_name in file_list:
file_to_write = os.path.join(home, '.bash_profile') file_path = os.path.join(home, file_name)
elif os.path.exists(os.path.join(home, '.bash_login')): if os.path.exists(file_path):
file_to_write = os.path.join(home, '.bash_login') file_to_write = file_path
elif os.path.exists(os.path.join(home, '.profile')): break
file_to_write = os.path.join(home, '.profile')
else: if file_to_write is None:
self.need_backup = False self.need_backup = False
file_to_write = os.path.join(home, '.bash_profile') file_to_write = os.path.join(home, file_list[0])
file = open(file_to_write, 'w') file_obj = open(file_to_write, 'w')
file.close() file_obj.close()
return file_to_write return file_to_write
@ -191,12 +205,19 @@ class SetEnvVar(object):
ret = os.environ[var] ret = os.environ[var]
except Exception: except Exception:
if not self._isWindows(): if not self._isWindows():
home = os.path.expanduser('~') file_list = None
for name in SetEnvVar.UNIX_CHECK_FILES: if self._isLinux():
path = os.path.join(home, name) file_list = SetEnvVar.LINUX_CHECK_FILES
ret = self._search_unix_variable(var, path) elif self._is_mac():
if ret is not None: file_list = SetEnvVar.MAC_CHECK_FILES
break
if file_list is not None:
home = os.path.expanduser('~')
for name in file_list:
path = os.path.join(home, name)
ret = self._search_unix_variable(var, path)
if ret is not None:
break
else: else:
import _winreg import _winreg
try: try:
@ -434,9 +455,13 @@ class SetEnvVar(object):
patten = re.compile(str_re) patten = re.compile(str_re)
replace_str = 'export %s=%s\n' % (var_name, value) replace_str = 'export %s=%s\n' % (var_name, value)
print " ->Update variable %s in files %s" % (var_name, str(SetEnvVar.UNIX_CHECK_FILES)) file_list = SetEnvVar.MAC_CHECK_FILES
if self._isLinux():
file_list = SetEnvVar.LINUX_CHECK_FILES
print " ->Update variable %s in files %s" % (var_name, str(file_list))
variable_updated = False variable_updated = False
for file_name in SetEnvVar.UNIX_CHECK_FILES: for file_name in file_list:
path = os.path.join(home, file_name) path = os.path.join(home, file_name)
if os.path.isfile(path): if os.path.isfile(path):
lines = [] lines = []

View File

@ -1 +1 @@
ee48702a58c132b4999c618ce6cd69b78f0d9cd9 31d62e35548799d9402b2c5d8038d2f4313a19a5

View File

@ -35,6 +35,7 @@ static std::function<Layer*()> createFunctions[] =
{ {
CL(NewSpriteTest), CL(NewSpriteTest),
CL(NewSpriteBatchTest), CL(NewSpriteBatchTest),
CL(GroupCommandTest),
CL(NewClippingNodeTest), CL(NewClippingNodeTest),
CL(NewDrawNodeTest), CL(NewDrawNodeTest),
CL(NewCullingTest), CL(NewCullingTest),
@ -222,6 +223,56 @@ std::string NewSpriteTest::subtitle() const
return "SpriteTest"; return "SpriteTest";
} }
class SpriteInGroupCommand : public Sprite
{
protected:
GroupCommand _spriteWrapperCommand;
public:
static SpriteInGroupCommand* create(const std::string& filename);
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
};
SpriteInGroupCommand* SpriteInGroupCommand::create(const std::string &filename)
{
SpriteInGroupCommand* sprite = new SpriteInGroupCommand();
sprite->initWithFile(filename);
sprite->autorelease();
return sprite;
}
void SpriteInGroupCommand::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
CCASSERT(renderer, "Render is null");
_spriteWrapperCommand.init(_globalZOrder);
renderer->addCommand(&_spriteWrapperCommand);
renderer->pushGroup(_spriteWrapperCommand.getRenderQueueID());
Sprite::draw(renderer, transform, transformUpdated);
renderer->popGroup();
}
GroupCommandTest::GroupCommandTest()
{
auto sprite = SpriteInGroupCommand::create("Images/grossini.png");
Size winSize = Director::getInstance()->getWinSize();
sprite->setPosition(winSize.width/2,winSize.height/2);
addChild(sprite);
}
GroupCommandTest::~GroupCommandTest()
{
}
std::string GroupCommandTest::title() const
{
return "Renderer";
}
std::string GroupCommandTest::subtitle() const
{
return "GroupCommandTest: You should see a sprite";
}
//-------- New Sprite Batch Test //-------- New Sprite Batch Test
NewSpriteBatchTest::NewSpriteBatchTest() NewSpriteBatchTest::NewSpriteBatchTest()

View File

@ -56,6 +56,19 @@ protected:
virtual ~NewSpriteTest(); virtual ~NewSpriteTest();
}; };
class GroupCommandTest : public MultiSceneTest
{
public:
CREATE_FUNC(GroupCommandTest);
virtual std::string title() const override;
virtual std::string subtitle() const override;
protected:
GroupCommandTest();
virtual ~GroupCommandTest();
};
class NewSpriteBatchTest : public MultiSceneTest class NewSpriteBatchTest : public MultiSceneTest
{ {
public: public:

View File

@ -232,14 +232,12 @@ RenderTextureIssue937::RenderTextureIssue937()
auto background = LayerColor::create(Color4B(200,200,200,255)); auto background = LayerColor::create(Color4B(200,200,200,255));
addChild(background); addChild(background);
auto s = Director::getInstance()->getWinSize();
auto spr_premulti = Sprite::create("Images/fire.png"); auto spr_premulti = Sprite::create("Images/fire.png");
spr_premulti->setPosition(Point(16,48)); spr_premulti->setPosition(Point(s.width/2-16, s.height/2+16));
auto spr_nonpremulti = Sprite::create("Images/fire.png"); auto spr_nonpremulti = Sprite::create("Images/fire.png");
spr_nonpremulti->setPosition(Point(16,16)); spr_nonpremulti->setPosition(Point(s.width/2-16, s.height/2-16));
/* A2 & B2 setup */ /* A2 & B2 setup */
auto rend = RenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888); auto rend = RenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888);
@ -249,20 +247,17 @@ RenderTextureIssue937::RenderTextureIssue937()
return; return;
} }
auto spr_size = spr_premulti->getContentSize();
rend->setKeepMatrix(true);
Size pixelSize = Director::getInstance()->getWinSizeInPixels();
rend->setVirtualViewport(Point(s.width/2-32, s.height/2-32),Rect(0,0,s.width,s.height),Rect(0,0,pixelSize.width,pixelSize.height));
// It's possible to modify the RenderTexture blending function by // It's possible to modify the RenderTexture blending function by
// [[rend sprite] setBlendFunc:(BlendFunc) {GL_ONE, GL_ONE_MINUS_SRC_ALPHA}]; // [[rend sprite] setBlendFunc:(BlendFunc) {GL_ONE, GL_ONE_MINUS_SRC_ALPHA}];
rend->begin(); rend->begin();
spr_premulti->visit(); spr_premulti->visit();
spr_nonpremulti->visit(); spr_nonpremulti->visit();
rend->end(); rend->end();
auto s = Director::getInstance()->getWinSize();
/* A1: setup */
spr_premulti->setPosition(Point(s.width/2-16, s.height/2+16));
/* B1: setup */
spr_nonpremulti->setPosition(Point(s.width/2-16, s.height/2-16));
rend->setPosition(Point(s.width/2+16, s.height/2)); rend->setPosition(Point(s.width/2+16, s.height/2));

View File

@ -353,86 +353,83 @@ void TestController::addConsoleAutoTest()
for (int i = 0; i < g_testCount; i++) for (int i = 0; i < g_testCount; i++)
{ {
// create the test scene and run it // create the test scene and run it
auto scene = g_aTestNames[i].callback(); std::string msg("autotest: running test:");
msg += g_aTestNames[i].test_name;
send(fd, msg.c_str(), strlen(msg.c_str()),0);
send(fd, "\n",1,0);
if (scene) currentController = &g_aTestNames[i];
sched->performFunctionInCocosThread( [&](){
auto scene = currentController->callback();
if(scene)
{
scene->runThisTest();
scene->release();
}
} );
wait(1);
BaseTest* firstTest = app->getCurrentTest();
if(firstTest == nullptr)
{ {
std::string msg("autotest: running test:"); continue;
msg += g_aTestNames[i].test_name; }
send(fd, msg.c_str(), strlen(msg.c_str()),0); std::string t1("");
send(fd, "\n",1,0); t1 += firstTest->subtitle();
send(fd, t1.c_str(), strlen(t1.c_str()),0);
send(fd, "\n",1,0);
wait(2);
currentController = &g_aTestNames[i]; while(1)
{
//currentTest->nextCallback(nullptr);
sched->performFunctionInCocosThread( [&](){ sched->performFunctionInCocosThread( [&](){
currentController->callback()->runThisTest(); BaseTest *t = app->getCurrentTest();
currentController->callback()->release(); if(t != nullptr)
{
t->nextCallback(nullptr);
}
} ); } );
wait(1); wait(1);
BaseTest* firstTest = app->getCurrentTest(); BaseTest * curTest = app->getCurrentTest();
if(firstTest == nullptr) if(curTest == nullptr)
{ {
continue; break;
} }
std::string t1(""); std::string title("");
t1 += firstTest->subtitle(); title += curTest->subtitle();
send(fd, t1.c_str(), strlen(t1.c_str()),0); send(fd, title.c_str(), strlen(title.c_str()),0);
send(fd, "\n",1,0); send(fd, "\n",1,0);
wait(2); wait(2);
//printf("rtti:%s", typeid(firstTest).name()); if(t1 == title)
while(1)
{ {
//currentTest->nextCallback(nullptr); break;
sched->performFunctionInCocosThread( [&](){
BaseTest *t = app->getCurrentTest();
if(t != nullptr)
{
t->nextCallback(nullptr);
}
} );
wait(1);
BaseTest * curTest = app->getCurrentTest();
if(curTest == nullptr)
{
break;
}
std::string title("");
title += curTest->subtitle();
send(fd, title.c_str(), strlen(title.c_str()),0);
send(fd, "\n",1,0);
wait(2);
if(t1 == title)
{
break;
}
} }
} }
} }
return;
} }
for(int i = 0; i < g_testCount; i++) for(int i = 0; i < g_testCount; i++)
{ {
if(args == g_aTestNames[i].test_name) if(args == g_aTestNames[i].test_name)
{ {
// create the test scene and run it currentController = &g_aTestNames[i];
auto scene = g_aTestNames[i].callback(); std::string msg("autotest: running test:");
if (scene) msg += args;
{ send(fd, msg.c_str(), strlen(msg.c_str()),0);
std::string msg("autotest: running test:"); send(fd, "\n",1,0);
msg += args;
send(fd, msg.c_str(), strlen(msg.c_str()),0);
send(fd, "\n",1,0);
currentController = &g_aTestNames[i];
sched->performFunctionInCocosThread( [&](){ sched->performFunctionInCocosThread( [&](){
currentController->callback()->runThisTest(); auto scene = currentController->callback();
currentController->callback()->release(); if(scene)
} ); {
return; scene->runThisTest();
} scene->release();
}
} );
return;
} }
} }

View File

@ -10,6 +10,11 @@ local testArray =
SpriteAccelerationEvent = 6, SpriteAccelerationEvent = 6,
RemoveAndRetainNode = 7, RemoveAndRetainNode = 7,
RemoveListenerAfterAdding = 8, RemoveListenerAfterAdding = 8,
GlobalZTouchTest = 9,
StopPropagationTest = 10,
PauseResumeTargetTest = 11,
Issue4129Test = 12,
Issue4160Test = 13,
} }
local curLayerIdx = testArray.TouchableSprite local curLayerIdx = testArray.TouchableSprite
@ -60,6 +65,16 @@ function EventDispatcherTestDemo.title(idx)
return "RemoveAndRetainNodeTest" return "RemoveAndRetainNodeTest"
elseif testArray.RemoveListenerAfterAdding == idx then elseif testArray.RemoveListenerAfterAdding == idx then
return "RemoveListenerAfterAddingTest" return "RemoveListenerAfterAddingTest"
elseif testArray.GlobalZTouchTest == idx then
return "Global Z Value, Try touch blue sprite"
elseif testArray.StopPropagationTest == idx then
return "Stop Propagation Test"
elseif testArray.PauseResumeTargetTest == idx then
return "PauseResumeTargetTest"
elseif testArray.Issue4129Test == idx then
return "Issue 4129: Remove All Listeners"
elseif testArray.Issue4160Test == idx then
return "Issue 4160: Out of range exception"
end end
end end
@ -80,6 +95,16 @@ function EventDispatcherTestDemo.subTitle(idx)
return "Sprite should be removed after 5s, add to scene again after 5s" return "Sprite should be removed after 5s, add to scene again after 5s"
elseif testArray.RemoveListenerAfterAdding == idx then elseif testArray.RemoveListenerAfterAdding == idx then
return "Should not crash!" return "Should not crash!"
elseif testArray.GlobalZTouchTest == idx then
return "Blue Sprite should change go from foreground to background"
elseif testArray.StopPropagationTest == idx then
return "Shouldn't crash and only blue block could be clicked"
elseif testArray.PauseResumeTargetTest == idx then
return ""
elseif testArray.Issue4129Test == idx then
return "Should see 'Yeah, this issue was fixed.'"
elseif testArray.Issue4160Test == idx then
return "Touch the red block twice \n should not crash and the red one couldn't be touched"
end end
end end
@ -136,7 +161,7 @@ function EventDispatcherTestDemo:createMenu()
menu:setPosition(cc.p(0, 0)) menu:setPosition(cc.p(0, 0))
self:addChild(menu) self:addChild(menu, 9999)
end end
function EventDispatcherTestDemo:creatTitleAndSubTitle(idx) function EventDispatcherTestDemo:creatTitleAndSubTitle(idx)
@ -227,16 +252,9 @@ function TouchableSpriteTest:onEnter()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener1, sprite1) eventDispatcher:addEventListenerWithSceneGraphPriority(listener1, sprite1)
local listener2 = listener1:clone() local listener2 = listener1:clone()
listener2:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)
listener2:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED)
listener2:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
eventDispatcher:addEventListenerWithSceneGraphPriority(listener2, sprite2) eventDispatcher:addEventListenerWithSceneGraphPriority(listener2, sprite2)
local listener3 = listener1:clone() local listener3 = listener1:clone()
listener3:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
listener3:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
listener3:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
eventDispatcher:addEventListenerWithSceneGraphPriority(listener3, sprite3) eventDispatcher:addEventListenerWithSceneGraphPriority(listener3, sprite3)
local function removeAllTouchItem(tag, sender) local function removeAllTouchItem(tag, sender)
@ -286,6 +304,7 @@ TouchableSpriteWithFixedPriority.__index = TouchableSpriteWithFixedPriority
TouchableSpriteWithFixedPriority._listener = nil TouchableSpriteWithFixedPriority._listener = nil
TouchableSpriteWithFixedPriority._fixedPriority = 0 TouchableSpriteWithFixedPriority._fixedPriority = 0
TouchableSpriteWithFixedPriority._useNodePriority = false TouchableSpriteWithFixedPriority._useNodePriority = false
TouchableSpriteWithFixedPriority._removeListenerOnTouchEnded = false
function TouchableSpriteWithFixedPriority.extend(target) function TouchableSpriteWithFixedPriority.extend(target)
local t = tolua.getpeer(target) local t = tolua.getpeer(target)
@ -298,6 +317,8 @@ function TouchableSpriteWithFixedPriority.extend(target)
end end
function TouchableSpriteWithFixedPriority:onEnter() function TouchableSpriteWithFixedPriority:onEnter()
local eventDispatcher = self:getEventDispatcher()
local function onTouchBegan(touch, event) local function onTouchBegan(touch, event)
local locationInNode = self:convertToNodeSpace(touch:getLocation()) local locationInNode = self:convertToNodeSpace(touch:getLocation())
local s = self:getContentSize() local s = self:getContentSize()
@ -317,6 +338,10 @@ function TouchableSpriteWithFixedPriority:onEnter()
local function onTouchEnded(touch, event) local function onTouchEnded(touch, event)
self:setColor(cc.c3b(255, 255, 255)) self:setColor(cc.c3b(255, 255, 255))
if self._removeListenerOnTouchEnded then
eventDispatcher:removeEventListener(self._listener)
end
end end
local listener = cc.EventListenerTouchOneByOne:create() local listener = cc.EventListenerTouchOneByOne:create()
@ -327,8 +352,7 @@ function TouchableSpriteWithFixedPriority:onEnter()
listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED ) listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED ) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
local eventDispatcher = self:getEventDispatcher() if 0 == self._fixedPriority then
if self._useNodePriority then
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self) eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)
else else
eventDispatcher:addEventListenerWithFixedPriority(listener,self._fixedPriority) eventDispatcher:addEventListenerWithFixedPriority(listener,self._fixedPriority)
@ -345,6 +369,10 @@ function TouchableSpriteWithFixedPriority:setPriority(fixedPriority)
self._useNodePriority = false self._useNodePriority = false
end end
function TouchableSpriteWithFixedPriority:removeListenerOnTouchEnded(toRemove)
self._removeListenerOnTouchEnded = toRemove
end
function TouchableSpriteWithFixedPriority:setPriorityWithThis(useNodePriority) function TouchableSpriteWithFixedPriority:setPriorityWithThis(useNodePriority)
self._fixedPriority = 0 self._fixedPriority = 0
self._useNodePriority = useNodePriority self._useNodePriority = useNodePriority
@ -970,6 +998,507 @@ function RemoveListenerAfterAddingTest.create()
return layer return layer
end end
local GlobalZTouchTest = class("GlobalZTouchTest",EventDispatcherTestDemo)
GlobalZTouchTest.__index = GlobalZTouchTest
GlobalZTouchTest._sprite = nil
GlobalZTouchTest._accum = 0
GlobalZTouchTest._layer = nil
function GlobalZTouchTest.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, GlobalZTouchTest)
return target
end
function GlobalZTouchTest:onEnter()
local function onTouchBegan(touch, event)
local target = event:getCurrentTarget()
local locationInNode = target:convertToNodeSpace(touch:getLocation())
local s = target:getContentSize()
local rect = cc.rect(0, 0, s.width, s.height)
if cc.rectContainsPoint(rect, locationInNode) then
print(string.format("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y))
target:setOpacity(180)
return true
end
return false
end
local function onTouchMoved(touch, event)
local target = event:getCurrentTarget()
local posX,posY = target:getPosition()
local delta = touch:getDelta()
target:setPosition(cc.p(posX + delta.x, posY + delta.y))
end
local function onTouchEnded(touch, event)
local target = event:getCurrentTarget()
print("sprite onTouchesEnded..")
target:setOpacity(255)
end
local listener = cc.EventListenerTouchOneByOne:create()
listener:setSwallowTouches(true)
listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
local SPRITE_COUNT = 8
for i = 0, SPRITE_COUNT - 1 do
local sprite = nil
if 4 == i then
sprite = cc.Sprite:create("Images/CyanSquare.png")
self._sprite = sprite
self._sprite:setGlobalZOrder(-1)
else
sprite = cc.Sprite:create("Images/YellowSquare.png")
end
local eventDispatcher = self:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener:clone(), sprite)
self._layer:addChild(sprite)
local visibleSize = cc.Director:getInstance():getVisibleSize()
sprite:setPosition(VisibleRect:left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect:center().y)
end
local function update(dt)
self._accum = self._accum + dt
if self._accum > 2.0 then
local z = self._sprite:getGlobalZOrder()
self._sprite:setGlobalZOrder(-z)
self._accum = 0
end
end
self._layer:scheduleUpdateWithPriorityLua(update, 0)
end
function GlobalZTouchTest:onExit()
self._layer:unscheduleUpdate()
end
function GlobalZTouchTest.create()
local layer = GlobalZTouchTest.extend(cc.Layer:create())
local function onNodeEvent(event)
if event == "enter" then
layer:onEnter()
elseif event == "exit" then
layer:onExit()
end
end
layer:createMenu()
layer:creatTitleAndSubTitle(curLayerIdx)
layer:registerScriptHandler(onNodeEvent)
GlobalZTouchTest._layer = layer
return layer
end
local StopPropagationTest = class("StopPropagationTest",EventDispatcherTestDemo)
local TAG_BLUE_SPRITE = 101
local TAG_BLUE_SPRITE2 = 102
local SPRITE_COUNT = 8
function StopPropagationTest.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, StopPropagationTest)
return target
end
function StopPropagationTest:onEnter()
local function onTouchBegan(touch, event)
if not self:isPointInTopHalfAreaOfScreen(touch:getLocation()) then
return false
end
local target = event:getCurrentTarget()
assert(target:getTag() == TAG_BLUE_SPRITE, "Yellow blocks shouldn't response event.")
if self:isPointInNode(touch:getLocation(), target) then
target:setOpacity(180)
return true
end
event:stopPropagation()
return false
end
local function onTouchEnded(touch, event)
local target = event:getCurrentTarget()
target:setOpacity(255)
end
local touchOneByOneListener = cc.EventListenerTouchOneByOne:create()
touchOneByOneListener:setSwallowTouches(true)
touchOneByOneListener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
touchOneByOneListener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
local function onTouchesBegan(touches, event)
if self:isPointInTopHalfAreaOfScreen(touches[1]:getLocation()) then
return
end
local target = event:getCurrentTarget()
assert(target:getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.")
if self:isPointInNode(touches[1]:getLocation(), target) then
target:setOpacity(180)
end
event:stopPropagation()
end
local function onTouchesEnd(touches, event)
if self:isPointInTopHalfAreaOfScreen(touches[1]:getLocation()) then
return
end
local target = event:getCurrentTarget()
assert(target:getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.")
if self:isPointInNode(touches[1]:getLocation(), target) then
target:setOpacity(255)
end
event:stopPropagation()
end
local touchAllAtOnceListener = cc.EventListenerTouchAllAtOnce:create()
touchAllAtOnceListener:registerScriptHandler(onTouchesBegan,cc.Handler.EVENT_TOUCHES_BEGAN )
touchAllAtOnceListener:registerScriptHandler(onTouchesEnd,cc.Handler.EVENT_TOUCHES_ENDED )
local function onKeyPressed(key, event)
local target = event:getCurrentTarget()
assert(target:getTag() == TAG_BLUE_SPRITE or target:getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.")
event:stopPropagation()
end
local keyboardEventListener = cc.EventListenerKeyboard:create()
keyboardEventListener:registerScriptHandler(onKeyPressed, cc.Handler.EVENT_KEYBOARD_PRESSED )
local eventDispatcher = self:getEventDispatcher()
for i = 0, SPRITE_COUNT - 1 do
local sprite = nil
local sprite2 = nil
if 4 == i then
sprite = cc.Sprite:create("Images/CyanSquare.png")
sprite:setTag(TAG_BLUE_SPRITE)
self:addChild(sprite, 100)
sprite2 = cc.Sprite:create("Images/CyanSquare.png")
sprite2:setTag(TAG_BLUE_SPRITE2)
self:addChild(sprite2, 100)
else
sprite = cc.Sprite:create("Images/YellowSquare.png")
self:addChild(sprite, 0)
sprite2 = cc.Sprite:create("Images/YellowSquare.png")
self:addChild(sprite2, 0)
end
eventDispatcher:addEventListenerWithSceneGraphPriority(touchOneByOneListener:clone(), sprite)
eventDispatcher:addEventListenerWithSceneGraphPriority(keyboardEventListener:clone(), sprite)
eventDispatcher:addEventListenerWithSceneGraphPriority(touchAllAtOnceListener:clone(), sprite2)
eventDispatcher:addEventListenerWithSceneGraphPriority(keyboardEventListener:clone(), sprite2)
local visibleSize = cc.Director:getInstance():getVisibleSize()
sprite:setPosition(VisibleRect:left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect:center().y + sprite2:getContentSize().height / 2 + 10)
sprite2:setPosition(VisibleRect:left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect:center().y - sprite2:getContentSize().height / 2 - 10)
end
end
function StopPropagationTest:onExit()
end
function StopPropagationTest:isPointInNode(pt, node)
local locationInNode = node:convertToNodeSpace(pt)
local s = node:getContentSize()
local rect = cc.rect(0, 0, s.width, s.height)
if cc.rectContainsPoint(rect, locationInNode) then
return true
end
return false
end
function StopPropagationTest:isPointInTopHalfAreaOfScreen(pt)
local winSize = cc.Director:getInstance():getWinSize()
if pt.y >= winSize.height / 2 then
return true
end
return false
end
function StopPropagationTest.create()
local layer = StopPropagationTest.extend(cc.Layer:create())
local function onNodeEvent(event)
if event == "enter" then
layer:onEnter()
elseif event == "exit" then
layer:onExit()
end
end
layer:createMenu()
layer:creatTitleAndSubTitle(curLayerIdx)
layer:registerScriptHandler(onNodeEvent)
return layer
end
local PauseResumeTargetTest = class("PauseResumeTargetTest",EventDispatcherTestDemo)
function PauseResumeTargetTest.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, PauseResumeTargetTest)
return target
end
function PauseResumeTargetTest:onEnter()
local origin = cc.Director:getInstance():getVisibleOrigin()
local size = cc.Director:getInstance():getVisibleSize()
local sprite1 = TouchableSpriteWithFixedPriority.create()
sprite1:setTexture("Images/CyanSquare.png")
sprite1:setPosition(cc.p(origin.x + size.width/2 - 80, origin.y + size.height/2 + 40))
self:addChild(sprite1, -10)
local sprite2 = TouchableSpriteWithFixedPriority.create()
sprite2:setTexture("Images/MagentaSquare.png")
sprite2:setPosition(cc.p(origin.x + size.width/2, origin.y + size.height/2))
self:addChild(sprite2, -20)
local sprite3 = TouchableSpriteWithFixedPriority.create()
sprite3:setTexture("Images/YellowSquare.png")
sprite3:setPosition(cc.p(0, 0))
sprite2:addChild(sprite3, -1)
local function popUp(tag, sender)
local eventDispatcher = self:getEventDispatcher()
eventDispatcher:pauseEventListenersForTarget(self, true)
local colorLayer = cc.LayerColor:create(cc.c4b(0, 0, 255, 100))
self:addChild(colorLayer, 99999)
local function closePopUp(tag, sender)
colorLayer:removeFromParent()
eventDispatcher:resumeEventListenersForTarget(self, true)
end
local closeItem = cc.MenuItemFont:create("close")
closeItem:registerScriptTapHandler(closePopUp)
closeItem:setPosition(VisibleRect:center())
local closeMenu = cc.Menu:create(closeItem)
closeMenu:setAnchorPoint(cc.p(0.0, 0.0))
closeMenu:setPosition(cc.p(0.0, 0.0))
colorLayer:addChild(closeMenu)
end
local popUpItem = cc.MenuItemFont:create("Popup")
popUpItem:registerScriptTapHandler(popUp)
popUpItem:setAnchorPoint(cc.p(1.0, 0.5))
popUpItem:setPosition(VisibleRect:right())
local menu = cc.Menu:create(popUpItem)
menu:setAnchorPoint(cc.p(0.0, 0.0))
menu:setPosition(cc.p(0.0, 0.0))
self:addChild(menu)
end
function PauseResumeTargetTest:onExit()
end
function PauseResumeTargetTest.create()
local layer = PauseResumeTargetTest.extend(cc.Layer:create())
local function onNodeEvent(event)
if event == "enter" then
layer:onEnter()
elseif event == "exit" then
layer:onExit()
end
end
layer:createMenu()
layer:creatTitleAndSubTitle(curLayerIdx)
layer:registerScriptHandler(onNodeEvent)
return layer
end
local Issue4129Test = class("Issue4129Test",EventDispatcherTestDemo)
Issue4129Test._customListener = nil
function Issue4129Test.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, Issue4129Test)
return target
end
function Issue4129Test:onEnter()
local bugFixed = false
local eventDispatcher = self:getEventDispatcher()
local function eventCustomListener(event)
local label = cc.Label:create("Yeah, this issue was fixed.", "", 20)
label:setAnchorPoint(cc.p(0, 0.5))
label:setPosition(VisibleRect:left())
self:addChild(label)
eventDispatcher:removeEventListener(self._customListener)
self._customListener = nil
bugFixed = true
end
self._customListener = cc.EventListenerCustom:create("event_come_to_background",eventCustomListener)
eventDispatcher:addEventListenerWithFixedPriority(self._customListener, 1)
local function removeAllTouch(tag, sender)
local senderItem = sender
senderItem:setString("Only 'Reset' item could be clicked")
eventDispatcher:removeAllEventListeners()
local function next(tag, sender)
assert(bugFixed, "This issue was not fixed!")
self.restartCallback()
end
local nextItem = cc.MenuItemFont:create("Reset")
nextItem:registerScriptTapHandler(next)
nextItem:setFontSizeObj(16)
nextItem:setPosition(cc.p(VisibleRect:right().x - 100 , VisibleRect:right().y - 30))
local menu2 = cc.Menu:create(nextItem)
menu2:setPosition(cc.p(0, 0))
menu2:setAnchorPoint(cc.p(0, 0))
self:addChild(menu2)
--Simulate to dispatch 'come to background' event
local event = cc.EventCustom:new("event_come_to_background")
eventDispatcher:dispatchEvent(event)
end
local removeAllTouchItem = cc.MenuItemFont:create("Remove All Listeners")
removeAllTouchItem:registerScriptTapHandler(removeAllTouch)
removeAllTouchItem:setFontSizeObj(16)
removeAllTouchItem:setPosition(cc.p(VisibleRect:right().x - 100, VisibleRect:right().y))
local menu = cc.Menu:create(removeAllTouchItem)
menu:setPosition(cc.p(0, 0))
menu:setAnchorPoint(cc.p(0, 0))
self:addChild(menu)
end
function Issue4129Test:onExit()
if nil ~= self._customListener then
local eventDispatcher = self:getEventDispatcher()
eventDispatcher:removeEventListener(self._customListener)
end
end
function Issue4129Test.create()
local layer = Issue4129Test.extend(cc.Layer:create())
local function onNodeEvent(event)
if event == "enter" then
layer:onEnter()
elseif event == "exit" then
layer:onExit()
end
end
layer:createMenu()
layer:creatTitleAndSubTitle(curLayerIdx)
layer:registerScriptHandler(onNodeEvent)
return layer
end
local Issue4160Test = class("Issue4160Test",EventDispatcherTestDemo)
Issue4160Test._customListener = nil
function Issue4160Test.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, Issue4160Test)
return target
end
function Issue4160Test:onEnter()
local origin = cc.Director:getInstance():getVisibleOrigin()
local size = cc.Director:getInstance():getVisibleSize()
local sprite1 = TouchableSpriteWithFixedPriority.create()
sprite1:setPriority(-30)
sprite1:setTexture("Images/CyanSquare.png")
sprite1:setPosition(cc.p(origin.x + size.width/2 - 80, origin.y + size.height/2 + 40))
self:addChild(sprite1, -10)
local sprite2 = TouchableSpriteWithFixedPriority.create()
sprite2:setPriority(-20)
sprite2:setTexture("Images/MagentaSquare.png")
sprite2:removeListenerOnTouchEnded(true)
sprite2:setPosition(cc.p(origin.x + size.width/2, origin.y + size.height/2))
self:addChild(sprite2, -20)
local sprite3 = TouchableSpriteWithFixedPriority.create()
sprite3:setPriority(-10)
sprite3:setTexture("Images/YellowSquare.png")
sprite3:setPosition(cc.p(0, 0))
sprite2:addChild(sprite3, -1)
end
function Issue4160Test:onExit()
end
function Issue4160Test.create()
local layer = Issue4160Test.extend(cc.Layer:create())
local function onNodeEvent(event)
if event == "enter" then
layer:onEnter()
elseif event == "exit" then
layer:onExit()
end
end
layer:createMenu()
layer:creatTitleAndSubTitle(curLayerIdx)
layer:registerScriptHandler(onNodeEvent)
return layer
end
local createFunction = local createFunction =
{ {
@ -981,6 +1510,11 @@ local createFunction =
SpriteAccelerationEventTest.create, SpriteAccelerationEventTest.create,
RemoveAndRetainNodeTest.create, RemoveAndRetainNodeTest.create,
RemoveListenerAfterAddingTest.create, RemoveListenerAfterAddingTest.create,
GlobalZTouchTest.create,
StopPropagationTest.create,
PauseResumeTargetTest.create,
Issue4129Test.create,
Issue4160Test.create,
} }
function nextEventDispatcherTest() function nextEventDispatcherTest()

@ -1 +1 @@
Subproject commit 3bd2143c9b031dd1de1b4ccbcf5b3d507b406b45 Subproject commit 22db42ddf57dd020f1e6084ff08dee8d9e2334ec

@ -1 +1 @@
Subproject commit 9aeab189f0a734423e7418c5ea11771c1db09592 Subproject commit ae27f3bafbbdda9c32e5b89c79183183486e1299

View File

@ -154,8 +154,8 @@ def ANDROID_BUILD():
def main(): def main():
print 'will build mac project.' print 'will build mac project.'
suc_build_mac = MAC_BUILD() suc_build_mac = MAC_BUILD()
print 'will build android project.' # print 'will build android project.'
suc_build_android = ANDROID_BUILD() # suc_build_android = ANDROID_BUILD()
if suc_build_mac: if suc_build_mac:
autotest(TYPE_MAC) autotest(TYPE_MAC)
if suc_build_android: if suc_build_android:

View File

@ -13,6 +13,7 @@ import time
import socket import socket
import smtplib import smtplib
from email.mime.text import MIMEText from email.mime.text import MIMEText
from os.path import join, getsize
# default console_param. # default console_param.
console_param = '[console run]' console_param = '[console run]'
@ -71,7 +72,7 @@ cocos_console_dir = 'tools/cocos2d-console/bin/'
# now cocos2d-console suport different run on Platforms, e.g: only run android on win # now cocos2d-console suport different run on Platforms, e.g: only run android on win
runSupport = { runSupport = {
'darwin' : {'mac':1,'ios':1,'android':0}, 'darwin' : {'mac':1,'ios':1,'android':1},
'win' : {'mac':0,'ios':0,'android':1}, 'win' : {'mac':0,'ios':0,'android':1},
'linux' : {'mac':0,'ios':0,'android':1} 'linux' : {'mac':0,'ios':0,'android':1}
} }
@ -174,8 +175,11 @@ def appendToResult(content):
global console_result global console_result
console_result = console_result + content console_result = console_result + content
# if any error
ANY_ERROR_IN_RUN = 0
# excute cocos command # excute cocos command
def cocos_project(level): def cocos_project(level):
global ANY_ERROR_IN_RUN
print 'will excute cocos_command: ', COCOS_CMD[level], level print 'will excute cocos_command: ', COCOS_CMD[level], level
appendToResult('will excute ' + COCOS_CMD[level] + ' command:'+"\n\r\t") appendToResult('will excute ' + COCOS_CMD[level] + ' command:'+"\n\r\t")
for proj in project_types: for proj in project_types:
@ -188,6 +192,7 @@ def cocos_project(level):
time.sleep(12) time.sleep(12)
addConsoleListenOnTCP(proj) addConsoleListenOnTCP(proj)
print 'create project',proj,' is:', not info_create print 'create project',proj,' is:', not info_create
ANY_ERROR_IN_RUN = ANY_ERROR_IN_RUN + info_create
appendToResult(' '+cmd +': ' + str(not info_create) + ".\n\r\t") appendToResult(' '+cmd +': ' + str(not info_create) + ".\n\r\t")
else: else:
for phone in phonePlats: for phone in phonePlats:
@ -199,18 +204,21 @@ def cocos_project(level):
if runSupport[curPlat][phone]: if runSupport[curPlat][phone]:
info_cmd = os.system(cmd) info_cmd = os.system(cmd)
print 'info '+COCOS_CMD[level]+':', not info_cmd print 'info '+COCOS_CMD[level]+':', not info_cmd
else : appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t")
else:
if runSupport[curPlat][phone]: if runSupport[curPlat][phone]:
if phone == 'android' and getAndroidDevices() == 0: if phone == 'android' and getAndroidDevices() == 0:
print 'no android device, please checkout the device is running ok.' strInfo = 'no android device, please checkout the device is running ok.'
continue print strInfo
info_cmd = os.system(cmd) # appendToResult(' '+strInfo+"\n\r\t")
print 'info '+COCOS_CMD[level]+':', not info_cmd else:
if level == ENUM_PARAM.run: info_cmd = os.system(cmd)
time.sleep(20) print 'info '+COCOS_CMD[level]+':', not info_cmd
strClose = close_proj(proj, phone) if level == ENUM_PARAM.run:
appendToResult(' '+strClose+"\n\r\t") time.sleep(20)
appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t") strClose = close_proj(proj, phone)
appendToResult(' '+strClose+"\n\r\t")
appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t")
# build and run according to params of provided.(lv_ignore: e.g:ignore new) # build and run according to params of provided.(lv_ignore: e.g:ignore new)
def build_run(lv_ignore): def build_run(lv_ignore):
@ -232,9 +240,9 @@ def start_android_simulator():
return return
if cocos_param >= LEVEL_COCOS[ENUM_PARAM.deploy]: if cocos_param >= LEVEL_COCOS[ENUM_PARAM.deploy]:
cmd_start = [ 'emulator -avd '+ANDROID_SIMULATOR_NAME ] cmd_start = [ 'emulator -avd '+ANDROID_SIMULATOR_NAME ]
print 'cmd_start:', cmd_start # print 'cmd_start:', cmd_start
info_start = subprocess.Popen(cmd_start, stdin=subprocess.PIPE, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # info_start = subprocess.Popen(cmd_start, stdin=subprocess.PIPE, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print 'start an android simulator:', not info_start # print 'start an android simulator:', not info_start
# send email # send email
EMAIL_KEYS={ EMAIL_KEYS={
@ -285,16 +293,48 @@ def send_mail(to_list,sub,title,content):
def sendEmail(msg): def sendEmail(msg):
send_mail(OBJ_EMAIL_INFO[EMAIL_KEYS[4]], "cocos-console-test result", 'for error.', msg) send_mail(OBJ_EMAIL_INFO[EMAIL_KEYS[4]], "cocos-console-test result", 'for error.', msg)
# get package size
def getdirsize(dir):
size = 0L
for root, dirs, files in os.walk(dir):
size += sum([getsize(join(root, name)) for name in files])
return size
APP_FILE_DIR = {
'cpp':'bin/debug/',
'lua':'runtime/'
}
APP_FILE_SUFFIX = {
'mac':'.app',
'ios':'.app',
'android':'-debug-unaligned.apk'
}
def getPackageSize():
for proj in project_types:
for phone in phonePlats:
# if runSupport[curPlat][phone]:
package_path = './'+proj+PROJ_SUFFIX+'/'+APP_FILE_DIR[proj]+phone+'/'+proj+PROJ_SUFFIX+APP_FILE_SUFFIX[phone]
print 'package_path', package_path
package_size = 0
if os.path.isfile(package_path):
package_size = os.path.getsize(package_path);
else:
package_size = getdirsize(package_path);
strSize = 'size of '+proj+PROJ_SUFFIX+' '+phone+' is:'+str(package_size/(1024))+'KB'+'\n\t'
print 'strSize:', strSize
appendToResult(strSize)
def main(): def main():
print 'in main:' print 'in main:'
# start_android_simulator() # start_android_simulator()
print 'will build_run:' print 'will build_run:'
build_run(-1) build_run(-1)
print 'end build run.' print 'ANY_ERROR_IN_RUN:', ANY_ERROR_IN_RUN
print 'end build run. and get package size.'
getPackageSize()
print 'will send email:' print 'will send email:'
if OBJ_EMAIL_INFO[ EMAIL_KEYS[5] ]:
sendEmail(console_result)
print 'console_result:', console_result print 'console_result:', console_result
if OBJ_EMAIL_INFO[ EMAIL_KEYS[5] ] or ANY_ERROR_IN_RUN:
sendEmail(console_result)
# -------------- main -------------- # -------------- main --------------
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -85,7 +85,7 @@ def main():
git_fetch_pr = "git fetch origin pull/" + str(pr_num) + "/merge" git_fetch_pr = "git fetch origin pull/" + str(pr_num) + "/merge"
ret = os.system(git_fetch_pr) ret = os.system(git_fetch_pr)
if(ret != 0): if(ret != 0):
return(1) return(2)
#checkout #checkout
git_checkout = "git checkout -b " + "pull" + str(pr_num) + " FETCH_HEAD" git_checkout = "git checkout -b " + "pull" + str(pr_num) + " FETCH_HEAD"
@ -99,7 +99,7 @@ def main():
git_update_submodule = "git submodule update --init --force" git_update_submodule = "git submodule update --init --force"
ret = os.system(git_update_submodule) ret = os.system(git_update_submodule)
if(ret != 0): if(ret != 0):
return(1) return(2)
# Generate binding glue codes # Generate binding glue codes
if(branch == 'develop'): if(branch == 'develop'):