mirror of https://github.com/axmolengine/axmol.git
Merge branch 'develop' into develop_migrate_math_lib_merge
This commit is contained in:
commit
07ac817a7c
6
AUTHORS
6
AUTHORS
|
@ -809,6 +809,12 @@ Developers:
|
|||
mgcL
|
||||
A potential memory leak fix in value's default constructor
|
||||
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:
|
||||
WenSheng Yang
|
||||
|
|
|
@ -1 +1 @@
|
|||
b78af2958c35d67fd0d06f1ca9fd7fce58799235
|
||||
334022fee8065e04cd3ba41672900023d8b45e35
|
|
@ -351,6 +351,7 @@ void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive
|
|||
|
||||
if (listener->getSceneGraphPriority() == target)
|
||||
{
|
||||
listener->setSceneGraphPriority(nullptr); // Ensure no dangling ptr to the target node.
|
||||
listener->setRegistered(false);
|
||||
listener->release();
|
||||
iter = _toAddedListeners.erase(iter);
|
||||
|
|
|
@ -237,7 +237,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
|
|||
|
||||
bool existNewLetter = false;
|
||||
int bottomHeight = _commonLineHeight - _fontAscender;
|
||||
float startX = _currentPageOrigX;
|
||||
|
||||
float startY = _currentPageOrigY;
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
|
@ -268,7 +268,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
|
|||
auto data = _currentPageData + CacheTextureWidth * (int)startY;
|
||||
_atlasTextures[_currentPage]->updateWithData(data, 0, startY,
|
||||
CacheTextureWidth, CacheTextureHeight - startY);
|
||||
startX = 0.0f;
|
||||
|
||||
startY = 0.0f;
|
||||
|
||||
_currentPageOrigY = 0;
|
||||
|
|
|
@ -497,7 +497,7 @@ void FontFreeType::renderCharAt(unsigned char *dest,int posX, int posY, unsigned
|
|||
{
|
||||
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) */
|
||||
/*int index = (iX + ( iY * destSize )) * 3;
|
||||
|
|
|
@ -1081,15 +1081,17 @@ void Label::drawTextSprite(Renderer *renderer, bool parentTransformUpdated)
|
|||
if (_shadowEnabled && _shadowNode == nullptr)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
|
@ -1240,7 +1242,7 @@ void Label::computeStringNumLines()
|
|||
{
|
||||
int quantityOfLines = 1;
|
||||
|
||||
unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
|
||||
int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
|
||||
if (stringLen < 1)
|
||||
{
|
||||
_currNumLines = stringLen;
|
||||
|
@ -1248,7 +1250,7 @@ void Label::computeStringNumLines()
|
|||
}
|
||||
|
||||
// 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')
|
||||
{
|
||||
|
|
|
@ -108,7 +108,7 @@ void NodeGrid::visit(Renderer *renderer, const Matrix &parentTransform, bool par
|
|||
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
||||
|
||||
Director::Projection beforeProjectionType;
|
||||
Director::Projection beforeProjectionType = Director::Projection::DEFAULT;
|
||||
if(_nodeGrid && _nodeGrid->isActive())
|
||||
{
|
||||
beforeProjectionType = Director::getInstance()->getProjection();
|
||||
|
|
|
@ -483,6 +483,7 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
|
|||
{
|
||||
memset(tmpQuads+oldCapactiy, 0, (_capacity - oldCapactiy)*sizeof(_quads[0]) );
|
||||
}
|
||||
_quads = nullptr;
|
||||
}
|
||||
|
||||
if (_indices == nullptr)
|
||||
|
@ -492,7 +493,6 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
|
|||
{
|
||||
memset( tmpIndices, 0, _capacity * 6 * sizeof(_indices[0]) );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -501,6 +501,7 @@ bool TextureAtlas::resizeCapacity(ssize_t newCapacity)
|
|||
{
|
||||
memset( tmpIndices+oldCapactiy, 0, (_capacity-oldCapactiy) * 6 * sizeof(_indices[0]) );
|
||||
}
|
||||
_indices = nullptr;
|
||||
}
|
||||
|
||||
if( ! ( tmpQuads && tmpIndices) ) {
|
||||
|
|
|
@ -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_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_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__
|
||||
|
|
|
@ -500,7 +500,9 @@ void FileUtils::purgeCachedEntries()
|
|||
|
||||
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;
|
||||
unsigned char* buffer = nullptr;
|
||||
|
|
|
@ -250,7 +250,6 @@ void GLViewProtocol::handleTouchesBegin(int num, intptr_t ids[], float xs[], flo
|
|||
y = ys[i];
|
||||
|
||||
auto iter = g_touchIdReorderMap.find(id);
|
||||
unusedIndex = 0;
|
||||
|
||||
// it is a new touch
|
||||
if (iter == g_touchIdReorderMap.end())
|
||||
|
|
|
@ -1552,7 +1552,7 @@ bool Image::initWithTGAData(tImageTGA* tgaData)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (tgaData->imageData != nullptr)
|
||||
if (tgaData && tgaData->imageData != nullptr)
|
||||
{
|
||||
free(tgaData->imageData);
|
||||
_data = nullptr;
|
||||
|
@ -2023,7 +2023,7 @@ bool Image::saveImageToPNG(const std::string& filePath, bool 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)
|
||||
{
|
||||
fclose(fp);
|
||||
|
|
|
@ -24,7 +24,6 @@ THE SOFTWARE.
|
|||
****************************************************************************/
|
||||
package org.cocos2dx.lib;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Locale;
|
||||
import java.lang.Runnable;
|
||||
|
@ -61,7 +60,6 @@ public class Cocos2dxHelper {
|
|||
private static String sFileDirectory;
|
||||
private static Activity sActivity = null;
|
||||
private static Cocos2dxHelperListener sCocos2dxHelperListener;
|
||||
private static ConcurrentLinkedQueue<Runnable> jobs = new ConcurrentLinkedQueue<Runnable>();
|
||||
|
||||
/**
|
||||
* Optional meta-that can be in the manifest for this component, specifying
|
||||
|
@ -75,18 +73,8 @@ public class Cocos2dxHelper {
|
|||
// 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) {
|
||||
jobs.add(r);
|
||||
((Cocos2dxActivity)sActivity).runOnGLThread(r);
|
||||
}
|
||||
|
||||
private static boolean sInited = false;
|
||||
|
|
|
@ -65,6 +65,7 @@ public class Cocos2dxSound {
|
|||
private Semaphore mSemaphore;
|
||||
|
||||
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 int SOUND_PRIORITY = 1;
|
||||
private static final int SOUND_QUALITY = 5;
|
||||
|
@ -83,7 +84,13 @@ public class Cocos2dxSound {
|
|||
}
|
||||
|
||||
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.mLeftVolume = 0.5f;
|
||||
|
|
|
@ -52,7 +52,6 @@ public:
|
|||
//TODO use material to decide if it is translucent
|
||||
inline bool isTranslucent() const { return true; }
|
||||
|
||||
void generateMaterialID();
|
||||
inline uint32_t getMaterialID() const { return _materialID; }
|
||||
|
||||
inline GLuint getTextureID() const { return _textureID; }
|
||||
|
@ -67,6 +66,9 @@ public:
|
|||
|
||||
inline const Matrix& getModelView() const { return _mv; }
|
||||
|
||||
private:
|
||||
void generateMaterialID();
|
||||
|
||||
protected:
|
||||
uint32_t _materialID;
|
||||
|
||||
|
|
|
@ -110,8 +110,6 @@ Renderer::Renderer()
|
|||
|
||||
RenderQueue defaultRenderQueue;
|
||||
_renderGroups.push_back(defaultRenderQueue);
|
||||
RenderStackElement elelment = {DEFAULT_RENDER_QUEUE, 0};
|
||||
_renderStack.push(elelment);
|
||||
_batchedQuadCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
|
||||
}
|
||||
|
||||
|
@ -260,6 +258,58 @@ int Renderer::createRenderQueue()
|
|||
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()
|
||||
{
|
||||
//Uncomment this once everything is rendered by new renderer
|
||||
|
@ -278,87 +328,9 @@ void Renderer::render()
|
|||
{
|
||||
renderqueue.sort();
|
||||
}
|
||||
|
||||
while(!_renderStack.empty())
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
visitRenderQueue(_renderGroups[0]);
|
||||
flush();
|
||||
}
|
||||
|
||||
clean();
|
||||
}
|
||||
|
||||
|
@ -379,15 +351,6 @@ void Renderer::clean()
|
|||
_batchedQuadCommands.clear();
|
||||
_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,12 +123,13 @@ protected:
|
|||
|
||||
//Draw the previews queued quads and flush previous context
|
||||
void flush();
|
||||
|
||||
void visitRenderQueue(const RenderQueue& queue);
|
||||
|
||||
void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView);
|
||||
|
||||
std::stack<int> _commandGroupStack;
|
||||
|
||||
std::stack<RenderStackElement> _renderStack;
|
||||
std::vector<RenderQueue> _renderGroups;
|
||||
|
||||
uint32_t _lastMaterialID;
|
||||
|
|
|
@ -7,8 +7,7 @@ LOCAL_MODULE_FILENAME := libcocosdenshion
|
|||
|
||||
LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
|
||||
ccdandroidUtils.cpp \
|
||||
jni/cddandroidAndroidJavaEngine.cpp \
|
||||
opensl/cddandroidOpenSLEngine.cpp
|
||||
jni/cddandroidAndroidJavaEngine.cpp
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
|
||||
|
||||
|
|
|
@ -33,41 +33,6 @@ USING_NS_CC;
|
|||
|
||||
namespace CocosDenshion {
|
||||
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) {
|
||||
// Changing file path to full path
|
||||
std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(pszFilename);
|
||||
|
|
|
@ -29,7 +29,6 @@ THE SOFTWARE.
|
|||
|
||||
namespace CocosDenshion {
|
||||
namespace android {
|
||||
bool is_buggy_device(void);
|
||||
std::string getFullPathWithoutAssetsPrefix(const char* pszFilename);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ THE SOFTWARE.
|
|||
|
||||
#include "SimpleAudioEngine.h"
|
||||
#include "jni/cddandroidAndroidJavaEngine.h"
|
||||
#include "opensl/cddandroidOpenSLEngine.h"
|
||||
#include "ccdandroidUtils.h"
|
||||
|
||||
namespace CocosDenshion {
|
||||
|
@ -34,12 +33,7 @@ namespace CocosDenshion {
|
|||
|
||||
SimpleAudioEngine* SimpleAudioEngine::getInstance() {
|
||||
if (! s_pEngine) {
|
||||
// if (CocosDenshion::android::is_buggy_device()) {
|
||||
// use the Java Audio implementation until compatibility is confirmed
|
||||
s_pEngine = new CocosDenshion::android::AndroidJavaEngine();
|
||||
// } else {
|
||||
// s_pEngine = new CocosDenshion::android::OpenSLEngine();
|
||||
// }
|
||||
s_pEngine = new CocosDenshion::android::AndroidJavaEngine();
|
||||
}
|
||||
|
||||
return s_pEngine;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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) { }
|
||||
|
||||
}
|
||||
}
|
|
@ -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__
|
|
@ -462,7 +462,7 @@ void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
|
|||
{
|
||||
ALuint buffer = AL_NONE;
|
||||
ALuint source = AL_NONE;
|
||||
soundData *data = new soundData;
|
||||
|
||||
|
||||
checkALError("preloadEffect:init");
|
||||
OpenALFile file;
|
||||
|
@ -472,7 +472,7 @@ void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
|
|||
fprintf(stderr, "Cannot read file: '%s'\n", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool success = false;
|
||||
const std::vector<OpenALDecoder *> &decoders = OpenALDecoder::getDecoders();
|
||||
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);
|
||||
checkALError("preloadEffect:alSourcei");
|
||||
|
||||
|
||||
soundData *data = new soundData;
|
||||
data->isLooped = false;
|
||||
data->buffer = buffer;
|
||||
data->source = source;
|
||||
|
|
|
@ -414,13 +414,13 @@ void Console::commandHelp(int fd, const std::string &args)
|
|||
for(auto it=_commands.begin();it!=_commands.end();++it)
|
||||
{
|
||||
auto cmd = it->second;
|
||||
mydprintf(fd, "\t%s", cmd.name);
|
||||
ssize_t tabs = strlen(cmd.name) / 8;
|
||||
mydprintf(fd, "\t%s", cmd.name.c_str());
|
||||
ssize_t tabs = strlen(cmd.name.c_str()) / 8;
|
||||
tabs = 3 - tabs;
|
||||
for(int j=0;j<tabs;j++){
|
||||
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)
|
||||
{
|
||||
ssize_t n, rc;
|
||||
|
@ -775,11 +777,20 @@ void Console::commandUpload(int fd)
|
|||
{
|
||||
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 == ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
*ptr++ = c;
|
||||
}
|
||||
else if( rc == 0 )
|
||||
{
|
||||
|
@ -875,10 +886,10 @@ bool Console::parseCommand(int fd)
|
|||
}
|
||||
else
|
||||
{
|
||||
const char err[] = "Unknown Command!\n";
|
||||
sendPrompt(fd);
|
||||
const char err[] = "upload: invalid args! Type 'help' for options\n";
|
||||
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";
|
||||
send(fd, err, sizeof(err),0);
|
||||
sendPrompt(fd);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto it = _commands.find(trim(args[0]));
|
||||
|
|
|
@ -74,8 +74,8 @@ class CC_DLL Console
|
|||
{
|
||||
public:
|
||||
struct Command {
|
||||
const char* name;
|
||||
const char* help;
|
||||
std::string name;
|
||||
std::string help;
|
||||
std::function<void(int, const std::string&)> callback;
|
||||
};
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ public:
|
|||
if (CURLE_OK != curl_easy_perform(_curl))
|
||||
return false;
|
||||
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));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
99f00c770c5e8962571ec10047eb65f8fa1d5db0
|
||||
48b548727f5f4ae9112bdb75069ad09641dcf643
|
|
@ -1002,7 +1002,7 @@ const Rect& Layout::getClippingRect()
|
|||
float scissorHeight = _size.height*t.d;
|
||||
Rect parentClippingRect;
|
||||
Layout* parent = this;
|
||||
bool firstClippingParentFounded = false;
|
||||
|
||||
while (parent)
|
||||
{
|
||||
parent = dynamic_cast<Layout*>(parent->getParent());
|
||||
|
@ -1010,12 +1010,8 @@ const Rect& Layout::getClippingRect()
|
|||
{
|
||||
if (parent->isClippingEnabled())
|
||||
{
|
||||
if (!firstClippingParentFounded)
|
||||
{
|
||||
_clippingParent = parent;
|
||||
firstClippingParentFounded = true;
|
||||
break;
|
||||
}
|
||||
_clippingParent = parent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ cpArrayNew(int size)
|
|||
|
||||
arr->num = 0;
|
||||
arr->max = (size ? size : 4);
|
||||
arr->arr = (void **)cpcalloc(arr->max, sizeof(void**));
|
||||
arr->arr = (void **)cpcalloc(arr->max, sizeof(void*));
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
|
63
setup.py
63
setup.py
|
@ -69,7 +69,8 @@ class SetEnvVar(object):
|
|||
RESULT_UPDATED = 1
|
||||
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=(.+)'
|
||||
|
||||
def __init__(self):
|
||||
|
@ -84,20 +85,33 @@ class SetEnvVar(object):
|
|||
def _isLinux(self):
|
||||
return sys.platform.startswith('linux')
|
||||
|
||||
def _is_mac(self):
|
||||
return sys.platform == 'darwin'
|
||||
|
||||
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('~')
|
||||
if os.path.exists(os.path.join(home, '.bash_profile')):
|
||||
file_to_write = os.path.join(home, '.bash_profile')
|
||||
elif os.path.exists(os.path.join(home, '.bash_login')):
|
||||
file_to_write = os.path.join(home, '.bash_login')
|
||||
elif os.path.exists(os.path.join(home, '.profile')):
|
||||
file_to_write = os.path.join(home, '.profile')
|
||||
else:
|
||||
for file_name in file_list:
|
||||
file_path = os.path.join(home, file_name)
|
||||
if os.path.exists(file_path):
|
||||
file_to_write = file_path
|
||||
break
|
||||
|
||||
if file_to_write is None:
|
||||
self.need_backup = False
|
||||
file_to_write = os.path.join(home, '.bash_profile')
|
||||
file = open(file_to_write, 'w')
|
||||
file.close()
|
||||
file_to_write = os.path.join(home, file_list[0])
|
||||
file_obj = open(file_to_write, 'w')
|
||||
file_obj.close()
|
||||
|
||||
return file_to_write
|
||||
|
||||
|
@ -191,12 +205,19 @@ class SetEnvVar(object):
|
|||
ret = os.environ[var]
|
||||
except Exception:
|
||||
if not self._isWindows():
|
||||
home = os.path.expanduser('~')
|
||||
for name in SetEnvVar.UNIX_CHECK_FILES:
|
||||
path = os.path.join(home, name)
|
||||
ret = self._search_unix_variable(var, path)
|
||||
if ret is not None:
|
||||
break
|
||||
file_list = None
|
||||
if self._isLinux():
|
||||
file_list = SetEnvVar.LINUX_CHECK_FILES
|
||||
elif self._is_mac():
|
||||
file_list = SetEnvVar.MAC_CHECK_FILES
|
||||
|
||||
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:
|
||||
import _winreg
|
||||
try:
|
||||
|
@ -434,9 +455,13 @@ class SetEnvVar(object):
|
|||
patten = re.compile(str_re)
|
||||
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
|
||||
for file_name in SetEnvVar.UNIX_CHECK_FILES:
|
||||
for file_name in file_list:
|
||||
path = os.path.join(home, file_name)
|
||||
if os.path.isfile(path):
|
||||
lines = []
|
||||
|
|
|
@ -1 +1 @@
|
|||
ee48702a58c132b4999c618ce6cd69b78f0d9cd9
|
||||
31d62e35548799d9402b2c5d8038d2f4313a19a5
|
|
@ -35,6 +35,7 @@ static std::function<Layer*()> createFunctions[] =
|
|||
{
|
||||
CL(NewSpriteTest),
|
||||
CL(NewSpriteBatchTest),
|
||||
CL(GroupCommandTest),
|
||||
CL(NewClippingNodeTest),
|
||||
CL(NewDrawNodeTest),
|
||||
CL(NewCullingTest),
|
||||
|
@ -222,6 +223,56 @@ std::string NewSpriteTest::subtitle() const
|
|||
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
|
||||
|
||||
NewSpriteBatchTest::NewSpriteBatchTest()
|
||||
|
|
|
@ -56,6 +56,19 @@ protected:
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -232,14 +232,12 @@ RenderTextureIssue937::RenderTextureIssue937()
|
|||
auto background = LayerColor::create(Color4B(200,200,200,255));
|
||||
addChild(background);
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
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");
|
||||
spr_nonpremulti->setPosition(Point(16,16));
|
||||
|
||||
|
||||
|
||||
spr_nonpremulti->setPosition(Point(s.width/2-16, s.height/2-16));
|
||||
|
||||
/* A2 & B2 setup */
|
||||
auto rend = RenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888);
|
||||
|
@ -249,20 +247,17 @@ RenderTextureIssue937::RenderTextureIssue937()
|
|||
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
|
||||
// [[rend sprite] setBlendFunc:(BlendFunc) {GL_ONE, GL_ONE_MINUS_SRC_ALPHA}];
|
||||
|
||||
rend->begin();
|
||||
spr_premulti->visit();
|
||||
spr_nonpremulti->visit();
|
||||
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->end();
|
||||
|
||||
rend->setPosition(Point(s.width/2+16, s.height/2));
|
||||
|
||||
|
|
|
@ -353,86 +353,83 @@ void TestController::addConsoleAutoTest()
|
|||
for (int i = 0; i < g_testCount; i++)
|
||||
{
|
||||
// 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:");
|
||||
msg += g_aTestNames[i].test_name;
|
||||
send(fd, msg.c_str(), strlen(msg.c_str()),0);
|
||||
send(fd, "\n",1,0);
|
||||
continue;
|
||||
}
|
||||
std::string t1("");
|
||||
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( [&](){
|
||||
currentController->callback()->runThisTest();
|
||||
currentController->callback()->release();
|
||||
BaseTest *t = app->getCurrentTest();
|
||||
if(t != nullptr)
|
||||
{
|
||||
t->nextCallback(nullptr);
|
||||
}
|
||||
} );
|
||||
wait(1);
|
||||
BaseTest* firstTest = app->getCurrentTest();
|
||||
if(firstTest == nullptr)
|
||||
BaseTest * curTest = app->getCurrentTest();
|
||||
if(curTest == nullptr)
|
||||
{
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
std::string t1("");
|
||||
t1 += firstTest->subtitle();
|
||||
send(fd, t1.c_str(), strlen(t1.c_str()),0);
|
||||
std::string title("");
|
||||
title += curTest->subtitle();
|
||||
send(fd, title.c_str(), strlen(title.c_str()),0);
|
||||
send(fd, "\n",1,0);
|
||||
wait(2);
|
||||
|
||||
//printf("rtti:%s", typeid(firstTest).name());
|
||||
while(1)
|
||||
|
||||
if(t1 == title)
|
||||
{
|
||||
//currentTest->nextCallback(nullptr);
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < g_testCount; i++)
|
||||
{
|
||||
if(args == g_aTestNames[i].test_name)
|
||||
{
|
||||
// create the test scene and run it
|
||||
auto scene = g_aTestNames[i].callback();
|
||||
if (scene)
|
||||
{
|
||||
std::string msg("autotest: running test:");
|
||||
msg += args;
|
||||
send(fd, msg.c_str(), strlen(msg.c_str()),0);
|
||||
send(fd, "\n",1,0);
|
||||
currentController = &g_aTestNames[i];
|
||||
std::string msg("autotest: running test:");
|
||||
msg += args;
|
||||
send(fd, msg.c_str(), strlen(msg.c_str()),0);
|
||||
send(fd, "\n",1,0);
|
||||
|
||||
currentController = &g_aTestNames[i];
|
||||
sched->performFunctionInCocosThread( [&](){
|
||||
currentController->callback()->runThisTest();
|
||||
currentController->callback()->release();
|
||||
} );
|
||||
return;
|
||||
}
|
||||
|
||||
sched->performFunctionInCocosThread( [&](){
|
||||
auto scene = currentController->callback();
|
||||
if(scene)
|
||||
{
|
||||
scene->runThisTest();
|
||||
scene->release();
|
||||
}
|
||||
} );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ local testArray =
|
|||
SpriteAccelerationEvent = 6,
|
||||
RemoveAndRetainNode = 7,
|
||||
RemoveListenerAfterAdding = 8,
|
||||
GlobalZTouchTest = 9,
|
||||
StopPropagationTest = 10,
|
||||
PauseResumeTargetTest = 11,
|
||||
Issue4129Test = 12,
|
||||
Issue4160Test = 13,
|
||||
}
|
||||
|
||||
local curLayerIdx = testArray.TouchableSprite
|
||||
|
@ -60,6 +65,16 @@ function EventDispatcherTestDemo.title(idx)
|
|||
return "RemoveAndRetainNodeTest"
|
||||
elseif testArray.RemoveListenerAfterAdding == idx then
|
||||
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
|
||||
|
||||
|
@ -80,6 +95,16 @@ function EventDispatcherTestDemo.subTitle(idx)
|
|||
return "Sprite should be removed after 5s, add to scene again after 5s"
|
||||
elseif testArray.RemoveListenerAfterAdding == idx then
|
||||
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
|
||||
|
||||
|
@ -136,7 +161,7 @@ function EventDispatcherTestDemo:createMenu()
|
|||
|
||||
menu:setPosition(cc.p(0, 0))
|
||||
|
||||
self:addChild(menu)
|
||||
self:addChild(menu, 9999)
|
||||
end
|
||||
|
||||
function EventDispatcherTestDemo:creatTitleAndSubTitle(idx)
|
||||
|
@ -227,16 +252,9 @@ function TouchableSpriteTest:onEnter()
|
|||
eventDispatcher:addEventListenerWithSceneGraphPriority(listener1, sprite1)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
local function removeAllTouchItem(tag, sender)
|
||||
|
@ -286,6 +304,7 @@ TouchableSpriteWithFixedPriority.__index = TouchableSpriteWithFixedPriority
|
|||
TouchableSpriteWithFixedPriority._listener = nil
|
||||
TouchableSpriteWithFixedPriority._fixedPriority = 0
|
||||
TouchableSpriteWithFixedPriority._useNodePriority = false
|
||||
TouchableSpriteWithFixedPriority._removeListenerOnTouchEnded = false
|
||||
|
||||
function TouchableSpriteWithFixedPriority.extend(target)
|
||||
local t = tolua.getpeer(target)
|
||||
|
@ -298,6 +317,8 @@ function TouchableSpriteWithFixedPriority.extend(target)
|
|||
end
|
||||
|
||||
function TouchableSpriteWithFixedPriority:onEnter()
|
||||
local eventDispatcher = self:getEventDispatcher()
|
||||
|
||||
local function onTouchBegan(touch, event)
|
||||
local locationInNode = self:convertToNodeSpace(touch:getLocation())
|
||||
local s = self:getContentSize()
|
||||
|
@ -317,6 +338,10 @@ function TouchableSpriteWithFixedPriority:onEnter()
|
|||
|
||||
local function onTouchEnded(touch, event)
|
||||
self:setColor(cc.c3b(255, 255, 255))
|
||||
if self._removeListenerOnTouchEnded then
|
||||
eventDispatcher:removeEventListener(self._listener)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local listener = cc.EventListenerTouchOneByOne:create()
|
||||
|
@ -327,8 +352,7 @@ function TouchableSpriteWithFixedPriority:onEnter()
|
|||
listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
|
||||
listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
|
||||
|
||||
local eventDispatcher = self:getEventDispatcher()
|
||||
if self._useNodePriority then
|
||||
if 0 == self._fixedPriority then
|
||||
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)
|
||||
else
|
||||
eventDispatcher:addEventListenerWithFixedPriority(listener,self._fixedPriority)
|
||||
|
@ -345,6 +369,10 @@ function TouchableSpriteWithFixedPriority:setPriority(fixedPriority)
|
|||
self._useNodePriority = false
|
||||
end
|
||||
|
||||
function TouchableSpriteWithFixedPriority:removeListenerOnTouchEnded(toRemove)
|
||||
self._removeListenerOnTouchEnded = toRemove
|
||||
end
|
||||
|
||||
function TouchableSpriteWithFixedPriority:setPriorityWithThis(useNodePriority)
|
||||
self._fixedPriority = 0
|
||||
self._useNodePriority = useNodePriority
|
||||
|
@ -970,6 +998,507 @@ function RemoveListenerAfterAddingTest.create()
|
|||
return layer
|
||||
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 =
|
||||
{
|
||||
|
@ -981,6 +1510,11 @@ local createFunction =
|
|||
SpriteAccelerationEventTest.create,
|
||||
RemoveAndRetainNodeTest.create,
|
||||
RemoveListenerAfterAddingTest.create,
|
||||
GlobalZTouchTest.create,
|
||||
StopPropagationTest.create,
|
||||
PauseResumeTargetTest.create,
|
||||
Issue4129Test.create,
|
||||
Issue4160Test.create,
|
||||
}
|
||||
|
||||
function nextEventDispatcherTest()
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3bd2143c9b031dd1de1b4ccbcf5b3d507b406b45
|
||||
Subproject commit 22db42ddf57dd020f1e6084ff08dee8d9e2334ec
|
|
@ -1 +1 @@
|
|||
Subproject commit 9aeab189f0a734423e7418c5ea11771c1db09592
|
||||
Subproject commit ae27f3bafbbdda9c32e5b89c79183183486e1299
|
|
@ -154,8 +154,8 @@ def ANDROID_BUILD():
|
|||
def main():
|
||||
print 'will build mac project.'
|
||||
suc_build_mac = MAC_BUILD()
|
||||
print 'will build android project.'
|
||||
suc_build_android = ANDROID_BUILD()
|
||||
# print 'will build android project.'
|
||||
# suc_build_android = ANDROID_BUILD()
|
||||
if suc_build_mac:
|
||||
autotest(TYPE_MAC)
|
||||
if suc_build_android:
|
||||
|
|
|
@ -13,6 +13,7 @@ import time
|
|||
import socket
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from os.path import join, getsize
|
||||
|
||||
# default console_param.
|
||||
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
|
||||
runSupport = {
|
||||
'darwin' : {'mac':1,'ios':1,'android':0},
|
||||
'darwin' : {'mac':1,'ios':1,'android':1},
|
||||
'win' : {'mac':0,'ios':0,'android':1},
|
||||
'linux' : {'mac':0,'ios':0,'android':1}
|
||||
}
|
||||
|
@ -174,8 +175,11 @@ def appendToResult(content):
|
|||
global console_result
|
||||
console_result = console_result + content
|
||||
|
||||
# if any error
|
||||
ANY_ERROR_IN_RUN = 0
|
||||
# excute cocos command
|
||||
def cocos_project(level):
|
||||
global ANY_ERROR_IN_RUN
|
||||
print 'will excute cocos_command: ', COCOS_CMD[level], level
|
||||
appendToResult('will excute ' + COCOS_CMD[level] + ' command:'+"\n\r\t")
|
||||
for proj in project_types:
|
||||
|
@ -188,6 +192,7 @@ def cocos_project(level):
|
|||
time.sleep(12)
|
||||
addConsoleListenOnTCP(proj)
|
||||
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")
|
||||
else:
|
||||
for phone in phonePlats:
|
||||
|
@ -199,18 +204,21 @@ def cocos_project(level):
|
|||
if runSupport[curPlat][phone]:
|
||||
info_cmd = os.system(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 phone == 'android' and getAndroidDevices() == 0:
|
||||
print 'no android device, please checkout the device is running ok.'
|
||||
continue
|
||||
info_cmd = os.system(cmd)
|
||||
print 'info '+COCOS_CMD[level]+':', not info_cmd
|
||||
if level == ENUM_PARAM.run:
|
||||
time.sleep(20)
|
||||
strClose = close_proj(proj, phone)
|
||||
appendToResult(' '+strClose+"\n\r\t")
|
||||
appendToResult(' '+cmd +': ' + str(not info_cmd) + ".\n\r\t")
|
||||
strInfo = 'no android device, please checkout the device is running ok.'
|
||||
print strInfo
|
||||
# appendToResult(' '+strInfo+"\n\r\t")
|
||||
else:
|
||||
info_cmd = os.system(cmd)
|
||||
print 'info '+COCOS_CMD[level]+':', not info_cmd
|
||||
if level == ENUM_PARAM.run:
|
||||
time.sleep(20)
|
||||
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)
|
||||
def build_run(lv_ignore):
|
||||
|
@ -232,9 +240,9 @@ def start_android_simulator():
|
|||
return
|
||||
if cocos_param >= LEVEL_COCOS[ENUM_PARAM.deploy]:
|
||||
cmd_start = [ 'emulator -avd '+ANDROID_SIMULATOR_NAME ]
|
||||
print 'cmd_start:', cmd_start
|
||||
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 'cmd_start:', cmd_start
|
||||
# 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
|
||||
|
||||
# send email
|
||||
EMAIL_KEYS={
|
||||
|
@ -285,16 +293,48 @@ def send_mail(to_list,sub,title,content):
|
|||
def sendEmail(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():
|
||||
print 'in main:'
|
||||
# start_android_simulator()
|
||||
print 'will build_run:'
|
||||
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:'
|
||||
if OBJ_EMAIL_INFO[ EMAIL_KEYS[5] ]:
|
||||
sendEmail(console_result)
|
||||
print 'console_result:', console_result
|
||||
if OBJ_EMAIL_INFO[ EMAIL_KEYS[5] ] or ANY_ERROR_IN_RUN:
|
||||
sendEmail(console_result)
|
||||
|
||||
# -------------- main --------------
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -85,7 +85,7 @@ def main():
|
|||
git_fetch_pr = "git fetch origin pull/" + str(pr_num) + "/merge"
|
||||
ret = os.system(git_fetch_pr)
|
||||
if(ret != 0):
|
||||
return(1)
|
||||
return(2)
|
||||
|
||||
#checkout
|
||||
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"
|
||||
ret = os.system(git_update_submodule)
|
||||
if(ret != 0):
|
||||
return(1)
|
||||
return(2)
|
||||
|
||||
# Generate binding glue codes
|
||||
if(branch == 'develop'):
|
||||
|
|
Loading…
Reference in New Issue