Merge pull request #16457 from minggo/merge-v3.13

Update rapid json to version 1.1.0.
This commit is contained in:
minggo 2016-08-29 15:22:01 +08:00 committed by GitHub
commit df3b33cd59
114 changed files with 1879 additions and 1275 deletions

View File

@ -37,4 +37,4 @@ before_install:
# whitelist
branches:
only:
- v3
- v3.13

View File

@ -1,3 +1,85 @@
cocos2d-x-3.13 Aug 22 2016
[HIGHLIGHT] add VR plugin
[HIGHLIGHT] support ETC1 alpha channel
[HIGHLIGHT] fix AudioEngine performance for Android 4.2+
[HIGHLIGHT] improve canvas renderer performance with dirty region
[HIGHLIGHT] add Andorid arm-64 support
[HIGHLIGHT] use luajit for Android arm-64
[HIGHLIGHT] switch to use gcc 4.9
[HIGHLIGHT] upgrade CURL to 7.50.0
[HIGHLIGHT] upgrade Spine to 3.4
[HIGHLIGHT] upgrade glfw to 3.2
[HIGHLIGHT] upgrade luajit to 2.1.0-beta2
[NEW] add `Configuration::supportsMapBuffer()`
[NEW] support hexagonal tile maps
[NEW] add `ListView::setScrollDuration()`
[NEW] implement `SimpleAudioEngine::willPlayBackgroundMusic()` on Android
[NEW] implement `AudioEngine::preload()` on Android
[NEW] add `cc.Node['.classname']` to get class name for tolua C++ class in lua
[NEW] support direct load in web engine to show scene without loading all resources, resources will be loaded asynchronously
[NEW] add `cc.view.setOrientation` API to force orientation in web browser
[REFINE] move back to use gcc 4.9 on Android to fix some crash bugs
[REFINE] optimize Node sorting speed for 64-bit
[REFINE] using `chrono::steady_clock()` instread of gettimeofday for FPS calculation
[REFINE] use `fstat` instead of `fseek` and `ftell` for performance to read file content
[REFINE] use std::string reference instead of char* for `utils::findChild()`
[REFINE] make `MotionStreak` _maxPoints framerate independent
[REFINE] support utf-8 bom lua script
[REFINE] can show utf-8 characters in MessageBox and lua log on win32
[REFINE] improve stability of new WebGL renderer provided in v3.12
[REFINE] update js auto binding settings with new ndk version
[REFINE] improve evalString implementation which was rely on deprecated API
[REFINE] improve js bindings code quality by merging part of cocos2d-x-lite repo
[REFINE] sources path in sourcemap of web engine are now relative
[FIX] `GLProgram::link()` only check result in debug mode or WinRT
[FIX] PageView::clone() misses cloing some member variables
[FIX] potential crash of `AudioEngine::uncache()`
[FIX] websocket receives package size > 1023 error
[FIX] the color of underline is different from the text color
[FIX] memory leak in `MenuItemToggle::create()`
[FIX] crash after removing a physics body right after adding it
[FIX] SpriteBatchNode crash if CC_SPRITE_DEBUG_DRAW is enabled
[FIX] memory leak in `Data::move()`
[FIX] crash in `EaseExpoentialOut::clone()`
[FIX] buffer over-read in `GLProgram::updateUniformLocation()`
[FIX] `dirty` variable incorrectly reset with a multiple camera setup causing drawing issues on Sprite
[FIX] fix label text formatter right alignment
[FIX] `bsd_signal` link error on Android
[FIX] crash while decoding small MP3 file on Android
[FIX] `AppDelegate::applicationWillEnterForeground()` is invoked at launch on Android
[FIX] fix `relocation overflow in R_ARM_THM_CALL` on Android
[FIX] navigation bar doesn't hide if show and dismiss keyboard on Android
[FIX] `utils::getTimeInMilliseconds()` may return wrong value on Android
[FiX] link error that `bsd_sinal` is not defined if building with API level 21+ and uses libwebsockets on Android
[FIX] compiling error with Android 6.0(API 23)
[FIX] music is not resumed when app is reactived on iOS
[FIX] random crash in `alGenBuffers` at startup on iOS
[FIX] can not play audio if uncache and play audio many times on iOS
[FIX] `Text::create()` crash if it contains invalid string on iOS
[FIX] `FileUtils::removeDirectory()` can not work on all platforms except iOS and Mac
[FIX] can not compile cocos2d-x on Mac OS X 10.10 and lower
[FIX] new js project link error on linux
[FIX] AudioEngine can not play large ogg file on Windows
[FIX] design resolution broken after minimize on desk platforms
[FIX] can not get the `backClicked` in lua
[FIX] `cc.convertColor` issue in lua
[FIX] browser version detection
[FIX] compiling error with `cocos gen-libs`
[FIX] spine track entry can circle reference each other
[FIX] global object can leak during restart in JSB
[FIX] progress timer nested sprite can't change color in Canvas
[FIX] layout refresh issue in web engine
[FIX] dom element position synchronization issue in web engine
[FIX] armature position shake when parent node move in web engine
[FIX] rendering issue for Armature using sprite as display in bone in web engine
[FIX] Scale9Sprite GRAY state isn't correct in WebGL
[FIX] touch startPoint can be overwrote in web engine
[FIX] syncStatus transform dirty flag isn't resetting in web engine
cocos2d-x-3.12 Jul 06 2016
[HIGHLIGHT] add VR support

View File

@ -177,7 +177,7 @@ Main features
Build Requirements
------------------
* Mac OS X 10.7+, Xcode 5.1+
* Mac OS X 10.7+, Xcode 7+
* or Ubuntu 12.10+, CMake 2.6+
* or Windows 7+, VS 2013+
* Python 2.7.5

View File

@ -386,7 +386,7 @@ void MotionStreak::onDraw(const Mat4 &transform, uint32_t flags)
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
GL::bindTexture2D( _texture->getName() );
GL::bindTexture2D( _texture );
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, _texCoords);

View File

@ -78,7 +78,7 @@ bool ProgressTimer::initWithSprite(Sprite* sp)
setSprite(sp);
// shader state
setGLProgramState(sp->getGLProgramState()/*GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)*/);
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR, sp->getTexture()));
return true;
}
@ -512,7 +512,7 @@ void ProgressTimer::onDraw(const Mat4 &transform, uint32_t flags)
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::bindTexture2D( _sprite->getTexture()->getName() );
GL::bindTexture2D( _sprite->getTexture() );
glVertexAttribPointer( GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(_vertexData[0]) , &_vertexData[0].vertices);
glVertexAttribPointer( GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(_vertexData[0]), &_vertexData[0].texCoords);

View File

@ -92,7 +92,21 @@ bool TMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *la
_atlasIndexArray = ccCArrayNew(totalNumberOfTiles);
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(_layerSize.width * _mapTileSize.width, _layerSize.height * _mapTileSize.height)));
float width = 0;
float height = 0;
if (_layerOrientation == TMXOrientationHex) {
if (_staggerAxis == TMXStaggerAxis_X) {
height = _mapTileSize.height * (_layerSize.height + 0.5);
width = (_mapTileSize.width + _hexSideLength) * ((int)(_layerSize.width / 2)) + _mapTileSize.width * ((int)_layerSize.width % 2);
} else {
width = _mapTileSize.width * (_layerSize.width + 0.5);
height = (_mapTileSize.height + _hexSideLength) * ((int)(_layerSize.height / 2)) + _mapTileSize.height * ((int)_layerSize.height % 2);
}
} else {
width = _layerSize.width * _mapTileSize.width;
height = _layerSize.height * _mapTileSize.height;
}
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(width, height)));
_useAutomaticVertexZ = false;
_vertexZvalue = 0;

View File

@ -161,7 +161,13 @@ bool TMXMapInfo::initWithTMXFile(const std::string& tmxFile)
}
TMXMapInfo::TMXMapInfo()
: _mapSize(Size::ZERO)
: _orientation(TMXOrientationOrtho)
, _staggerAxis(TMXStaggerAxis_Y)
, _staggerIndex(TMXStaggerIndex_Even)
, _hexSideLength(0)
, _parentElement(0)
, _parentGID(0)
, _mapSize(Size::ZERO)
, _tileSize(Size::ZERO)
, _layerAttribs(0)
, _storingCharacters(false)

View File

@ -364,15 +364,23 @@ void AudioEngine::stopAll()
void AudioEngine::uncache(const std::string &filePath)
{
if(_audioPathIDMap.find(filePath) != _audioPathIDMap.end()){
auto itEnd = _audioPathIDMap[filePath].end();
for (auto it = _audioPathIDMap[filePath].begin() ; it != itEnd; ++it) {
auto audioID = *it;
auto audioIDsIter = _audioPathIDMap.find(filePath);
if (audioIDsIter != _audioPathIDMap.end())
{
//@Note: For safely iterating elements from the audioID list, we need to copy the list
// since 'AudioEngine::remove' may be invoked in '_audioEngineImpl->stop' synchronously.
// If this happens, it will break the iteration, and crash will appear on some devices.
std::list<int> copiedIDs(audioIDsIter->second);
for (int audioID : copiedIDs)
{
_audioEngineImpl->stop(audioID);
auto itInfo = _audioIDInfoMap.find(audioID);
if (itInfo != _audioIDInfoMap.end()){
if (itInfo->second.profileHelper) {
if (itInfo != _audioIDInfoMap.end())
{
if (itInfo->second.profileHelper)
{
itInfo->second.profileHelper->audioIDs.remove(audioID);
}
_audioIDInfoMap.erase(audioID);
@ -381,7 +389,8 @@ void AudioEngine::uncache(const std::string &filePath)
_audioPathIDMap.erase(filePath);
}
if (_audioEngineImpl){
if (_audioEngineImpl)
{
_audioEngineImpl->uncache(filePath);
}
}

View File

@ -26,6 +26,7 @@ LOCAL_SRC_FILES := AudioEngine-inl.cpp \
audio_utils/format.c \
audio_utils/minifloat.cpp \
audio_utils/primitives.c \
utils/Utils.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include

View File

@ -133,9 +133,24 @@ bool AudioDecoder::start()
bool ret;
do
{
ret = decodeToPcm(); if (!ret) break;
ret = resample(); if (!ret) break;
ret = interleave(); if (!ret) break;
ret = decodeToPcm();
if (!ret)
{
ALOGE("decodeToPcm (%s) failed!", _url.c_str());
break;
}
ret = resample();
if (!ret)
{
ALOGE("resample (%s) failed!", _url.c_str());
break;
}
ret = interleave();
if (!ret)
{
ALOGE("interleave (%s) failed!", _url.c_str());
break;
}
auto nowTime = clockNow();
@ -143,6 +158,8 @@ bool AudioDecoder::start()
intervalInMS(oldTime, nowTime));
} while(false);
ALOGV_IF(!ret, "%s returns false, decode (%s)", __FUNCTION__, _url.c_str());
return ret;
}

View File

@ -96,6 +96,60 @@ static void removeItemFromVector(std::vector<T>& v, T item)
}
}
void AudioMixerController::initTrack(Track* track, std::vector<Track*>& tracksToRemove)
{
uint32_t channelMask = audio_channel_out_mask_from_count(2);
int32_t name = _mixer->getTrackName(channelMask, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_SESSION_OUTPUT_MIX);
if (name < 0)
{
// If we could not get the track name, it means that there're MAX_NUM_TRACKS tracks
// So ignore the new track.
tracksToRemove.push_back(track);
}
else
{
_mixer->setBufferProvider(name, track);
_mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
_mixingBuffer.buf);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_FORMAT,
(void *) (uintptr_t) AUDIO_FORMAT_PCM_16_BIT);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::FORMAT,
(void *) (uintptr_t) AUDIO_FORMAT_PCM_16_BIT);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_CHANNEL_MASK,
(void *) (uintptr_t) channelMask);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::CHANNEL_MASK,
(void *) (uintptr_t) channelMask);
track->setState(Track::State::PLAYING);
track->setName(name);
_mixer->enable(name);
std::lock_guard<std::mutex> lk(track->_volumeDirtyMutex);
gain_minifloat_packed_t volume = track->getVolumeLR();
float lVolume = float_from_gain(gain_minifloat_unpack_left(volume));
float rVolume = float_from_gain(gain_minifloat_unpack_right(volume));
_mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &lVolume);
_mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &rVolume);
track->setVolumeDirty(false);
track->setInitialized(true);
}
}
void AudioMixerController::mixOneFrame()
{
_isMixingFrame = true;
@ -140,60 +194,17 @@ void AudioMixerController::mixOneFrame()
if (state == Track::State::IDLE)
{
uint32_t channelMask = audio_channel_out_mask_from_count(2);
int32_t name = _mixer->getTrackName(channelMask, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_SESSION_OUTPUT_MIX);
if (name < 0)
{
// If we could not get the track name, it means that there're MAX_NUM_TRACKS tracks
// So ignore the new track.
tracksToRemove.push_back(track);
}
else
{
_mixer->setBufferProvider(name, track);
_mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
_mixingBuffer.buf);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_FORMAT,
(void *) (uintptr_t) AUDIO_FORMAT_PCM_16_BIT);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::FORMAT,
(void *) (uintptr_t) AUDIO_FORMAT_PCM_16_BIT);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::MIXER_CHANNEL_MASK,
(void *) (uintptr_t) channelMask);
_mixer->setParameter(
name,
AudioMixer::TRACK,
AudioMixer::CHANNEL_MASK,
(void *) (uintptr_t) channelMask);
track->setState(Track::State::PLAYING);
track->setName(name);
_mixer->enable(name);
std::lock_guard<std::mutex> lk(track->_volumeDirtyMutex);
gain_minifloat_packed_t volume = track->getVolumeLR();
float lVolume = float_from_gain(gain_minifloat_unpack_left(volume));
float rVolume = float_from_gain(gain_minifloat_unpack_right(volume));
_mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &lVolume);
_mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &rVolume);
track->setVolumeDirty(false);
}
initTrack(track, tracksToRemove);
}
else if (state == Track::State::PLAYING)
{
ALOG_ASSERT(track->getName() >= 0);
if (!track->isInitialized())
{
initTrack(track, tracksToRemove);
}
int name = track->getName();
ALOG_ASSERT(name >= 0);
std::lock_guard<std::mutex> lk(track->_volumeDirtyMutex);
@ -213,6 +224,11 @@ void AudioMixerController::mixOneFrame()
}
else if (state == Track::State::RESUMED)
{
if (!track->isInitialized())
{
initTrack(track, tracksToRemove);
}
if (track->getPrevState() == Track::State::PAUSED)
{
_mixer->enable(track->getName());
@ -225,6 +241,11 @@ void AudioMixerController::mixOneFrame()
}
else if (state == Track::State::PAUSED)
{
if (!track->isInitialized())
{
initTrack(track, tracksToRemove);
}
if (track->getPrevState() == Track::State::PLAYING || track->getPrevState() == Track::State::RESUMED)
{
_mixer->disable(track->getName());
@ -236,13 +257,20 @@ void AudioMixerController::mixOneFrame()
}
else if (state == Track::State::STOPPED)
{
if (track->getPrevState() != Track::State::IDLE)
if (track->isInitialized())
{
_mixer->deleteTrackName(track->getName());
if (track->getPrevState() != Track::State::IDLE)
{
_mixer->deleteTrackName(track->getName());
}
else
{
ALOGV("Stop track (%p) while it's in IDLE state!", track);
}
}
else
{
ALOGV("Stop track (%p) while it's in IDLE state!", track);
ALOGV("Track (%p) hasn't been initialized yet!", track);
}
tracksToRemove.push_back(track);
}

View File

@ -54,7 +54,6 @@ public:
bool init();
bool addTrack(Track* track);
bool hasPlayingTacks();
void pause();
@ -67,6 +66,7 @@ public:
private:
void destroy();
void initTrack(Track* track, std::vector<Track*>& tracksToRemove);
private:
int _bufferSizeInFrames;

View File

@ -32,6 +32,7 @@ THE SOFTWARE.
#include "audio/android/PcmAudioService.h"
#include "audio/android/CCThreadPool.h"
#include "audio/android/ICallerThreadUtils.h"
#include "audio/android/utils/Utils.h"
#include <sys/system_properties.h>
#include <stdlib.h>
@ -47,12 +48,9 @@ static int getSystemAPILevel()
return __systemApiLevel;
}
int apiLevel = -1;
char sdk_ver_str[PROP_VALUE_MAX] = {0};
auto len = __system_property_get("ro.build.version.sdk", sdk_ver_str);
if (len > 0)
int apiLevel = getSystemProperty("ro.build.version.sdk");
if (apiLevel > 0)
{
apiLevel = atoi(sdk_ver_str);
ALOGD("Android API level: %d", apiLevel);
}
else
@ -131,6 +129,7 @@ IAudioPlayer *AudioPlayerProvider::getAudioPlayer(const std::string &audioFilePa
PcmData pcmData = iter->second;
_pcmCacheMutex.unlock();
player = obtainPcmAudioPlayer(audioFilePath, pcmData);
ALOGV_IF(player == nullptr, "%s, %d: player is nullptr, path: %s", __FUNCTION__, __LINE__, audioFilePath.c_str());
}
else
{
@ -150,20 +149,22 @@ IAudioPlayer *AudioPlayerProvider::getAudioPlayer(const std::string &audioFilePa
std::thread::id threadId = std::this_thread::get_id();
preloadEffect(info, [threadId, pcmData, isSucceed, isReturnFromCache](bool succeed, PcmData data){
preloadEffect(info, [&info, threadId, pcmData, isSucceed, isReturnFromCache](bool succeed, PcmData data){
// If the callback is in the same thread as caller's, it means that we found it
// in the cache
*isReturnFromCache = std::this_thread::get_id() == threadId;
*pcmData = data;
*isSucceed = succeed;
});
ALOGV("FileInfo (%p), Set isSucceed flag: %d, path: %s", &info, succeed, info.url.c_str());
}, true);
if (!*isReturnFromCache)
{
std::unique_lock<std::mutex> lk(_preloadWaitMutex);
// Wait for 2 seconds for the decoding in sub thread finishes.
ALOGV("Waiting preload (%s) to finish ...", audioFilePath.c_str());
ALOGV("FileInfo (%p), Waiting preload (%s) to finish ...", &info, audioFilePath.c_str());
_preloadWaitCond.wait_for(lk, std::chrono::seconds(2));
ALOGV("FileInfo (%p), Waitup preload (%s) ...", &info, audioFilePath.c_str());
}
if (*isSucceed)
@ -171,16 +172,31 @@ IAudioPlayer *AudioPlayerProvider::getAudioPlayer(const std::string &audioFilePa
if (pcmData->isValid())
{
player = obtainPcmAudioPlayer(info.url, *pcmData);
ALOGV_IF(player == nullptr, "%s, %d: player is nullptr, path: %s", __FUNCTION__, __LINE__, audioFilePath.c_str());
}
else
{
ALOGE("pcm data is invalid, path: %s", audioFilePath.c_str());
}
}
else
{
ALOGE("FileInfo (%p), preloadEffect (%s) failed", &info, audioFilePath.c_str());
}
}
else
{
player = createUrlAudioPlayer(info);
ALOGV_IF(player == nullptr, "%s, %d: player is nullptr, path: %s", __FUNCTION__, __LINE__, audioFilePath.c_str());
}
}
else
{
ALOGE("File info is invalid, path: %s", audioFilePath.c_str());
}
}
ALOGV_IF(player == nullptr, "%s, %d return nullptr", __FUNCTION__, __LINE__);
return player;
}
@ -212,11 +228,11 @@ void AudioPlayerProvider::preloadEffect(const std::string &audioFilePath, const
cb(succeed, data);
});
});
}, false);
}
// Used internally
void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const PreloadCallback& cb)
void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const PreloadCallback& cb, bool isPreloadInPlay2d)
{
PcmData pcmData;
@ -276,7 +292,7 @@ void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const Preload
_preloadCallbackMap.insert(std::make_pair(audioFilePath, std::move(callbacks)));
}
_threadPool->pushTask([this, audioFilePath](int tid) {
_threadPool->pushTask([this, audioFilePath, isPreloadInPlay2d](int tid) {
ALOGV("AudioPlayerProvider::preloadEffect: (%s)", audioFilePath.c_str());
PcmData d;
AudioDecoder decoder(_engineItf, audioFilePath, _bufferSizeInFrames, _deviceSampleRate, _fdGetterCallback);
@ -306,7 +322,10 @@ void AudioPlayerProvider::preloadEffect(const AudioFileInfo &info, const Preload
}
_preloadCallbackMap.erase(preloadIter);
_preloadWaitCond.notify_one();
if (isPreloadInPlay2d)
{
_preloadWaitCond.notify_one();
}
}
});
}

View File

@ -88,7 +88,7 @@ private:
UrlAudioPlayer *createUrlAudioPlayer(const AudioFileInfo &info);
void preloadEffect(const AudioFileInfo &info, const PreloadCallback& cb);
void preloadEffect(const AudioFileInfo &info, const PreloadCallback& cb, bool isPreloadInPlay2d);
AudioFileInfo getFileInfo(const std::string &audioFilePath);

View File

@ -23,6 +23,7 @@
#include <pthread.h>
#include <new>
#include "audio/android/cutils/log.h"
#include "audio/android/utils/Utils.h"
//#include <cutils/properties.h>
#include "audio/android/audio_utils/include/audio_utils/primitives.h"
#include "audio/android/AudioResampler.h"
@ -106,16 +107,12 @@ static AudioResampler::src_quality defaultQuality = AudioResampler::DEFAULT_QUAL
void AudioResampler::init_routine()
{
char value[PROPERTY_VALUE_MAX];
if (__system_property_get("af.resampler.quality", value) > 0) {
char *endptr;
unsigned long l = strtoul(value, &endptr, 0);
if (*endptr == '\0') {
defaultQuality = (src_quality) l;
ALOGD("forcing AudioResampler quality to %d", defaultQuality);
if (defaultQuality < DEFAULT_QUALITY || defaultQuality > VERY_HIGH_QUALITY) {
defaultQuality = DEFAULT_QUALITY;
}
int resamplerQuality = getSystemProperty("af.resampler.quality");
if (resamplerQuality > 0) {
defaultQuality = (src_quality) resamplerQuality;
ALOGD("forcing AudioResampler quality to %d", defaultQuality);
if (defaultQuality < DEFAULT_QUALITY || defaultQuality > VERY_HIGH_QUALITY) {
defaultQuality = DEFAULT_QUALITY;
}
}
}

View File

@ -40,6 +40,7 @@ Track::Track(const PcmData &pcmData)
, _volume(1.0f)
, _isVolumeDirty(true)
, _isLoop(false)
, _isInitialized(false)
{
init(_pcmData.pcmBuffer->data(), _pcmData.numFrames, _pcmData.bitsPerSample / 8 * _pcmData.numChannels);
}

View File

@ -79,6 +79,12 @@ private:
inline void setVolumeDirty(bool isDirty)
{ _isVolumeDirty = isDirty; };
inline bool isInitialized() const
{ return _isInitialized; };
inline void setInitialized(bool isInitialized)
{ _isInitialized = isInitialized; };
private:
PcmData _pcmData;
State _prevState;
@ -89,6 +95,7 @@ private:
bool _isVolumeDirty;
std::mutex _volumeDirtyMutex;
bool _isLoop;
bool _isInitialized;
friend class AudioMixerController;
};

View File

@ -27,10 +27,10 @@ THE SOFTWARE.
#include "audio/android/jni/cddandroidAndroidJavaEngine.h"
#include <stdlib.h>
#include <cstdio>
#include <sys/system_properties.h>
#include "audio/android/ccdandroidUtils.h"
#include "audio/android/utils/Utils.h"
#include "audio/include/AudioEngine.h"
#include "platform/android/jni/JniHelper.h"
@ -44,31 +44,11 @@ using namespace cocos2d;
using namespace cocos2d::experimental;
using namespace CocosDenshion::android;
namespace
{
int getSDKVersion()
{
int ret = -1;
std::string command = "getprop ro.build.version.sdk";
FILE* file = popen(command.c_str(), "r");
if (file)
{
char output[100];
if (std::fgets(output, sizeof(output), file) != nullptr)
ret = std::atoi(output);
pclose(file);
}
return ret;
}
}
AndroidJavaEngine::AndroidJavaEngine()
: _implementBaseOnAudioEngine(false)
, _effectVolume(1.f)
{
int sdkVer = getSDKVersion();
int sdkVer = getSystemProperty("ro.build.version.sdk");
if (sdkVer > 0)
{
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d", "android SDK version:%d", sdkVer);

View File

@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2016 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 "audio/android/utils/Utils.h"
#include <cstdio>
#include <cstdlib>
namespace cocos2d { namespace experimental {
int getSystemProperty(const std::string& property)
{
int ret = -1;
std::string command = "getprop " + property;
FILE* file = popen(command.c_str(), "r");
if (file)
{
char output[100];
if (std::fgets(output, sizeof(output), file) != nullptr)
ret = std::atoi(output);
pclose(file);
}
return ret;
}
}} // end of namespace cocos2d { namespace experimental

View File

@ -0,0 +1,29 @@
/****************************************************************************
Copyright (c) 2016 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 <string>
namespace cocos2d { namespace experimental {
extern int getSystemProperty(const std::string& property);
}}

View File

@ -21,6 +21,9 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#define LOG_TAG "AudioCache"
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
@ -35,10 +38,68 @@
#include "base/CCDirector.h"
#include "base/CCScheduler.h"
#include <windows.h>
#define PCMDATA_CACHEMAXSIZE 2621440
using namespace cocos2d::experimental;
//FIXME: Move _winLog, winLog to a separated file
static void _winLog(const char *format, va_list args)
{
static const int MAX_LOG_LENGTH = 16 * 1024;
int bufferSize = MAX_LOG_LENGTH;
char* buf = nullptr;
do
{
buf = new (std::nothrow) char[bufferSize];
if (buf == nullptr)
return; // not enough memory
int ret = vsnprintf(buf, bufferSize - 3, format, args);
if (ret < 0)
{
bufferSize *= 2;
delete[] buf;
}
else
break;
} while (true);
strcat(buf, "\n");
int pos = 0;
int len = strlen(buf);
char tempBuf[MAX_LOG_LENGTH + 1] = { 0 };
WCHAR wszBuf[MAX_LOG_LENGTH + 1] = { 0 };
do
{
std::copy(buf + pos, buf + pos + MAX_LOG_LENGTH, tempBuf);
tempBuf[MAX_LOG_LENGTH] = 0;
MultiByteToWideChar(CP_UTF8, 0, tempBuf, -1, wszBuf, sizeof(wszBuf));
OutputDebugStringW(wszBuf);
pos += MAX_LOG_LENGTH;
} while (pos < len);
delete[] buf;
}
void audioLog(const char * format, ...)
{
va_list args;
va_start(args, format);
_winLog(format, args);
va_end(args);
}
AudioCache::AudioCache()
: _pcmData(nullptr)
, _pcmDataSize(0)
@ -100,7 +161,7 @@ void AudioCache::readDataTask()
vf = new OggVorbis_File;
int openCode;
if (openCode = ov_fopen(FileUtils::getInstance()->getSuitableFOpen(_fileFullPath).c_str(), vf)){
log("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _fileFullPath.c_str(), openCode);
ALOGE("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _fileFullPath.c_str(), openCode);
goto ExitThread;
}
@ -119,13 +180,13 @@ void AudioCache::readDataTask()
int error = MPG123_OK;
mpg123handle = mpg123_new(nullptr, &error);
if (!mpg123handle){
log("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
ALOGE("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
goto ExitThread;
}
if (mpg123_open(mpg123handle,_fileFullPath.c_str()) != MPG123_OK ||
mpg123_getformat(mpg123handle, &rate, &_channels, &_mp3Encoding) != MPG123_OK) {
log("Trouble with mpg123: %s\n", mpg123_strerror(mpg123handle) );
ALOGE("Trouble with mpg123: %s\n", mpg123_strerror(mpg123handle) );
goto ExitThread;
}

View File

@ -41,6 +41,38 @@
#define QUEUEBUFFER_NUM 5
#define QUEUEBUFFER_TIME_STEP 0.1f
// log, CCLOG aren't threadsafe, since we uses sub threads for parsing pcm data, threadsafe log output
// is needed. Define the following macros (ALOGV, ALOGD, ALOGI, ALOGW, ALOGE) for threadsafe log output.
//FIXME:Move the definition of the following macros to a separated file.
void audioLog(const char * format, ...);
#define QUOTEME_(x) #x
#define QUOTEME(x) QUOTEME_(x)
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
#define ALOGV(fmt, ...) audioLog("V/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#else
#define ALOGV(fmt, ...) do {} while(false)
#endif
#define ALOGD(fmt, ...) audioLog("D/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#define ALOGI(fmt, ...) audioLog("I/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#define ALOGW(fmt, ...) audioLog("W/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#define ALOGE(fmt, ...) audioLog("E/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
#define CHECK_AL_ERROR_DEBUG() \
do { \
GLenum __error = alGetError(); \
if (__error) { \
ALOGE("OpenAL error 0x%04X in %s %s %d\n", __error, __FILE__, __FUNCTION__, __LINE__); \
} \
} while (false)
#else
#define CHECK_AL_ERROR_DEBUG()
#endif
NS_CC_BEGIN
namespace experimental{

View File

@ -21,6 +21,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#define LOG_TAG "AudioEngine-Win32"
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
@ -88,7 +90,7 @@ bool AudioEngineImpl::init()
alGenSources(MAX_AUDIOINSTANCES, _alSources);
alError = alGetError();
if(alError != AL_NO_ERROR){
log("%s:generating sources fail! error = %x\n", __FUNCTION__, alError);
ALOGE("%s:generating sources fail! error = %x\n", __FUNCTION__, alError);
break;
}
@ -140,14 +142,14 @@ AudioCache* AudioEngineImpl::preload(const std::string& filePath, std::function<
}
else
{
log("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
ALOGE("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
break;
}
}
}
else
{
log("Unsupported media type file: %s\n", filePath.c_str());
ALOGE("Unsupported media type file: %s\n", filePath.c_str());
break;
}
@ -245,7 +247,7 @@ void AudioEngineImpl::setVolume(int audioID,float volume)
auto error = alGetError();
if (error != AL_NO_ERROR) {
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
}
}
@ -266,7 +268,7 @@ void AudioEngineImpl::setLoop(int audioID, bool loop)
auto error = alGetError();
if (error != AL_NO_ERROR) {
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
}
}
@ -283,7 +285,7 @@ bool AudioEngineImpl::pause(int audioID)
auto error = alGetError();
if (error != AL_NO_ERROR) {
ret = false;
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
return ret;
@ -297,7 +299,7 @@ bool AudioEngineImpl::resume(int audioID)
auto error = alGetError();
if (error != AL_NO_ERROR) {
ret = false;
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
return ret;
@ -313,7 +315,7 @@ bool AudioEngineImpl::stop(int audioID)
auto error = alGetError();
if (error != AL_NO_ERROR) {
ret = false;
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
}
@ -380,7 +382,7 @@ float AudioEngineImpl::getCurrentTime(int audioID)
auto error = alGetError();
if (error != AL_NO_ERROR) {
log("%s, audio id:%d,error code:%x", __FUNCTION__,audioID,error);
ALOGE("%s, audio id:%d,error code:%x", __FUNCTION__,audioID,error);
}
}
}
@ -407,7 +409,7 @@ bool AudioEngineImpl::setCurrentTime(int audioID, float time)
auto error = alGetError();
if (error != AL_NO_ERROR) {
log("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
ALOGE("%s: audio id = %d, error = %x\n", __FUNCTION__,audioID,error);
}
ret = true;
}

View File

@ -21,6 +21,9 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#define LOG_TAG "AudioPlayer"
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
@ -109,7 +112,7 @@ bool AudioPlayer::play2d(AudioCache* cache)
alSourceQueueBuffers(_alSource, QUEUEBUFFER_NUM, _bufferIds);
}
else {
log("%s:alGenBuffers error code:%x", __FUNCTION__,alError);
ALOGE("%s:alGenBuffers error code:%x", __FUNCTION__,alError);
return false;
}
}
@ -125,7 +128,7 @@ bool AudioPlayer::play2d(AudioCache* cache)
auto alError = alGetError();
if (alError != AL_NO_ERROR) {
log("%s:alSourcePlay error code:%x\n", __FUNCTION__, alError);
ALOGE("%s:alSourcePlay error code:%x\n", __FUNCTION__, alError);
return false;
}
@ -135,6 +138,26 @@ bool AudioPlayer::play2d(AudioCache* cache)
return true;
}
int AudioPlayer::readPcmData(char* buffer, int bufferSize, const std::function<int/*readBytes*/(char* /*buf*/, int /*bytesToRead*/)>& fileReader)
{
assert(buffer != nullptr && bufferSize > 0);
int readBytes = 0;
int readBytesOnce = 0;
int remainBytes = bufferSize;
do
{
readBytesOnce = fileReader(buffer + readBytes, remainBytes);
if (readBytesOnce > 0)
{
readBytes += readBytesOnce;
remainBytes -= readBytesOnce;
}
} while (readBytesOnce > 0 && readBytes < bufferSize);
return readBytes;
}
void AudioPlayer::rotateBufferThread(int offsetFrame)
{
ALint sourceState;
@ -142,6 +165,9 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
mpg123_handle* mpg123handle = nullptr;
OggVorbis_File* vorbisFile = nullptr;
std::function<int(char*, int)> fileReader = nullptr;
std::function<void(int)> fileSeeker = nullptr;
auto audioFileFormat = _audioCache->_fileFormat;
char* tmpBuffer = (char*)malloc(_audioCache->_queBufferBytes);
@ -152,7 +178,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
int error = MPG123_OK;
mpg123handle = mpg123_new(nullptr, &error);
if (!mpg123handle){
log("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
ALOGE("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
goto ExitBufferThread;
}
long rate = 0;
@ -160,7 +186,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
int mp3Encoding = 0;
if (mpg123_open(mpg123handle,_audioCache->_fileFullPath.c_str()) != MPG123_OK
|| mpg123_getformat(mpg123handle, &rate, &channels, &mp3Encoding) != MPG123_OK){
log("Trouble with mpg123: %s\n", mpg123_strerror(mpg123handle) );
ALOGE("Trouble with mpg123: %s\n", mpg123_strerror(mpg123handle) );
goto ExitBufferThread;
}
@ -178,7 +204,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
vorbisFile = new OggVorbis_File;
int openCode;
if (openCode = ov_fopen(FileUtils::getInstance()->getSuitableFOpen(_audioCache->_fileFullPath).c_str(), vorbisFile)){
log("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _audioCache->_fileFullPath.c_str(), openCode);
ALOGE("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _audioCache->_fileFullPath.c_str(), openCode);
goto ExitBufferThread;
}
if (offsetFrame != 0) {
@ -192,6 +218,30 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
alSourcePlay(_alSource);
if (audioFileFormat == AudioCache::FileFormat::MP3)
{
fileReader = [&](char* buffer, int bufferSize) -> int {
size_t ret = 0;
mpg123_read(mpg123handle, (unsigned char*)buffer, bufferSize, &ret);
return ret;
};
fileSeeker = [&](int pos) {
mpg123_seek(mpg123handle, pos, SEEK_SET);
};
}
else if (audioFileFormat == AudioCache::FileFormat::OGG)
{
fileReader = [&](char* buffer, int bufferSize) -> int {
int current_section = 0;
return ov_read(vorbisFile, buffer, bufferSize, 0, 2, 1, &current_section);
};
fileSeeker = [&](int pos) {
ov_pcm_seek(vorbisFile, pos);
};
}
while (!_exitThread) {
alGetSourcei(_alSource, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_PLAYING) {
@ -203,18 +253,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
if (_timeDirty) {
_timeDirty = false;
offsetFrame = _currTime * _audioCache->_sampleRate;
switch (audioFileFormat)
{
case AudioCache::FileFormat::MP3:
mpg123_seek(mpg123handle,offsetFrame,SEEK_SET);
break;
case AudioCache::FileFormat::OGG:
ov_pcm_seek(vorbisFile,offsetFrame);
break;
default:
break;
}
fileSeeker(offsetFrame);
}
else {
_currTime += QUEUEBUFFER_TIME_STEP;
@ -227,49 +266,37 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
}
}
size_t readRet = 0;
if(audioFileFormat == AudioCache::FileFormat::MP3)
{
mpg123_read(mpg123handle,(unsigned char*)tmpBuffer, _audioCache->_queBufferBytes,&readRet);
if (readRet <= 0) {
if (_loop) {
mpg123_seek(mpg123handle,0,SEEK_SET);
mpg123_read(mpg123handle,(unsigned char*)tmpBuffer, _audioCache->_queBufferBytes,&readRet);
} else {
_exitThread = true;
break;
}
int readRet = readPcmData(tmpBuffer, _audioCache->_queBufferBytes, fileReader);
if (readRet <= 0) {
if (_loop) {
fileSeeker(0);
readRet = readPcmData(tmpBuffer, _audioCache->_queBufferBytes, fileReader);
}
else
{
_audioCache->_bytesOfRead += readRet;
else {
_exitThread = true;
break;
}
}
else if(audioFileFormat == AudioCache::FileFormat::OGG)
else
{
int current_section;
readRet = ov_read(vorbisFile,tmpBuffer,_audioCache->_queBufferBytes,0,2,1,&current_section);
if (readRet <= 0) {
if (_loop) {
ov_pcm_seek(vorbisFile,0);
readRet = ov_read(vorbisFile,tmpBuffer,_audioCache->_queBufferBytes,0,2,1,&current_section);
} else {
_exitThread = true;
break;
}
}
_audioCache->_bytesOfRead += readRet;
}
//ALOGV("readRet: %d, queBufferBytes: %d", (int)readRet, _audioCache->_queBufferBytes);
ALuint bid;
alSourceUnqueueBuffers(_alSource, 1, &bid);
CHECK_AL_ERROR_DEBUG();
alBufferData(bid, _audioCache->_alBufferFormat, tmpBuffer, readRet, _audioCache->_sampleRate);
CHECK_AL_ERROR_DEBUG();
alSourceQueueBuffers(_alSource, 1, &bid);
CHECK_AL_ERROR_DEBUG();
}
}
std::unique_lock<std::mutex> lk(_sleepMutex);
if (_exitThread)
{
ALOGV("thread exit...");
break;
}
@ -292,6 +319,7 @@ ExitBufferThread:
}
free(tmpBuffer);
_readForRemove = true;
ALOGV("%s exited.\n", __FUNCTION__);
}
bool AudioPlayer::setLoop(bool loop)

View File

@ -61,7 +61,8 @@ public:
protected:
void rotateBufferThread(int offsetFrame);
bool play2d(AudioCache* cache);
int readPcmData(char* buffer, int bufferSize, const std::function<int/*readBytes*/(char* /*buf*/, int /*bytesToRead*/)>& fileReader);
AudioCache* _audioCache;
float _volume;

View File

@ -88,13 +88,13 @@ void MciPlayer::Open(const char* pFileName, UINT uId)
MCI_OPEN_PARMS mciOpen = {0};
MCIERROR mciError;
mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID;
WCHAR* fileNameWideChar = new WCHAR[nLen + 1];
BREAK_IF(! fileNameWideChar);
MultiByteToWideChar(CP_ACP, 0, pFileName, nLen + 1, fileNameWideChar, nLen + 1);
WCHAR* fileNameWideChar = new WCHAR[nLen + 1];
BREAK_IF(! fileNameWideChar);
MultiByteToWideChar(CP_ACP, 0, pFileName, nLen + 1, fileNameWideChar, nLen + 1);
mciOpen.lpstrElementName = fileNameWideChar;
mciError = mciSendCommand(0,MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
CC_SAFE_DELETE_ARRAY(mciOpen.lpstrElementName);
CC_SAFE_DELETE_ARRAY(mciOpen.lpstrElementName);
BREAK_IF(mciError);
_dev = mciOpen.wDeviceID;

View File

@ -45,8 +45,6 @@ Ref::Ref()
, _luaID (0)
, _scriptObject(nullptr)
, _rooted(false)
, _scriptOwned(false)
,_referenceCountAtRootTime(0)
#endif
{
#if CC_ENABLE_SCRIPT_BINDING

View File

@ -161,16 +161,6 @@ public:
When true, it means that the object was already rooted.
*/
bool _rooted;
unsigned int _referenceCountAtRootTime;
/**
* The life of the object is scrolled by the scripting engine.
*
* When the object is controlled by the scripting engine
* some additional logic is performed, like Rooting/Unrooting
* the object when retain/release is called.
*/
bool _scriptOwned;
#endif
// Memory leak diagnostic data (only included when CC_REF_LEAK_DETECTION is defined and its value isn't zero)

View File

@ -30,132 +30,256 @@
<ClCompile Include="..\Animation.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\AnimationState.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\AnimationStateData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Atlas.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\AtlasAttachmentLoader.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Attachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\AttachmentLoader.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\AttachmentVertices.cpp" />
<ClCompile Include="..\Bone.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\BoneData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\BoundingBoxAttachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Cocos2dAttachmentLoader.cpp" />
<ClCompile Include="..\Event.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\EventData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\extension.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\IkConstraint.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\IkConstraintData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Json.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\MeshAttachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\PathAttachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\PathConstraint.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\PathConstraintData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\RegionAttachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Skeleton.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\SkeletonAnimation.cpp" />
<ClCompile Include="..\SkeletonBatch.cpp" />
<ClCompile Include="..\SkeletonBounds.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\SkeletonData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\SkeletonJson.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\SkeletonRenderer.cpp" />
<ClCompile Include="..\Skin.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\Slot.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\SlotData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\spine-cocos2dx.cpp" />
<ClCompile Include="..\TransformConstraint.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\TransformConstraintData.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
<ClCompile Include="..\VertexAttachment.c">
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
</ClCompile>
</ItemGroup>
<ItemGroup>

View File

@ -595,7 +595,15 @@ void WebSocket::onSubThreadStarted()
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = _wsProtocols;
info.extensions = exts;
// FIXME: Disable 'permessage-deflate' extension temporarily because of issues:
// https://github.com/cocos2d/cocos2d-x/issues/16045, https://github.com/cocos2d/cocos2d-x/issues/15767
// libwebsockets issue: https://github.com/warmcat/libwebsockets/issues/593
// Currently, we couldn't find out the exact reason.
// libwebsockets official said it's probably an issue of user code
// since 'libwebsockets' passed AutoBahn stressed Test.
// info.extensions = exts;
info.gid = -1;
info.uid = -1;

View File

@ -12,4 +12,4 @@
android.library=true
# Project target.
target=android-21
target=android-10

View File

@ -418,15 +418,28 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
protected void hideVirtualButton() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= 19) {
// use reflection to remove dependence of API level
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
Class viewClass = View.class;
final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION");
final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN");
final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
final int SYSTEM_UI_FLAG_FULLSCREEN = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_FULLSCREEN");
final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY");
final int SYSTEM_UI_FLAG_LAYOUT_STABLE = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_STABLE");
// getWindow().getDecorView().setSystemUiVisibility();
final Object[] parameters = new Object[]{SYSTEM_UI_FLAG_LAYOUT_STABLE
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| SYSTEM_UI_FLAG_IMMERSIVE_STICKY};
Cocos2dxReflectionHelper.<Void>invokeInstanceMethod(getWindow().getDecorView(),
"setSystemUiVisibility",
new Class[]{Integer.TYPE},
parameters);
}
}

View File

@ -53,7 +53,7 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView {
private static Handler sHandler;
private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
private static Cocos2dxTextInputWraper sCocos2dxTextInputWraper;
private static Cocos2dxTextInputWrapper sCocos2dxTextInputWraper;
private Cocos2dxRenderer mCocos2dxRenderer;
private Cocos2dxEditBox mCocos2dxEditText;
@ -90,7 +90,7 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView {
this.setFocusableInTouchMode(true);
Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView = this;
Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper = new Cocos2dxTextInputWraper(this);
Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper = new Cocos2dxTextInputWrapper(this);
Cocos2dxGLSurfaceView.sHandler = new Handler() {
@Override

View File

@ -123,17 +123,25 @@ public class Cocos2dxHelper {
int sampleRate = 44100;
int bufferSizeInFrames = 192;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= 17) {
AudioManager am = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
String strSampleRate = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
String strBufferSizeInFrames = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
// use reflection to remove dependence of API 17 when compiling
// AudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
final Class audioManagerClass = AudioManager.class;
Object[] parameters = new Object[]{Cocos2dxReflectionHelper.<String>getConstantValue(audioManagerClass, "PROPERTY_OUTPUT_SAMPLE_RATE")};
final String strSampleRate = Cocos2dxReflectionHelper.<String>invokeInstanceMethod(am, "getProperty", new Class[]{String.class}, parameters);
// AudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
parameters = new Object[]{Cocos2dxReflectionHelper.<String>getConstantValue(audioManagerClass, "PROPERTY_OUTPUT_FRAMES_PER_BUFFER")};
final String strBufferSizeInFrames = Cocos2dxReflectionHelper.<String>invokeInstanceMethod(am, "getProperty", new Class[]{String.class}, parameters);
sampleRate = Integer.parseInt(strSampleRate);
bufferSizeInFrames = Integer.parseInt(strBufferSizeInFrames);
Log.d(TAG, "sampleRate: " + sampleRate + ", framesPerBuffer: " + bufferSizeInFrames);
} else {
Log.d(TAG, "android version is lower than " + Build.VERSION_CODES.JELLY_BEAN_MR1);
Log.d(TAG, "android version is lower than 17");
}
nativeSetAudioDeviceInfo(isSupportLowLatency, sampleRate, bufferSizeInFrames);

View File

@ -0,0 +1,74 @@
/****************************************************************************
Copyright (c) 2016 cocos2d-x.org
Copyright (c) 2016 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.
****************************************************************************/
package org.cocos2dx.lib;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Cocos2dxReflectionHelper {
public static <T> T getConstantValue(final Class aClass, final String constantName) {
try {
return (T)aClass.getDeclaredField(constantName).get(null);
} catch (NoSuchFieldException e) {
Log.e("error", "can not find " + constantName + " in " + aClass.getName());
}
catch (IllegalAccessException e) {
Log.e("error", constantName + " is not accessable");
}
catch (IllegalArgumentException e) {
Log.e("error", "arguments error when get " + constantName);
}
catch (Exception e) {
Log.e("error", "can not get constant" + constantName);
}
return null;
}
public static <T> T invokeInstanceMethod(final Object instance, final String methodName,
final Class[] parameterTypes, final Object[] parameters) {
final Class aClass = instance.getClass();
try {
final Method method = aClass.getMethod(methodName, parameterTypes);
return (T)method.invoke(instance, parameters);
} catch (NoSuchMethodException e) {
Log.e("error", "can not find " + methodName + " in " + aClass.getName());
}
catch (IllegalAccessException e) {
Log.e("error", methodName + " is not accessible");
}
catch (IllegalArgumentException e) {
Log.e("error", "arguments are error when invoking " + methodName);
}
catch (InvocationTargetException e) {
Log.e("error", "an exception was thrown by the invoked method when invoking " + methodName);
}
return null;
}
}

View File

@ -33,12 +33,12 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class Cocos2dxTextInputWraper implements TextWatcher, OnEditorActionListener {
public class Cocos2dxTextInputWrapper implements TextWatcher, OnEditorActionListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxTextInputWraper.class.getSimpleName();
private static final String TAG = Cocos2dxTextInputWrapper.class.getSimpleName();
// ===========================================================
// Fields
@ -52,7 +52,7 @@ public class Cocos2dxTextInputWraper implements TextWatcher, OnEditorActionListe
// Constructors
// ===========================================================
public Cocos2dxTextInputWraper(final Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) {
public Cocos2dxTextInputWrapper(final Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSurfaceView = pCocos2dxGLSurfaceView;
}

View File

@ -38,6 +38,7 @@ THE SOFTWARE.
#include "platform/android/jni/JniHelper.h"
#include "network/CCDownloader-android.h"
#include <android/log.h>
#include <android/api-level.h>
#include <jni.h>
#define LOG_TAG "main"
@ -50,6 +51,28 @@ using namespace cocos2d;
extern "C"
{
// ndk break compatibility, refer to https://github.com/cocos2d/cocos2d-x/issues/16267 for detail information
// should remove it when using NDK r13 since NDK r13 will add back bsd_signal()
#if __ANDROID_API__ > 19
#include <signal.h>
#include <dlfcn.h>
typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t);
bsd_signal_func_t bsd_signal_func = NULL;
__sighandler_t bsd_signal(int s, __sighandler_t f) {
if (bsd_signal_func == NULL) {
// For now (up to Android 7.0) this is always available
bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal");
if (bsd_signal_func == NULL) {
__android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!");
}
}
return bsd_signal_func(s, f);
}
#endif // __ANDROID_API__ > 19
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);

View File

@ -152,6 +152,15 @@ void bindTexture2D(GLuint textureId)
GL::bindTexture2DN(0, textureId);
}
void bindTexture2D(Texture2D* texture)
{
GL::bindTexture2DN(0, texture->getName());
auto alphaTexID = texture->getAlphaTextureName();
if (alphaTexID > 0) {
GL::bindTexture2DN(1, alphaTexID);
}
}
void bindTexture2DN(GLuint textureUnit, GLuint textureId)
{
#if CC_ENABLE_GL_STATE_CACHE

View File

@ -41,7 +41,7 @@ NS_CC_BEGIN
*/
class GLProgram;
class Texture2D;
namespace GL {
/** Vertex attrib flags. */
@ -126,6 +126,16 @@ void CC_DLL enableVertexAttribs(uint32_t flags);
*/
void CC_DLL bindTexture2D(GLuint textureId);
/**
* If the texture is not already bound to texture unit 0, it binds it.
*
* If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly.
*
* @remark: It will bind alpha texture to support ETC1 alpha channel.
* @since v3.13
*/
void CC_DLL bindTexture2D(Texture2D* texture);
/**
* If the texture is not already bound to a given unit, it binds it.
*

View File

@ -479,8 +479,8 @@ ScriptingCore::ScriptingCore()
, _cx(nullptr)
, _jsInited(false)
, _needCleanup(false)
//, _global(nullptr)
//, _debugGlobal(nullptr)
, _global(nullptr)
, _debugGlobal(nullptr)
, _callFromScript(false)
{
// set utf8 strings internally (we don't need utf16)
@ -520,12 +520,39 @@ void ScriptingCore::string_report(JS::HandleValue val) {
bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal, const char *filename, JSContext* cx, JS::HandleObject global)
{
JSAutoCompartment ac(cx, global);
return JS_EvaluateScript(cx, global, string, (unsigned)strlen(string), "ScriptingCore::evalString", 1, outVal);
JS::PersistentRootedScript script(cx);
if (script == nullptr) {
return false;
}
JS::CompileOptions op(cx);
op.setUTF8(true);
std::string content = string;
bool ok = false;
bool evaluatedOK = false;
if (!content.empty())
{
ok = JS::Compile(cx, global, op, content.c_str(), content.size(), &(script) );
}
if (ok) {
evaluatedOK = JS_ExecuteScript(cx, global, script, outVal);
if (false == evaluatedOK) {
cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", content.c_str());
JS_ReportPendingException(cx);
}
}
else {
cocos2d::log("ScriptingCore:: evaluateScript fail: %s", content.c_str());
}
return evaluatedOK;
}
bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal)
{
return evalString(string, outVal, nullptr, _cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
return evalString(string, outVal, nullptr, _cx, global);
}
bool ScriptingCore::evalString(const char *string)
@ -629,19 +656,19 @@ void ScriptingCore::createGlobalContext() {
JS_SetGCZeal(this->_cx, 2, JS_DEFAULT_ZEAL_FREQ);
#endif
_global.construct(_cx);
_global.ref() = NewGlobalObject(_cx);
_global = new (std::nothrow) JS::PersistentRootedObject(_rt, NewGlobalObject(_cx));
JS::RootedObject global(_cx, _global->get());
// Removed in Firefox v34
js::SetDefaultObjectForContext(_cx, _global.ref());
js::SetDefaultObjectForContext(_cx, global);
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
runScript("script/jsb_prepare.js");
for (std::vector<sc_register_sth>::iterator it = registrationList.begin(); it != registrationList.end(); it++) {
sc_register_sth callback = *it;
callback(_cx, _global.ref());
callback(_cx, global);
}
_needCleanup = true;
@ -657,7 +684,7 @@ static std::string RemoveFileExt(const std::string& filePath) {
}
}
JS::PersistentRootedScript* ScriptingCore::getScript(const char *path)
JS::PersistentRootedScript* ScriptingCore::getScript(const std::string& path)
{
// a) check jsc file first
std::string byteCodePath = RemoveFileExt(std::string(path)) + BYTE_CODE_FILE_EXT;
@ -672,9 +699,9 @@ JS::PersistentRootedScript* ScriptingCore::getScript(const char *path)
return nullptr;
}
JS::PersistentRootedScript* ScriptingCore::compileScript(const char *path, JS::HandleObject global, JSContext* cx)
JS::PersistentRootedScript* ScriptingCore::compileScript(const std::string& path, JS::HandleObject global, JSContext* cx)
{
if (!path) {
if (path.empty()) {
return nullptr;
}
@ -682,11 +709,11 @@ JS::PersistentRootedScript* ScriptingCore::compileScript(const char *path, JS::H
if (script != nullptr) {
return script;
}
if (cx == nullptr) {
cx = _cx;
}
cocos2d::FileUtils *futil = cocos2d::FileUtils::getInstance();
JSAutoCompartment ac(cx, global);
@ -750,7 +777,7 @@ JS::PersistentRootedScript* ScriptingCore::compileScript(const char *path, JS::H
if (compileSucceed) {
return script;
} else {
LOGD("ScriptingCore:: compileScript fail:%s", path);
LOGD("ScriptingCore:: compileScript fail:%s", path.c_str());
CC_SAFE_DELETE(script);
return nullptr;
}
@ -785,14 +812,15 @@ void ScriptingCore::cleanAllScript()
filename_script.clear();
}
bool ScriptingCore::runScript(const char *path)
bool ScriptingCore::runScript(const std::string& path)
{
return runScript(path, _global.ref(), _cx);
JS::RootedObject global(_cx, _global->get());
return runScript(path, global, _cx);
}
bool ScriptingCore::runScript(const char *path, JS::HandleObject global, JSContext* cx)
bool ScriptingCore::runScript(const std::string& path, JS::HandleObject global, JSContext* cx)
{
if (cx == NULL) {
if (cx == nullptr) {
cx = _cx;
}
@ -800,14 +828,14 @@ bool ScriptingCore::runScript(const char *path, JS::HandleObject global, JSConte
if (script == nullptr) {
return false;
}
bool evaluatedOK = false;
if (script) {
JS::RootedValue rval(cx);
JSAutoCompartment ac(cx, global);
evaluatedOK = JS_ExecuteScript(cx, global, *script, &rval);
if (false == evaluatedOK) {
cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", path);
cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", path.c_str());
JS_ReportPendingException(cx);
}
}
@ -817,12 +845,13 @@ bool ScriptingCore::runScript(const char *path, JS::HandleObject global, JSConte
bool ScriptingCore::requireScript(const char *path, JS::MutableHandleValue jsvalRet)
{
return requireScript(path, _global.ref(), _cx, jsvalRet);
JS::RootedObject global(_cx, _global->get());
return requireScript(path, global, _cx, jsvalRet);
}
bool ScriptingCore::requireScript(const char *path, JS::HandleObject global, JSContext* cx, JS::MutableHandleValue jsvalRet)
{
if (cx == NULL)
if (cx == nullptr)
{
cx = _cx;
}
@ -870,6 +899,28 @@ void ScriptingCore::cleanup()
localStorageFree();
removeAllRoots(_cx);
garbageCollect();
if (_js_log_buf) {
free(_js_log_buf);
_js_log_buf = NULL;
}
for (auto& s : filename_script)
{
CC_SAFE_DELETE(s.second);
}
filename_script.clear();
registrationList.clear();
for (auto iter = _js_global_type_map.begin(); iter != _js_global_type_map.end(); ++iter)
{
delete iter->second->parentProto.ptr();
delete iter->second->proto.ptr();
}
CC_SAFE_DELETE(_global);
CC_SAFE_DELETE(_debugGlobal);
if (_cx)
{
JS_DestroyContext(_cx);
@ -880,22 +931,13 @@ void ScriptingCore::cleanup()
JS_DestroyRuntime(_rt);
_rt = NULL;
}
_global.destroyIfConstructed();
_debugGlobal.destroyIfConstructed();
if (_js_log_buf) {
free(_js_log_buf);
_js_log_buf = NULL;
}
for (auto iter = _js_global_type_map.begin(); iter != _js_global_type_map.end(); ++iter)
{
free(iter->second->jsclass);
free(iter->second);
}
_js_global_type_map.clear();
filename_script.clear();
registrationList.clear();
_needCleanup = false;
}
@ -926,7 +968,7 @@ bool ScriptingCore::log(JSContext* cx, uint32_t argc, jsval *vp)
void ScriptingCore::retainScriptObject(cocos2d::Ref* owner, cocos2d::Ref* target)
{
JS::RootedObject global(_cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
JS::RootedObject jsbObj(_cx);
get_or_create_js_obj(_cx, global, "jsb", &jsbObj);
JS::RootedValue jsbVal(_cx, OBJECT_TO_JSVAL(jsbObj));
@ -959,7 +1001,7 @@ void ScriptingCore::retainScriptObject(cocos2d::Ref* owner, cocos2d::Ref* target
void ScriptingCore::rootScriptObject(cocos2d::Ref* target)
{
JS::RootedObject global(_cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
JS::RootedObject jsbObj(_cx);
get_or_create_js_obj(_cx, global, "jsb", &jsbObj);
JS::RootedValue jsbVal(_cx, OBJECT_TO_JSVAL(jsbObj));
@ -993,7 +1035,7 @@ void ScriptingCore::rootScriptObject(cocos2d::Ref* target)
void ScriptingCore::releaseScriptObject(cocos2d::Ref* owner, cocos2d::Ref* target)
{
JS::RootedObject global(_cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
JS::RootedObject jsbObj(_cx);
get_or_create_js_obj(_cx, global, "jsb", &jsbObj);
JS::RootedValue jsbVal(_cx, OBJECT_TO_JSVAL(jsbObj));
@ -1026,7 +1068,7 @@ void ScriptingCore::releaseScriptObject(cocos2d::Ref* owner, cocos2d::Ref* targe
void ScriptingCore::unrootScriptObject(cocos2d::Ref* target)
{
JS::RootedObject global(_cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
JS::RootedObject jsbObj(_cx);
get_or_create_js_obj(_cx, global, "jsb", &jsbObj);
JS::RootedValue jsbVal(_cx, OBJECT_TO_JSVAL(jsbObj));
@ -1070,7 +1112,7 @@ void ScriptingCore::releaseAllChildrenRecursive(cocos2d::Node *node)
void ScriptingCore::releaseAllNativeRefs(cocos2d::Ref* owner)
{
JS::RootedObject global(_cx, _global.ref());
JS::RootedObject global(_cx, _global->get());
JS::RootedObject jsbObj(_cx);
get_or_create_js_obj(_cx, global, "jsb", &jsbObj);
JS::RootedValue jsbVal(_cx, OBJECT_TO_JSVAL(jsbObj));
@ -1106,7 +1148,6 @@ void ScriptingCore::removeScriptObjectByObject(Ref* pObj)
// else CCLOG("removeScriptObjectByObject. BUG: nproxy not found = %p", nproxy);
}
bool ScriptingCore::setReservedSpot(uint32_t i, JSObject *obj, jsval value) {
JS_SetReservedSlot(obj, i, value);
return true;
@ -1173,13 +1214,13 @@ bool ScriptingCore::dumpRoot(JSContext *cx, uint32_t argc, jsval *vp)
void ScriptingCore::pauseSchedulesAndActions(js_proxy_t* p)
{
JS::RootedObject obj(_cx, p->obj.get());
__Array * arr = JSScheduleWrapper::getTargetForJSObject(obj);
auto arr = JSScheduleWrapper::getTargetForJSObject(obj);
if (! arr) return;
Node* node = (Node*)p->ptr;
for(ssize_t i = 0; i < arr->count(); ++i) {
if (arr->getObjectAtIndex(i)) {
node->getScheduler()->pauseTarget(arr->getObjectAtIndex(i));
for(ssize_t i = 0; i < arr->size(); ++i) {
if (arr->at(i)) {
node->getScheduler()->pauseTarget(arr->at(i));
}
}
}
@ -1188,27 +1229,27 @@ void ScriptingCore::pauseSchedulesAndActions(js_proxy_t* p)
void ScriptingCore::resumeSchedulesAndActions(js_proxy_t* p)
{
JS::RootedObject obj(_cx, p->obj.get());
__Array * arr = JSScheduleWrapper::getTargetForJSObject(obj);
auto arr = JSScheduleWrapper::getTargetForJSObject(obj);
if (!arr) return;
Node* node = (Node*)p->ptr;
for(ssize_t i = 0; i < arr->count(); ++i) {
if (!arr->getObjectAtIndex(i)) continue;
node->getScheduler()->resumeTarget(arr->getObjectAtIndex(i));
for(ssize_t i = 0; i < arr->size(); ++i) {
if (!arr->at(i)) continue;
node->getScheduler()->resumeTarget(arr->at(i));
}
}
void ScriptingCore::cleanupSchedulesAndActions(js_proxy_t* p)
{
JS::RootedObject obj(_cx, p->obj.get());
__Array* arr = JSScheduleWrapper::getTargetForJSObject(obj);
if (arr) {
auto targetArray = JSScheduleWrapper::getTargetForJSObject(obj);
if (targetArray)
{
Node* node = (Node*)p->ptr;
Scheduler* pScheduler = node->getScheduler();
Ref* pObj = nullptr;
CCARRAY_FOREACH(arr, pObj)
auto scheduler = node->getScheduler();
for (auto&& target : *targetArray)
{
pScheduler->unscheduleAllForTarget(pObj);
scheduler->unscheduleAllForTarget(target);
}
JSScheduleWrapper::removeAllTargetsForJSObject(obj);
@ -1244,7 +1285,7 @@ int ScriptingCore::handleActionEvent(void* data)
js_proxy_t * p = jsb_get_native_proxy(actionObject);
if (!p) return 0;
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
int ret = 0;
JS::RootedValue retval(_cx);
@ -1276,7 +1317,7 @@ int ScriptingCore::handleNodeEvent(void* data)
js_proxy_t * p = jsb_get_native_proxy(node);
if (!p) return 0;
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
int ret = 0;
JS::RootedValue retval(_cx);
@ -1341,7 +1382,7 @@ int ScriptingCore::handleComponentEvent(void* data)
js_proxy_t * p = jsb_get_native_proxy(node);
if (!p) return 0;
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
int ret = 0;
JS::RootedValue retval(_cx);
@ -1360,10 +1401,12 @@ int ScriptingCore::handleComponentEvent(void* data)
else if (action == kComponentOnEnter)
{
ret = executeFunctionWithOwner(nodeValue, "onEnter", 1, &dataVal, &retval);
resumeSchedulesAndActions(p);
}
else if (action == kComponentOnExit)
{
ret = executeFunctionWithOwner(nodeValue, "onExit", 1, &dataVal, &retval);
pauseSchedulesAndActions(p);
}
else if (action == kComponentOnUpdate)
{
@ -1381,7 +1424,7 @@ bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::Eve
bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event, JS::MutableHandleValue jsvalRet)
{
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
bool ret = false;
std::string funcName = getTouchesFuncName(eventCode);
@ -1432,7 +1475,7 @@ bool ScriptingCore::handleTouchEvent(void* nativeObj, cocos2d::EventTouch::Event
bool ScriptingCore::handleTouchEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, cocos2d::Touch* touch, cocos2d::Event* event, JS::MutableHandleValue jsvalRet)
{
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
std::string funcName = getTouchFuncName(eventCode);
bool ret = false;
@ -1464,7 +1507,7 @@ bool ScriptingCore::handleMouseEvent(void* nativeObj, cocos2d::EventMouse::Mouse
bool ScriptingCore::handleMouseEvent(void* nativeObj, cocos2d::EventMouse::MouseEventType eventType, cocos2d::Event* event, JS::MutableHandleValue jsvalRet)
{
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
std::string funcName = getMouseFuncName(eventType);
bool ret = false;
@ -1553,7 +1596,7 @@ bool ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, cons
bool ScriptingCore::handleKeyboardEvent(void* nativeObj, cocos2d::EventKeyboard::KeyCode keyCode, bool isPressed, cocos2d::Event* event)
{
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (nullptr == p)
@ -1583,7 +1626,7 @@ bool ScriptingCore::handleKeyboardEvent(void* nativeObj, cocos2d::EventKeyboard:
bool ScriptingCore::handleFocusEvent(void* nativeObj, cocos2d::ui::Widget* widgetLoseFocus, cocos2d::ui::Widget* widgetGetFocus)
{
JSAutoCompartment ac(_cx, _global.ref());
JSAutoCompartment ac(_cx, _global->get());
js_proxy_t * p = jsb_get_native_proxy(nativeObj);
if (nullptr == p)
@ -1605,6 +1648,8 @@ bool ScriptingCore::handleFocusEvent(void* nativeObj, cocos2d::ui::Widget* widge
int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
const std::vector<Touch*>& touches, JSObject *obj)
{
JSAutoCompartment ac(_cx, _global->get());
std::string funcName = getTouchesFuncName(eventType);
JS::RootedObject jsretArr(_cx, JS_NewArrayObject(this->_cx, 0));
@ -1635,6 +1680,8 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touch *touch, JSObject *obj)
{
JSAutoCompartment ac(_cx, _global->get());
JS::RootedValue retval(_cx);
std::string funcName = getTouchFuncName(eventType);
@ -1649,11 +1696,12 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType, Touc
}
int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
Touch *touch, JSObject *obj,
JS::MutableHandleValue retval)
{
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
std::string funcName = getTouchFuncName(eventType);
js_type_class_t *typeClass = js_get_type_from_native<cocos2d::Touch>(touch);
@ -1722,7 +1770,8 @@ bool ScriptingCore::parseConfig(ConfigType type, const std::string &str)
jsval args[2];
args[0] = int32_to_jsval(_cx, static_cast<int>(type));
args[1] = std_string_to_jsval(_cx, str);
return (true == executeFunctionWithOwner(OBJECT_TO_JSVAL(_global.ref().get()), "__onParseConfig", 2, args));
JS::RootedValue globalVal(_cx, OBJECT_TO_JSVAL(_global->get()));
return (true == executeFunctionWithOwner(globalVal, "__onParseConfig", 2, args));
}
bool ScriptingCore::isObjectValid(JSContext *cx, uint32_t argc, jsval *vp)
@ -1808,13 +1857,13 @@ void SimpleRunLoop::update(float dt)
void ScriptingCore::debugProcessInput(const std::string& str)
{
JSAutoCompartment ac(_cx, _debugGlobal.ref());
JSAutoCompartment ac(_cx, _debugGlobal->get());
JSString* jsstr = JS_NewStringCopyZ(_cx, str.c_str());
jsval argv = STRING_TO_JSVAL(jsstr);
JS::RootedValue outval(_cx);
JS::RootedObject debugGlobal(_cx, _debugGlobal.ref());
JS::RootedObject debugGlobal(_cx, _debugGlobal->get());
JS_CallFunctionName(_cx, debugGlobal, "processInput", JS::HandleValueArray::fromMarkedLocation(1, &argv), &outval);
}
@ -1909,11 +1958,11 @@ static void processInput(const std::string& data) {
static void clearBuffers() {
std::lock_guard<std::mutex> lk(g_rwMutex);
// only process input if there's something and we're not locked
if (inData.length() > 0) {
if (!inData.empty()) {
processInput(inData);
inData.clear();
}
if (outData.length() > 0) {
if (!outData.empty()) {
_clientSocketWriteAndClearString(outData);
}
}
@ -1976,7 +2025,6 @@ static void serverEntryPoint(unsigned int port)
listen(s, 1);
#define MAX_RECEIVED_SIZE 1024
#define BUF_SIZE MAX_RECEIVED_SIZE + 1
@ -2032,18 +2080,17 @@ bool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp)
void ScriptingCore::enableDebugger(unsigned int port)
{
if (_debugGlobal.empty())
if (!_debugGlobal)
{
JSAutoCompartment ac0(_cx, _global.ref().get());
JSAutoCompartment ac0(_cx, _global->get());
JS_SetDebugMode(_cx, true);
_debugGlobal.construct(_cx);
_debugGlobal.ref() = NewGlobalObject(_cx, true);
_debugGlobal = new (std::nothrow) JS::PersistentRootedObject(_cx, NewGlobalObject(_cx, true));
// Adds the debugger object to root, otherwise it may be collected by GC.
//AddObjectRoot(_cx, &_debugGlobal.ref()); no need, it's persistent rooted now
//JS_WrapObject(_cx, &_debugGlobal.ref()); Not really needed, JS_WrapObject makes a cross-compartment wrapper for the given JS object
JS::RootedObject rootedDebugObj(_cx, _debugGlobal.ref());
JS::RootedObject rootedDebugObj(_cx, _debugGlobal->get());
JSAutoCompartment acDebug(_cx, rootedDebugObj);
// these are used in the debug program
JS_DefineFunction(_cx, rootedDebugObj, "log", ScriptingCore::log, 0, JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT);
@ -2053,7 +2100,7 @@ void ScriptingCore::enableDebugger(unsigned int port)
JS_DefineFunction(_cx, rootedDebugObj, "_exitNestedEventLoop", JSBDebug_exitNestedEventLoop, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(_cx, rootedDebugObj, "_getEventLoopNestLevel", JSBDebug_getEventLoopNestLevel, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS::RootedObject globalObj(_cx, _global.ref());
JS::RootedObject globalObj(_cx, _global->get());
JS_WrapObject(_cx, &globalObj);
runScript("script/jsb_debugger.js", rootedDebugObj);
@ -2178,7 +2225,7 @@ js_proxy_t* jsb_get_native_proxy(void* nativeObj)
return nullptr;
}
js_proxy_t* jsb_get_js_proxy(JSObject* jsObj)
js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj)
{
auto search = _js_native_global_map.find(jsObj);
if(search != _js_native_global_map.end())

View File

@ -40,7 +40,7 @@
#include <assert.h>
#include <memory>
#define ENGINE_VERSION "Cocos2d-JS v3.12"
#define ENGINE_VERSION "Cocos2d-JS v3.13"
void js_log(const char *format, ...);
@ -81,8 +81,8 @@ class CC_JS_DLL ScriptingCore : public cocos2d::ScriptEngineProtocol
private:
JSRuntime *_rt;
JSContext *_cx;
mozilla::Maybe<JS::PersistentRootedObject> _global;
mozilla::Maybe<JS::PersistentRootedObject> _debugGlobal;
JS::PersistentRootedObject *_global;
JS::PersistentRootedObject *_debugGlobal;
SimpleRunLoop* _runLoop;
bool _jsInited;
bool _needCleanup;
@ -90,7 +90,6 @@ private:
bool _callFromScript;
ScriptingCore();
public:
~ScriptingCore();
/**@~english
@ -289,22 +288,22 @@ public:
@param path @~english The script file path
@return @~english Script object
*/
JS::PersistentRootedScript* getScript(const char *path);
JS::PersistentRootedScript* getScript(const std::string& path);
/**@~english
* Compile the specified js file
* @param path @~english The path of the script to be compiled
* @param global @~english The js global object
* @param cx @~english The js context
*/
JS::PersistentRootedScript* compileScript(const char *path, JS::HandleObject global, JSContext* cx = NULL);
JS::PersistentRootedScript* compileScript(const std::string& path, JS::HandleObject global, JSContext* cx = nullptr);
/**@~english
* Run the specified js file
* @param path @~english The path of the script to be executed
* @return @~english Return true if succeed, otherwise return false.
*/
bool runScript(const char *path);
bool runScript(const std::string& path);
/**@~english
* Run the specified js file
* @param path @~english The path of the script to be executed
@ -312,8 +311,8 @@ public:
* @param global @~english The context to execute the script
* @return @~english Return true if succeed, otherwise return false.
*/
bool runScript(const char *path, JS::HandleObject global, JSContext* cx = NULL);
bool runScript(const std::string& path, JS::HandleObject global, JSContext* cx = NULL);
/**@~english
* Require the specified js file
* The difference between run and require is that require returns the export object of the script
@ -495,12 +494,12 @@ public:
* Gets the debug environment's global object
* @return @~english The debug environment's global object
*/
JSObject* getDebugGlobal() { return _debugGlobal.ref().get(); }
JSObject* getDebugGlobal() { return _debugGlobal->get(); }
/**@~english
* Gets the global object
* @return @~english The global object
*/
JSObject* getGlobalObject() { return _global.ref().get(); }
JSObject* getGlobalObject() { return _global->get(); }
/**@~english
* Checks whether a C++ function is overrided in js prototype chain
@ -567,18 +566,16 @@ js_type_class_t *jsb_register_class(JSContext *cx, JSClass *jsClass, JS::HandleO
std::string typeName = t.s_name();
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
JS::RootedObject protoRoot(cx, proto);
JS::RootedObject protoParentRoot(cx, parentProto);
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
memset(p, 0, sizeof(js_type_class_t));
p->jsclass = jsClass;
if (p->proto.empty())
{
p->proto.construct(cx);
}
p->proto.ref() = proto;
if (p->parentProto.empty())
{
p->parentProto.construct(cx);
}
p->parentProto.ref() = parentProto ;
auto persistentProtoRoot = new (std::nothrow) JS::PersistentRootedObject(cx, protoRoot);
p->proto.set(persistentProtoRoot);
auto persistentProtoParentRoot = new (std::nothrow) JS::PersistentRootedObject(cx, protoParentRoot);
p->parentProto.set(persistentProtoParentRoot);
_js_global_type_map.insert(std::make_pair(typeName, p));
}
return p;
@ -590,7 +587,7 @@ js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsObj);
/** returns the proxy associated with the Native* */
js_proxy_t* jsb_get_native_proxy(void* nativeObj);
/** returns the proxy associated with the JSObject* */
js_proxy_t* jsb_get_js_proxy(JSObject* jsObj);
js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj);
/** deprecated: use jsb_remove_proxy(js_proxy_t* proxy) instead */
void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy);
/** removes both the native and js proxies */

View File

@ -520,7 +520,10 @@ bool jsval_to_array_of_cpvect( JSContext *cx, jsval vp, cpVect**verts, int *numV
double value = 0;
ok = JS::ToNumber(cx, valarg, &value);
JSB_PRECONDITION( ok, "Error converting value to nsobject");
if (!ok) {
free(array);
}
JSB_PRECONDITION(ok, "Error converting value to nsobject");
if(i%2==0)
array[i/2].x = value;
@ -1013,6 +1016,8 @@ void JSB_cpSpace_finalize(JSFreeOp *fop, JSObject *jsthis)
{
struct jsb_c_proxy_s *proxy = jsb_get_c_proxy_for_jsobject(jsthis);
if ( proxy ) {
CCLOGINFO("jsbindings: finalizing JS object %p (cpSpace), handle: %p", jsthis, proxy->handle);
// space
cpSpace *space = (cpSpace*) proxy->handle;

File diff suppressed because it is too large Load Diff

View File

@ -35,25 +35,43 @@
class JSScheduleWrapper;
namespace JSBinding
{
typedef cocos2d::Vector<cocos2d::Ref*> Array;
typedef cocos2d::Map<std::string, cocos2d::Ref*> Dictionary;
class DictionaryRef : public cocos2d::Ref
{
public:
Dictionary data;
};
class ArrayRef : public cocos2d::Ref
{
public:
Array data;
};
}
// JSScheduleWrapper* --> Array* since one js function may correspond to many targets.
// To debug this, you could refer to JSScheduleWrapper::dump function.
// It will prove that i'm right. :)
typedef struct jsScheduleFunc_proxy {
JSObject* jsfuncObj;
cocos2d::__Array* targets;
JSBinding::Array* targets;
UT_hash_handle hh;
} schedFunc_proxy_t;
typedef struct jsScheduleTarget_proxy {
JSObject* jsTargetObj;
cocos2d::__Array* targets;
JSBinding::Array* targets;
UT_hash_handle hh;
} schedTarget_proxy_t;
typedef struct jsCallFuncTarget_proxy {
void * ptr;
cocos2d::__Array *obj;
JSBinding::Array* obj;
UT_hash_handle hh;
} callfuncTarget_proxy_t;
@ -131,7 +149,6 @@ void js_remove_object_reference(JS::HandleValue owner, JS::HandleValue target);
void js_add_object_root(JS::HandleValue target);
void js_remove_object_root(JS::HandleValue target);
JS::Value anonEvaluate(JSContext *cx, JS::HandleObject thisObj, const char* string);
void register_cocos2dx_js_core(JSContext* cx, JS::HandleObject obj);
@ -163,9 +180,9 @@ public:
JSScheduleWrapper(JS::HandleValue owner);
static void setTargetForSchedule(JS::HandleValue sched, JSScheduleWrapper *target);
static cocos2d::__Array * getTargetForSchedule(JS::HandleValue sched);
static JSBinding::Array* getTargetForSchedule(JS::HandleValue sched);
static void setTargetForJSObject(JS::HandleObject jsTargetObj, JSScheduleWrapper *target);
static cocos2d::__Array * getTargetForJSObject(JS::HandleObject jsTargetObj);
static JSBinding::Array* getTargetForJSObject(JS::HandleObject jsTargetObj);
// Remove all targets.
static void removeAllTargets();

View File

@ -25,7 +25,6 @@
#include "scripting/js-bindings/manual/ScriptingCore.h"
#include "scripting/js-bindings/manual/cocos2d_specifics.hpp"
#include "editor-support/cocostudio/CocoStudio.h"
#include "deprecated/CCDictionary.h"
class JSArmatureWrapper: public JSCallbackWrapper {
public:
@ -121,13 +120,14 @@ static bool js_cocos2dx_ArmatureAnimation_setMovementEventCallFunc(JSContext *cx
JSArmatureWrapper *tmpObj = new (std::nothrow) JSArmatureWrapper(args.thisv());
tmpObj->autorelease();
cocos2d::__Dictionary* dict = static_cast<cocos2d::__Dictionary*>(cobj->getUserObject());
if (nullptr == dict)
auto userDict = static_cast<JSBinding::DictionaryRef*>(cobj->getUserObject());
if (nullptr == userDict)
{
dict = cocos2d::__Dictionary::create();
cobj->setUserObject(dict);
userDict = new (std::nothrow) JSBinding::DictionaryRef();
cobj->setUserObject(userDict);
userDict->release();
}
dict->setObject(tmpObj, "moveEvent");
userDict->data.insert("moveEvent", tmpObj);
tmpObj->setJSCallbackFunc(args.get(0));
if (argc == 1)
@ -167,13 +167,14 @@ static bool js_cocos2dx_ArmatureAnimation_setFrameEventCallFunc(JSContext *cx, u
JSArmatureWrapper *tmpObj = new (std::nothrow) JSArmatureWrapper(args.thisv());
tmpObj->autorelease();
cocos2d::__Dictionary* dict = static_cast<cocos2d::__Dictionary*>(cobj->getUserObject());
auto dict = static_cast<JSBinding::DictionaryRef*>(cobj->getUserObject());
if (nullptr == dict)
{
dict = cocos2d::__Dictionary::create();
dict = new (std::nothrow) JSBinding::DictionaryRef();
cobj->setUserObject(dict);
dict->release();
}
dict->setObject(tmpObj, "frameEvent");
dict->data.insert("frameEvent", tmpObj);
tmpObj->setJSCallbackFunc(args.get(0));
if (argc == 1)
@ -1465,5 +1466,4 @@ void register_all_cocos2dx_studio_manual(JSContext* cx, JS::HandleObject global)
JS_DefineProperty(cx, textureData, "height", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, js_get_TextureData_height, js_set_TextureData_height);
JS_DefineProperty(cx, textureData, "pivotX", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, js_get_TextureData_pivotX, js_set_TextureData_pivotX);
JS_DefineProperty(cx, textureData, "pivotY", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED, js_get_TextureData_pivotY, js_set_TextureData_pivotY);
}

View File

@ -82,7 +82,8 @@ ComponentJS::ComponentJS(const std::string& scriptFileName)
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
JS::RemoveObjectRoot(cx, &nproxy->obj);
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
jsb_remove_proxy(nproxy, jsb_get_js_proxy(nproxy->obj));
JS::RootedObject nobj(cx, nproxy->obj);
jsb_remove_proxy(nproxy, jsb_get_js_proxy(nobj));
}
// link the native object with the javascript object
jsb_new_proxy(this, jsObj->ref());

View File

@ -30,7 +30,6 @@
#include "base/CCDirector.h"
#include "base/CCScheduler.h"
#include "deprecated/CCDictionary.h"
#include "renderer/CCTextureCache.h"
#include "renderer/CCTextureCube.h"
@ -197,15 +196,15 @@ static bool js_cocos2dx_CCTableView_setDelegate(JSContext *cx, uint32_t argc, js
JS_SetProperty(cx, obj, "_delegate", args.get(0));
__Dictionary* userDict = static_cast<__Dictionary*>(cobj->getUserObject());
auto userDict = static_cast<JSBinding::DictionaryRef*>(cobj->getUserObject());
if (NULL == userDict)
{
userDict = new (std::nothrow) __Dictionary();
userDict = new (std::nothrow) JSBinding::DictionaryRef();
cobj->setUserObject(userDict);
userDict->release();
}
userDict->setObject(nativeDelegate, KEY_TABLEVIEW_DELEGATE);
userDict->data.insert(KEY_TABLEVIEW_DELEGATE, nativeDelegate);
cobj->setDelegate(nativeDelegate);
@ -374,15 +373,15 @@ static bool js_cocos2dx_CCTableView_setDataSource(JSContext *cx, uint32_t argc,
JS_SetProperty(cx, obj, "_dataSource", args.get(0));
__Dictionary* userDict = static_cast<__Dictionary*>(cobj->getUserObject());
auto userDict = static_cast<JSBinding::DictionaryRef*>(cobj->getUserObject());
if (NULL == userDict)
{
userDict = new (std::nothrow) __Dictionary();
userDict = new (std::nothrow) JSBinding::DictionaryRef();
cobj->setUserObject(userDict);
userDict->release();
}
userDict->setObject(pNativeSource, KEY_TABLEVIEW_DATA_SOURCE);
userDict->data.insert(KEY_TABLEVIEW_DATA_SOURCE, pNativeSource);
cobj->setDataSource(pNativeSource);
@ -450,8 +449,8 @@ static bool js_cocos2dx_CCTableView_create(JSContext *cx, uint32_t argc, jsval *
}
ret->reloadData();
__Dictionary* userDict = new (std::nothrow) __Dictionary();
userDict->setObject(pNativeSource, KEY_TABLEVIEW_DATA_SOURCE);
JSBinding::DictionaryRef* userDict = new (std::nothrow) JSBinding::DictionaryRef();
userDict->data.insert(KEY_TABLEVIEW_DATA_SOURCE, pNativeSource);
ret->setUserObject(userDict);
userDict->release();
@ -505,8 +504,8 @@ static bool js_cocos2dx_CCTableView_init(JSContext *cx, uint32_t argc, jsval *vp
}
cobj->reloadData();
__Dictionary* userDict = new (std::nothrow) __Dictionary();
userDict->setObject(pNativeSource, KEY_TABLEVIEW_DATA_SOURCE);
JSBinding::DictionaryRef* userDict = new (std::nothrow) JSBinding::DictionaryRef();
userDict->data.insert(KEY_TABLEVIEW_DATA_SOURCE, pNativeSource);
cobj->setUserObject(userDict);
userDict->release();
@ -632,16 +631,15 @@ static bool js_cocos2dx_CCControl_addTargetWithActionForControlEvents(JSContext
nativeDelegate->setJSCallback(args.get(1), jscb);
nativeDelegate->setEventType(arg2);
__Array* nativeDelegateArray = static_cast<__Array*>(cobj->getUserObject());
auto nativeDelegateArray = static_cast<JSBinding::ArrayRef*>(cobj->getUserObject());
if (nullptr == nativeDelegateArray)
{
nativeDelegateArray = new (std::nothrow) __Array();
nativeDelegateArray->init();
nativeDelegateArray = new (std::nothrow) JSBinding::ArrayRef();
cobj->setUserObject(nativeDelegateArray); // The reference of nativeDelegateArray is added to 2
nativeDelegateArray->release(); // Release nativeDelegateArray to make the reference to 1
}
nativeDelegateArray->addObject(nativeDelegate); // The reference of nativeDelegate is added to 2
nativeDelegateArray->data.pushBack(nativeDelegate); // The reference of nativeDelegate is added to 2
nativeDelegate->release(); // Release nativeDelegate to make the reference to 1
js_add_object_reference(args.thisv(), args.get(1));

View File

@ -37,9 +37,21 @@
#include "scripting/js-bindings/manual/cocos2d_specifics.hpp"
#include "scripting/js-bindings/manual/js_bindings_config.h"
USING_NS_CC;
namespace
{
class StringRef : public cocos2d::Ref
{
public:
CREATE_FUNC(StringRef);
virtual bool init() { return true; }
std::string data;
};
};
// JSStringWrapper
JSStringWrapper::JSStringWrapper()
: _buffer(nullptr)
@ -364,18 +376,12 @@ bool jsval_to_charptr( JSContext *cx, JS::HandleValue vp, const char **ret )
JSString *jsstr = JS::ToString( cx, vp );
JSB_PRECONDITION2( jsstr, cx, false, "invalid string" );
//XXX: what's this?
// root it
// vp = STRING_TO_JSVAL(jsstr);
JSStringWrapper strWrapper(jsstr);
// XXX: It is converted to String and then back to char* to autorelease the created object.
__String *tmp = __String::create(strWrapper.get());
auto tmp = StringRef::create();
tmp->data = strWrapper.get();
JSB_PRECONDITION2( tmp, cx, false, "Error creating string from UTF8");
*ret = tmp->getCString();
*ret = tmp->data.c_str();
return true;
}
@ -596,7 +602,7 @@ bool jsval_to_long_long(JSContext *cx, JS::HandleValue vp, long long* r)
}
bool jsval_to_std_string(JSContext *cx, JS::HandleValue v, std::string* ret) {
if(v.isString() || v.isNumber())
if(v.isString() || v.isBoolean())
{
JSString *tmp = JS::ToString(cx, v);
JSB_PRECONDITION3(tmp, cx, false, "Error processing arguments");
@ -605,6 +611,10 @@ bool jsval_to_std_string(JSContext *cx, JS::HandleValue v, std::string* ret) {
*ret = str.get();
return true;
}
if (v.isNullOrUndefined()) {
*ret = "";
return true;
}
return false;
}
@ -1007,6 +1017,8 @@ bool jsval_to_ccarray_of_CCPoint(JSContext* cx, JS::HandleValue v, Point **point
JS_GetElement(cx, jsobj, i, &valarg);
ok = jsval_to_ccpoint(cx, valarg, &array[i]);
if(!ok)
delete [] array;
JSB_PRECONDITION3(ok, cx, false, "Error processing arguments");
}
@ -2891,7 +2903,7 @@ jsval vector_vec2_to_jsval(JSContext *cx, const std::vector<cocos2d::Vec2>& v)
JS::RootedObject jsretArr(cx, JS_NewArrayObject(cx, v.size()));
int i = 0;
for (const cocos2d::Vec2 obj : v)
for (const cocos2d::Vec2& obj : v)
{
JS::RootedValue arrElement(cx);
arrElement = vector2_to_jsval(cx, obj);

View File

@ -132,14 +132,14 @@ bool jsval_to_ray(JSContext *cx, JS::HandleValue vp, cocos2d::Ray* ret);
bool jsval_to_resourcedata(JSContext *cx, JS::HandleValue v, cocos2d::ResourceData* ret);
// forward declaration
CC_JS_DLL js_proxy_t* jsb_get_js_proxy(JSObject* jsObj);
CC_JS_DLL js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj);
template <class T>
bool jsvals_variadic_to_ccvector( JSContext *cx, /*jsval *vp, int argc,*/const JS::CallArgs& args, cocos2d::Vector<T>* ret)
{
bool ok = true;
for (int i = 0; i < args.length(); i++)
for (unsigned i = 0; i < args.length(); i++)
{
js_proxy_t* p;
JS::RootedObject obj(cx, args.get(i).toObjectOrNull());

View File

@ -44,8 +44,11 @@ bool js_EventListenerTouchOneByOne_create(JSContext *cx, uint32_t argc, jsval *v
if (!ok)
return false;
CCASSERT(jsret.isBoolean(), "the return value of onTouchBegan isn't boolean");
return jsret.toBoolean();
if (jsret.isBoolean()) {
return jsret.toBoolean();
} else {
return false;
}
};
ret->onTouchMoved = [ret](Touch* touch, Event* event) {

View File

@ -62,9 +62,13 @@ bool JSB_localStorageSetItem(JSContext *cx, uint32_t argc, jsval *vp) {
ok &= jsval_to_std_string( cx, args.get(0), &arg0 );
ok &= jsval_to_std_string( cx, args.get(1), &arg1 );
JSB_PRECONDITION2(ok, cx, false, "Error processing arguments");
if( ok ) {
localStorageSetItem(arg0 , arg1);
}
else {
log("JSB_localStorageSetItem:Error processing arguments");
}
localStorageSetItem(arg0 , arg1);
args.rval().setUndefined();
return true;
}

View File

@ -42,7 +42,7 @@ using namespace std;
* @brief Implementation for header retrieving.
* @param header
*/
void MinXmlHttpRequest::_gotHeader(string header)
void MinXmlHttpRequest::_gotHeader(string& header)
{
// Get Header and Set StatusText
// Split String into Tokens
@ -524,6 +524,20 @@ JS_BINDED_PROP_SET_IMPL(MinXmlHttpRequest, timeout)
JS_BINDED_PROP_GET_IMPL(MinXmlHttpRequest, responseType)
{
JSString* str = JS_NewStringCopyN(cx, "", 0);
switch(_responseType)
{
case ResponseType::STRING:
str = JS_NewStringCopyN(cx, "text", 4);
break;
case ResponseType::ARRAY_BUFFER:
str = JS_NewStringCopyN(cx, "arraybuffer", 11);
break;
case ResponseType::JSON:
str = JS_NewStringCopyN(cx, "json", 4);
break;
default:
break;
}
args.rval().set(STRING_TO_JSVAL(str));
return true;
}
@ -700,7 +714,6 @@ JS_BINDED_PROP_GET_IMPL(MinXmlHttpRequest, response)
//bool ok = JS_ParseJSON(cx, utf16Buf, static_cast<uint32_t>(utf16Count), &outVal);
JS::RootedString jsstr(cx, strVal.toString());
bool ok = JS_ParseJSON(cx, jsstr, &outVal);
if (ok)
{
args.rval().set(outVal);
@ -796,7 +809,6 @@ JS_BINDED_FUNC_IMPL(MinXmlHttpRequest, send)
// Clean up header map. New request, new headers!
_httpHeader.clear();
_errorFlag = false;
if (argc == 1)

View File

@ -90,7 +90,7 @@ public:
void update(float dt);
private:
void _gotHeader(std::string header);
void _gotHeader(std::string& header);
void _setRequestHeader(const char* field, const char* value);
void _setHttpRequestHeader();
void _setHttpRequestData(const char *data, size_t len);

View File

@ -24,6 +24,7 @@
#include "scripting/js-bindings/manual/network/jsb_websocket.h"
#include "base/ccUTF8.h"
#include "base/CCDirector.h"
#include "network/WebSocket.h"
#include "platform/CCPlatformMacros.h"
#include "scripting/js-bindings/manual/ScriptingCore.h"
@ -78,6 +79,9 @@ public:
js_proxy_t * p = jsb_get_native_proxy(ws);
if (!p) return;
if (cocos2d::Director::getInstance() == nullptr || cocos2d::ScriptEngineManager::getInstance() == nullptr)
return;
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
@ -94,7 +98,10 @@ public:
virtual void onMessage(WebSocket* ws, const WebSocket::Data& data)
{
js_proxy_t * p = jsb_get_native_proxy(ws);
if (!p) return;
if (p == nullptr) return;
if (cocos2d::Director::getInstance() == nullptr || cocos2d::ScriptEngineManager::getInstance() == nullptr)
return;
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
@ -104,11 +111,10 @@ public:
vp = c_string_to_jsval(cx, "message");
JS_SetProperty(cx, jsobj, "type", vp);
jsval args = OBJECT_TO_JSVAL(jsobj);
JS::RootedValue args(cx, OBJECT_TO_JSVAL(jsobj));
if (data.isBinary)
{// data is binary
JSObject* buffer = JS_NewArrayBuffer(cx, static_cast<uint32_t>(data.len));
JS::RootedObject buffer(cx, JS_NewArrayBuffer(cx, static_cast<uint32_t>(data.len)));
if (data.len > 0)
{
uint8_t* bufdata = JS_GetArrayBufferData(buffer);
@ -129,7 +135,6 @@ public:
{// Normal string
dataVal = c_string_to_jsval(cx, data.bytes);
}
if (dataVal.isNullOrUndefined())
{
ws->closeAsync();
@ -138,7 +143,7 @@ public:
JS_SetProperty(cx, jsobj, "data", dataVal);
}
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onmessage", 1, &args);
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onmessage", 1, args.address());
}
virtual void onClose(WebSocket* ws)
@ -146,20 +151,24 @@ public:
js_proxy_t * p = jsb_get_native_proxy(ws);
if (!p) return;
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
JS::RootedObject jsobj(cx, JS_NewObject(cx, NULL, JS::NullPtr(), JS::NullPtr()));
JS::RootedValue vp(cx);
vp = c_string_to_jsval(cx, "close");
JS_SetProperty(cx, jsobj, "type", vp);
jsval args = OBJECT_TO_JSVAL(jsobj);
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onclose", 1, &args);
auto copy = &p->obj;
JS::RemoveObjectRoot(cx, copy);
jsb_remove_proxy(p);
if (cocos2d::Director::getInstance() != nullptr && cocos2d::Director::getInstance()->getRunningScene() && cocos2d::ScriptEngineManager::getInstance() != nullptr)
{
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
JS::RootedObject jsobj(cx, JS_NewObject(cx, NULL, JS::NullPtr(), JS::NullPtr()));
JS::RootedValue vp(cx);
vp = c_string_to_jsval(cx, "close");
JS_SetProperty(cx, jsobj, "type", vp);
JS::RootedValue args(cx, OBJECT_TO_JSVAL(jsobj));
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onclose", 1, args.address());
auto copy = &p->obj;
JS::RemoveObjectRoot(cx, copy);
jsb_remove_proxy(p);
}
// Delete WebSocket instance
CC_SAFE_DELETE(ws);
// Delete self at last while websocket was closed.
@ -171,6 +180,9 @@ public:
js_proxy_t * p = jsb_get_native_proxy(ws);
if (!p) return;
if (cocos2d::Director::getInstance() == nullptr || cocos2d::ScriptEngineManager::getInstance() == nullptr)
return;
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
JSContext* cx = ScriptingCore::getInstance()->getGlobalContext();
@ -179,9 +191,9 @@ public:
vp = c_string_to_jsval(cx, "error");
JS_SetProperty(cx, jsobj, "type", vp);
jsval args = OBJECT_TO_JSVAL(jsobj);
JS::RootedValue args(cx, OBJECT_TO_JSVAL(jsobj));
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onerror", 1, &args);
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(_JSDelegate.ref()), "onerror", 1, args.address());
}
void setJSDelegate(JS::HandleObject pJSDelegate)
@ -255,7 +267,7 @@ bool js_cocos2dx_extension_WebSocket_send(JSContext *cx, uint32_t argc, jsval *v
return true;
}
JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0);
return false;
return true;
}
bool js_cocos2dx_extension_WebSocket_close(JSContext *cx, uint32_t argc, jsval *vp){
@ -280,7 +292,6 @@ bool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, j
if (argc == 1 || argc == 2)
{
std::string url;
do {
@ -292,10 +303,7 @@ bool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, j
JS::RootedObject obj(cx, JS_NewObject(cx, js_cocos2dx_websocket_class, proto, JS::NullPtr()));
//JS::RootedObject obj(cx, JS_NewObjectForConstructor(cx, js_cocos2dx_websocket_class, args));
WebSocket* cobj = new (std::nothrow) WebSocket();
JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate();
delegate->setJSDelegate(obj);
WebSocket* cobj = nullptr;
if (argc == 2)
{
std::vector<std::string> protocols;
@ -331,14 +339,20 @@ bool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, j
protocols.push_back(protocol);
}
}
cobj = new (std::nothrow) WebSocket();
JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate();
delegate->setJSDelegate(obj);
cobj->init(*delegate, url, &protocols);
}
else
{
cobj = new (std::nothrow) WebSocket();
JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate();
delegate->setJSDelegate(obj);
cobj->init(*delegate, url);
}
JS_DefineProperty(cx, obj, "URL", args.get(0), JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
//protocol not support yet (always return "")
@ -374,8 +388,8 @@ static bool js_cocos2dx_extension_WebSocket_get_readyState(JSContext *cx, uint32
}
}
void register_jsb_websocket(JSContext *cx, JS::HandleObject global) {
void register_jsb_websocket(JSContext *cx, JS::HandleObject global)
{
js_cocos2dx_websocket_class = (JSClass *)calloc(1, sizeof(JSClass));
js_cocos2dx_websocket_class->name = "WebSocket";
js_cocos2dx_websocket_class->addProperty = JS_PropertyStub;

View File

@ -42,10 +42,38 @@ typedef struct js_proxy {
JSObject* _jsobj;
} js_proxy_t;
class ScriptingRootHolder
{
public:
ScriptingRootHolder(JS::PersistentRootedObject* ptr)
{
set(ptr);
}
void set(JS::PersistentRootedObject* k)
{
p = k;
}
JSObject* ref()
{
return *p;
}
JS::PersistentRootedObject* ptr()
{
return p;
}
private:
JS::PersistentRootedObject* p;
};
typedef struct js_type_class {
JSClass *jsclass;
mozilla::Maybe<JS::PersistentRootedObject> proto;
mozilla::Maybe<JS::PersistentRootedObject> parentProto;
ScriptingRootHolder proto;
ScriptingRootHolder parentProto;
} js_type_class_t;
extern std::unordered_map<std::string, js_type_class_t*> _js_global_type_map;

View File

@ -28,6 +28,8 @@
using namespace spine;
std::unordered_map<spTrackEntry*, jsval> _spTrackEntryMap;
jsval speventdata_to_jsval(JSContext* cx, spEventData& v)
{
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
@ -284,12 +286,36 @@ jsval sptrackentry_to_jsval(JSContext* cx, spTrackEntry& v)
JS::RootedValue nextVal(cx);
if (v.next)
nextVal = sptrackentry_to_jsval(cx, *v.next);
{
auto nextPtr = v.next;
auto entry = _spTrackEntryMap.find(nextPtr);
if (entry == _spTrackEntryMap.end())
{
_spTrackEntryMap.emplace(nextPtr, nextVal.get());
nextVal = sptrackentry_to_jsval(cx, *v.next);
}
else
{
nextVal.set(entry->second);
}
}
JS::RootedValue previousVal(cx);
if (v.previous)
previousVal = sptrackentry_to_jsval(cx, *v.previous);
{
auto previousPtr = v.previous;
auto entry = _spTrackEntryMap.find(previousPtr);
if (entry == _spTrackEntryMap.end())
{
_spTrackEntryMap.emplace(previousPtr, previousVal.get());
previousVal = sptrackentry_to_jsval(cx, *previousPtr);
}
else
{
previousVal.set(entry->second);
}
}
JS::RootedValue jsanimation(cx, spanimation_to_jsval(cx, *v.animation));
bool ok = JS_DefineProperty(cx, tmp, "delay", v.delay, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
JS_DefineProperty(cx, tmp, "time", v.time, JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
@ -455,6 +481,7 @@ bool jsb_cocos2dx_spine_getCurrent(JSContext *cx, uint32_t argc, jsval *vp)
if (ret)
{
jsret = sptrackentry_to_jsval(cx, *ret);
_spTrackEntryMap.clear();
}
} while (0);
@ -468,6 +495,7 @@ bool jsb_cocos2dx_spine_getCurrent(JSContext *cx, uint32_t argc, jsval *vp)
if (ret)
{
jsret = sptrackentry_to_jsval(cx, *ret);
_spTrackEntryMap.clear();
}
} while (0);
@ -504,6 +532,7 @@ bool jsb_cocos2dx_spine_setAnimation(JSContext *cx, uint32_t argc, jsval *vp)
if (ret)
{
jsret = sptrackentry_to_jsval(cx, *ret);
_spTrackEntryMap.clear();
}
} while(0);
@ -541,6 +570,7 @@ bool jsb_cocos2dx_spine_addAnimation(JSContext *cx, uint32_t argc, jsval *vp)
if (ret)
{
jsret = sptrackentry_to_jsval(cx, *ret);
_spTrackEntryMap.clear();
}
} while(0);
@ -566,6 +596,7 @@ bool jsb_cocos2dx_spine_addAnimation(JSContext *cx, uint32_t argc, jsval *vp)
if (ret)
{
jsret = sptrackentry_to_jsval(cx, *ret);
_spTrackEntryMap.clear();
}
} while(0);

View File

@ -26,7 +26,7 @@
// CCConfig.js
//
cc.ENGINE_VERSION = "Cocos2d-JS v3.12";
cc.ENGINE_VERSION = "Cocos2d-JS v3.13";
cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 0;
cc.DIRECTOR_STATS_POSITION = {x: 0, y: 0};

View File

@ -193,13 +193,6 @@ cc.defineGetterSetter(_proto, "cascadeOpacity", _proto.isCascadeOpacityEnabled,
cc.defineGetterSetter(_proto, "color", _proto.getColor, _proto.setColor);
cc.defineGetterSetter(_proto, "cascadeColor", _proto.isCascadeColorEnabled, _proto.setCascadeColorEnabled);
_proto = cc.LayerRGBA.prototype;
cc.defineGetterSetter(_proto, "opacityModifyRGB", _proto.isOpacityModifyRGB, _proto.setOpacityModifyRGB);
cc.defineGetterSetter(_proto, "opacity", _proto.getOpacity, _proto.setOpacity);
cc.defineGetterSetter(_proto, "cascadeOpacity", _proto.isCascadeOpacityEnabled, _proto.setCascadeOpacityEnabled);
cc.defineGetterSetter(_proto, "color", _proto.getColor, _proto.setColor);
cc.defineGetterSetter(_proto, "cascadeColor", _proto.isCascadeColorEnabled, _proto.setCascadeColorEnabled);
_proto = cc.LayerColor.prototype;
cc.defineGetterSetter(_proto, "width", _proto._getWidth, _proto._setWidth);
cc.defineGetterSetter(_proto, "height", _proto._getHeight, _proto._setHeight);

View File

@ -7308,9 +7308,9 @@ int lua_cocos2dx_Application_is64BitIOSDevice(lua_State* tolua_S)
{
bool is64BitIOSDevice = false;
Application::Platform platform = cocos2d::Application::getInstance()->getTargetPlatform();
if (Application::Platform::OS_IPHONE == platform || Application::Platform::OS_IPAD == platform)
if (Application::Platform::OS_IPHONE == platform || Application::Platform::OS_IPAD == platform || Application::Platform::OS_ANDROID == platform)
{
#if defined(__arm64__)
#if defined(__arm64__) || defined(__aarch64__)
is64BitIOSDevice = true;
#endif
}

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
NS_CC_BEGIN
namespace ui {
IMPLEMENT_CLASS_GUI_INFO(PageView)
PageView::PageView():
@ -39,7 +39,9 @@ _childFocusCancelOffset(5.0f),
_pageViewEventListener(nullptr),
_pageViewEventSelector(nullptr),
_eventCallback(nullptr),
_autoScrollStopEpsilon(0.001f)
_autoScrollStopEpsilon(0.001f),
_previousPageIndex(-1),
_isTouchBegin(false)
{
}
@ -60,7 +62,7 @@ PageView* PageView::create()
CC_SAFE_DELETE(widget);
return nullptr;
}
bool PageView::init()
{
if (ListView::init())
@ -132,7 +134,7 @@ void PageView::removePageAtIndex(ssize_t index)
{
removeItem(index);
}
void PageView::removeAllPages()
{
removeAllItems();
@ -177,12 +179,12 @@ float PageView::getCustomScrollThreshold()const
{
return 0;
}
void PageView::setUsingCustomScrollThreshold(bool flag)
{
CCLOG("PageView::setUsingCustomScrollThreshold() has no effect!");
}
bool PageView::isUsingCustomScrollThreshold()const
{
return false;
@ -229,6 +231,16 @@ void PageView::refreshIndicatorPosition()
}
}
void PageView::handlePressLogic(Touch *touch)
{
ListView::handlePressLogic(touch);
if (!_isTouchBegin) {
_currentPageIndex = getIndex(getCenterItemInCurrentView());
_previousPageIndex = _currentPageIndex;
_isTouchBegin = true;
}
}
void PageView::handleReleaseLogic(Touch *touch)
{
// Use `ScrollView` method in order to avoid `startMagneticScroll()` by `ListView`.
@ -238,7 +250,6 @@ void PageView::handleReleaseLogic(Touch *touch)
{
return;
}
Vec2 touchMoveVelocity = flattenVectorByDirection(calculateTouchMoveVelocity());
static const float INERTIA_THRESHOLD = 500;
@ -276,12 +287,25 @@ void PageView::handleReleaseLogic(Touch *touch)
}
}
}
float PageView::getAutoScrollStopEpsilon() const
{
return _autoScrollStopEpsilon;
}
void PageView::addEventListenerPageView(Ref *target, SEL_PageViewEvent selector)
{
_pageViewEventListener = target;
_pageViewEventSelector = selector;
ccScrollViewCallback scrollViewCallback = [=](Ref* ref, ScrollView::EventType type) -> void{
if (type == ScrollView::EventType::AUTOSCROLL_ENDED && _previousPageIndex != _currentPageIndex) {
pageTurningEvent();
}
};
this->addEventListener(scrollViewCallback);
}
void PageView::pageTurningEvent()
{
this->retain();
@ -297,21 +321,16 @@ void PageView::pageTurningEvent()
{
_ccEventCallback(this, static_cast<int>(EventType::TURNING));
}
_isTouchBegin = false;
this->release();
}
void PageView::addEventListenerPageView(Ref *target, SEL_PageViewEvent selector)
{
_pageViewEventListener = target;
_pageViewEventSelector = selector;
}
void PageView::addEventListener(const ccPageViewCallback& callback)
{
_eventCallback = callback;
ccScrollViewCallback scrollViewCallback = [=](Ref* ref, ScrollView::EventType type) -> void{
if (type == ScrollView::EventType::AUTOSCROLL_ENDED) {
callback(ref, PageView::EventType::TURNING);
if (type == ScrollView::EventType::AUTOSCROLL_ENDED && _previousPageIndex != _currentPageIndex) {
pageTurningEvent();
}
};
this->addEventListener(scrollViewCallback);
@ -374,6 +393,12 @@ void PageView::copySpecialProperties(Widget *widget)
_ccEventCallback = pageView->_ccEventCallback;
_pageViewEventListener = pageView->_pageViewEventListener;
_pageViewEventSelector = pageView->_pageViewEventSelector;
_currentPageIndex = pageView->_currentPageIndex;
_previousPageIndex = pageView->_previousPageIndex;
_childFocusCancelOffset = pageView->_childFocusCancelOffset;
_autoScrollStopEpsilon = pageView->_autoScrollStopEpsilon;
_indicatorPositionAsAnchorPoint = pageView->_indicatorPositionAsAnchorPoint;
_isTouchBegin = pageView->_isTouchBegin;
}
}
@ -461,13 +486,13 @@ void PageView::setIndicatorIndexNodesColor(const Color3B& color)
_indicator->setIndexNodesColor(color);
}
}
const Color3B& PageView::getIndicatorIndexNodesColor() const
{
CCASSERT(_indicator != nullptr, "");
return _indicator->getIndexNodesColor();
}
void PageView::setIndicatorIndexNodesScale(float indexNodesScale)
{
if(_indicator != nullptr)
@ -476,13 +501,13 @@ void PageView::setIndicatorIndexNodesScale(float indexNodesScale)
_indicator->indicate(_currentPageIndex);
}
}
float PageView::getIndicatorIndexNodesScale() const
{
CCASSERT(_indicator != nullptr, "");
return _indicator->getIndexNodesScale();
}
void PageView::setIndicatorIndexNodesTexture(const std::string& texName,Widget::TextureResType texType)
{
if(_indicator != nullptr)
@ -491,7 +516,7 @@ void PageView::setIndicatorIndexNodesTexture(const std::string& texName,Widget::
_indicator->indicate(_currentPageIndex);
}
}
void PageView::remedyLayoutParameter(Widget *item)
{
item->setContentSize(this->getContentSize());

View File

@ -410,6 +410,7 @@ protected:
virtual void onItemListChanged() override;
virtual void onSizeChanged() override;
virtual void handleReleaseLogic(Touch *touch) override;
virtual void handlePressLogic(Touch *touch) override;
virtual Widget* createCloneInstance() override;
virtual void copySpecialProperties(Widget* model) override;
@ -439,6 +440,8 @@ protected:
#endif
ccPageViewCallback _eventCallback;
float _autoScrollStopEpsilon;
ssize_t _previousPageIndex;
bool _isTouchBegin;
};
}

View File

@ -2,193 +2,101 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Cocos2d-x 3.12 Release Notes](#cocos2d-x-312-release-notes)
- [Cocos2d-x 3.13 Release Notes](#cocos2d-x-313-release-notes)
- [Misc Information](#misc-information)
- [Requirements](#requirements)
- [Runtime Requirements](#runtime-requirements)
- [Compiler Requirements](#compiler-requirements)
- [How to run tests](#how-to-run-tests)
- [Cocos Console](#cocos-console)
- [Mac OSX & iOS](#mac-osx-&-ios)
- [Android](#android)
- [Windows](#windows)
- [Linux](#linux)
- [How to start a new game](#how-to-start-a-new-game)
- [v3.12](#v312)
- [v3.13](#v313)
- [Highlights](#highlights)
- [The main features in detail of Cocos2d-x v3.12](#the-main-features-in-detail-of-cocos2d-x-v312)
- [VR support](#vr-support)
- [Tizen support](#tizen-support)
- [improve Android performance](#improve-android-performance)
- [improve web engine performance in WebGL mode](#improve-web-engine-performance-in-webgl-mode)
- [Use clang on Android](#use-clang-on-android)
- [Other changes](#other-changes)
- [The main features in detail of Cocos2d-x v3.13](#the-main-features-in-detail-of-cocos2d-x-v313)
- [Add VR plugin](#add-vr-plugin)
- [Support ETC1 alpha channel](#support-etc1-alpha-channel)
- [AudioEngine performance for Android 4.2+](#audioengine-performance-for-android-42)
- [Dirty region in canvas renderer](#dirty-region-in-canvas-renderer)
- [Android arm-64 support](#android-arm-64-support)
- [Switch to use gcc 4.9 on Android](#switch-to-use-gcc-49-on-android)
- [Upgrade CURL to 7.50.0](#upgrade-curl-to-7500)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# Cocos2d-x 3.12 Release Notes #
# Cocos2d-x 3.13 Release Notes #
# Misc Information
* [Full Changelog](https://github.com/cocos2d/cocos2d-x/blob/v3/CHANGELOG)
# Requirements
## Runtime Requirements
* Android 2.3.3+
* iOS 5.0 or newer
* OS X 10.7 or newer
* Windows 7 or newer
* Windows Phone 8.1
* Windows 10 UWP
* Linux Ubuntu 14.04 or newer
* Modern browsers and IE 9+ (On mobile platforms, only iOS and Android 5 activated WebGL support)
## Compiler Requirements
* Xcode 5.1 or newer for iOS or Mac
* gcc 4.9 or newer for Linux
* ndk-r11+ for Android
* Visual Studio 2013 or newer for Windows (win32)
* Visual Studio 2013 update4 or newer for Windows 8.1 universal Apps
* Visual Studio 2015 or newer and Windows 10.0 (build 10074 or higher) for Windows 10.0 UWP Apps
## How to run tests
### Cocos Console
You can use [Cocos Console](www.cocos2d-x.org/wiki/Cocos2d-console) command line tool to run the test cases on almost all supported platforms.
In console application:
```
// Enter cpp test folder
cd tests/cpp-tests
// Or enter js test folder
cd tests/js-tests
// Or enter lua test folder
cd tests/lua-tests
// Compile or run test case
cocos compile -p ios|mac|android|win32|win8_1|metro|web -m debug|release
cocos run -p ios|mac|android|win32|win8_1|metro|web -m debug|release
```
For example, if you want to run cpp test in release mode on Android, you can use the following command:
```
cocos run -p android -m release
```
### Mac OSX & iOS
You can run the samples by:
* Open __cocos2d-x/build__ folder, open __cocos2d_test.xcodeproj__
* Select `cpp-tests`, `lua-tests`, `js-tests` for __iOS__ or __OS X__ target in scheme toolbar
* Click __run__ button
### Android
You can run the samples by either using the command-line or Eclipse:
**Using command line:**
Perform the following steps:
$ cd cocos2d-x
$ ./setup.py
$ cd build
$ ./android-build.py cpp-empty-test -p 10
$ adb install cocos2d-x/tests/cpp-empty-test/proj.android/bin/CppEmptyTest-debug.apk
Then click item on Android device to run tests. Available value of `-p` is the API level, Cocos2d-x supports from level 10.
**Using Eclipse:**
Perform the following steps:
$ cd cocos2d-x
$ ./setup.py
$ cd build
$ ./android-build.py cpp-empty-test -p 10
Next:
* Import Cocos2d-x Android project into Eclipse, the path used to import is __cocos/2d/platform/android__
* Import `cpp-empty-test` Android project into Eclipse, the path used to import is __tests/cpp-empty-test/proj.android__
* Build `cpp-empty-test` Android project and run
### Windows
You can run the samples by:
* For win32 project, enter __cocos2d-x/build__, and open __cocos2d-win32.sln__
* For win 8.1 project, enter __cocos2d-x/build__, and open __cocos2d-win8.1-universal.sln__
* For win 10 project, enter __cocos2d-x/build__, and open __cocos2d-win10.sln__
* Select running target
* Click run button
### Linux
You can run the samples by:
$ cd cocos2d-x/build
$ ./install-deps-linux.sh
$ cd ../..
Next:
$ mkdir build
$ cd build
$ cmake ../cocos2d-x
$ make -j4
Then run:
$ cd bin/cpp-empty-test
$ ./cpp-empty-test
## How to start a new game
Use the __cocos__ console app to create a new game:
```
cocos new -l cpp|js|lua MyNewGame
```
# v3.12
# v3.13
## Highlights
* add VR support in experimental
* add Tizen support
* improve Android performance issue
* improve web engine performance in WebGL mode
* support Android obb extension
* use clang instead of gcc on Android, use NDK r11+
* added VR plugins for Gear, Deepoon, Google Cardboard and Oculus.
* support ETC1 alpha channel
* fix AudioEngine performance for Android 4.2+
* improve canvas renderer performance with dirty region
* add Andorid arm-64 support
* switch to use gcc 4.9
* upgrade CURL to 7.50.0
* upgrade Spine to 3.4
* upgrade GLFW to 3.2
## The main features in detail of Cocos2d-x v3.12
## The main features in detail of Cocos2d-x v3.13
### VR support
VR Support is now available! Currently there is support for __Google Cardboard__, __Oculus Rift__, __Samsung Gear__ and __Deepoon E2__. Also provided is a *generic* __VR__ renderer to help with testing. It should not be used to trust deploying a production __VR__ game. In usual Cocos2d-x fashion it is very easy to get started with an easy to understand API. Read our chapter in the [Programmers Guide](http://cocos2d-x.org/docs/programmers-guide/vr/index.html) for more information.
### Added VR plugins
### Tizen support
You can now develop for the __Tizen__ mobile platform. The latest __2.4__ SDK is supported. Tizen development uses it's own uniqie IDE as well as a simulator for testing applications. For setup instructions please read our [documentation](http://cocos2d-x.org/docs/installation/Tizen/).
Support for Gear, Deepoon, Google Cardboard and Oculus has been added. Read about VR in our [Programmers Guide](http://www.cocos2d-x.org/docs/programmers-guide/vr/index.html)
### Improve Android performance
### Support ETC1 alpha channel
Thank you to our users for helping diagnose performance issues on some Android devices. It is because Cocos2d-x creates a big map buffer by default and fills the map buffer with actual data, which is less than the map buffer size. On some Android devices, it will transfer as much data as the map buffer size which causes performance issue.
Thanks [halx99](https://github.com/halx99)'s contribution, now cocos2d-x supports ETC1 alpha channel by default.
More detail information and discussion can refer to [the issue](https://github.com/cocos2d/cocos2d-x/issues/15652).
If want to use ETC1 alpha chaneel, you should put `xxx.pkm` and `xxx.pkm@alpha` in the same folder, and use it like this:
### Improve web engine performance in WebGL mode
```c++
auto sprite = Sprite::create("xxx.pkm");
```
The web engine is receiving a big performance upgrade. The WebGL renderer have been completely refactored from the ground up. This means improved rendering and a reduced memory footprint.
`xxx.pkm@alpha` is the resource for alpha channel. `@alpha` subfix is required by engine to load alpha texture automatically.
![rendering performance](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/adverage-time-per-frame.png)
More detail usage can refer to the implementation of `Sprite1ETC1Alpha` in `tests/cpp-tests/Classes/SpriteTest/SpriteTest.cpp`.
![cpu-usage](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/cpu-usage.png)
![](https://raw.githubusercontent.com/minggo/Pictures/master/etc1-alpha.png)
![memory-usage](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/memory-usage.png)
As you can see, the blue block in the middle of the picture is an ETC1 picture with alpha channel.
### Use clang on Android
[Google deprecated gcc starting in NDK r11](https://developer.android.com/ndk/downloads/revision_history.html), Cocos2d-x now uses clang. We suggest using the NDK r11c.
### AudioEngine performance for Android 4.2+
We found an issue that, if using NDKr 10c + clang, then `Node::enumerateChildren()` will crash on Android.
AudioEngine uses [OpenSL ES](https://developer.android.com/ndk/guides/audio/opensl-for-android.html) on Android, and it supports decoding audio source file to PCM data in codes since Android 4.2. Now AudioEngine uses this feature to fix the performance issue. The performane is the same as before if running on Android 4.1 or lower version. **Should preload first, or there is not performance improved for first time playing of the audio.**
## Other changes
View our [full changelog](https://github.com/cocos2d/cocos2d-x/blob/v3/CHANGELOG).
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance1.png)
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance2.png)
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance3.png)
### Dirty region in canvas renderer
In v3.12, we improved WebGL renderer in the web engine, this version have brought the dirty region algorithm to improve canvas renderer performance. Basically, it detect every region that have been changed between frames, then only render these parts instead of refresh the whole canvas. This technique is beneficial for many games in which the dynamic region is often limited, it can improve frame rate and reduce CPU usage, power consumation. It's desactivated by default, to activate it, you can do the following:
```
// Enable dirty region algorithm
if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
cc.renderer.enableDirtyRegion(true);
// Maximum dirty region count to activate the partial rendering process
cc.renderer.setDirtyRegionCountThreshold(6);
}
// Detect if dirty is enabled
var enabled = isDirtyRegionEnabled();
```
### Android arm-64 support
Now we provide arm-64 bit 3rd party libraries, which means can build 64-bit apps on Android. You can use the command to build 64-bit apps:
```
cocos run -p android --app-abi arm64-v8a
```
### Switch to use gcc 4.9 on Android
cocos2d-x switch to use clang in `v3.12`, but developers reported [some crash issue](https://github.com/cocos2d/cocos2d-x/issues/16244) that caused by using `clang+gnustl_static`, so we switch to use gcc 4.9. We will change to use `clang+c++_static` when `c++_static` is stable.
### Upgrade CURL to 7.50.0
Because CURL has [a bug about connect to IPV4 numerical IP address in NAT64 environment](https://github.com/curl/curl/issues/863), and it is fixed in v7.50.0, so we upgrade to this version when v7.50.0 is released.

View File

@ -2,77 +2,114 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [v3.12](#v312)
- [v3.13](#v313)
- [新特性](#%E6%96%B0%E7%89%B9%E6%80%A7)
- [主要特性的详细介绍](#%E4%B8%BB%E8%A6%81%E7%89%B9%E6%80%A7%E7%9A%84%E8%AF%A6%E7%BB%86%E4%BB%8B%E7%BB%8D)
- [VR支持](#vr%E6%94%AF%E6%8C%81)
- [Tizen支持](#tizen%E6%94%AF%E6%8C%81)
- [提高Android渲染效率](#%E6%8F%90%E9%AB%98android%E6%B8%B2%E6%9F%93%E6%95%88%E7%8E%87)
- [提升Cocos2d-html5引擎WebGL模式下的性能](#%E6%8F%90%E5%8D%87cocos2d-html5%E5%BC%95%E6%93%8Ewebgl%E6%A8%A1%E5%BC%8F%E4%B8%8B%E7%9A%84%E6%80%A7%E8%83%BD)
- [Android使用clang编译器](#android%E4%BD%BF%E7%94%A8clang%E7%BC%96%E8%AF%91%E5%99%A8)
- [增加VR插件](#%E5%A2%9E%E5%8A%A0vr%E6%8F%92%E4%BB%B6)
- [支持ETC1 alpha通道](#%E6%94%AF%E6%8C%81etc1-alpha%E9%80%9A%E9%81%93)
- [AudioEngin性能提升](#audioengin%E6%80%A7%E8%83%BD%E6%8F%90%E5%8D%87)
- [脏矩形算法](#%E8%84%8F%E7%9F%A9%E5%BD%A2%E7%AE%97%E6%B3%95)
- [支持Android 64位应用](#%E6%94%AF%E6%8C%81android-64%E4%BD%8D%E5%BA%94%E7%94%A8)
- [Android切换回gcc 4.9](#android%E5%88%87%E6%8D%A2%E5%9B%9Egcc-49)
- [CURL升级到7.50.0](#curl%E5%8D%87%E7%BA%A7%E5%88%B07500)
- [其他改动](#%E5%85%B6%E4%BB%96%E6%94%B9%E5%8A%A8)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# v3.12
# v3.13
## 新特性
* 支持VR目前还处于测试阶段
* 支持Tizen平台
* 提升引擎在Android平台的渲染效率
* 提升Cocos2d-html5 WebGL模式的性能
* 支持Android的OBB扩展格式
* Android平台使用clang编译器使用NDK r11+
* 增加了VR插件包括**GearVR**、**GVR(Cardboard和Daydream)**、**DeepoonVR**和**OculusVR**
* 支持ETC1 alpha通道
* 解决了AudioEngin的性能问题在Android 4.2+有效
* 通过脏矩形算法提升Canvas渲染器性能
* 支持Android 64位应用
* 集成[AnySDK][1]
* Android切换回gcc 4.9
* CURL升级到7.50.0
* Spine升级到3.4
* GLFW升级到3.2
## 主要特性的详细介绍
### VR支持
### 增加VR插件
该版本添加了VR支持不过还处于测试阶段。目前支持的设备有__Google Cardboard____Oculus Rift____Samsung Gear__和__Deepoon E2__。关于如何使用、测试VR功能请参考[Programming Guide](http://cocos2d-x.org/docs/programmers-guide/vr/index.html)。
支持了Gear、Deepon、Google Cardboard和Oculus插件。具体的使用方法可以参考[Programmers Guide](http://www.cocos2d-x.org/docs/programmers-guide/vr/index.html)。
### Tizen支持
### 支持ETC1 alpha通道
该版本添加了Tizen平台的支持。支持的TizenSDK版本是__2.4__。开发Tizen平台应用时需要使用Tizen平台有自己的IDE和模拟器。请参考[这篇文档](http://cocos2d-x.org/docs/installation/Tizen/)了解如何搭建Tizen应用开发环境
感谢[halx99](https://github.com/halx99)的贡献cocos2d-x支持ETC1 alpha通道
### 提高Android渲染效率
这里要多谢社区的开发者帮忙在各种Android设备上测试、验证性能问题。这个问题的原因是因为引擎默认创建了一个比较大的map buffer实际需要传到该map buffer的数据并没有那么多。但是在有些Android设备不管实际数据大小是多少每次都传输和map buffer大小一样多的数据。
通过代码解释如下:
要想使用ETC1 alpha通道必须在相同目录下提供`xxx.pkm`和`xxx.pkm@alpha`,代码使用方法如下:
```c++
// 初始化map buffer
glBindBuffer(GL_ARRAY_BUFFER, BUFFER_ID);
glBufferData(GL_ARRAY_BUFFER, 65536, xxx , GL_DYNAMIC_DRAW);
auto sprite = Sprite::create("xxx.pkm");
```
具体使用map buffer的代码是
引擎会自动去加载`xxx.pkm@alpha`作为alpha通道数据。更详细的使用方式请参考`tests/cpp-tests/Classes/SpriteTest/SpriteTest.cpp`里的`Sprite1ETC1Alpha `测试例子。
```c++
// 实际使用map buffer
glBindBuffer(GL_ARRAY_BUFFER, BUFFER_ID);
// 虽然只需要传输100个元素但是在某些Android机器上仍然传输65536个元素
glBufferData(GL_ARRAY_BUFFER, 100, xxx , GL_DYNAMIC_DRAW);
![](https://raw.githubusercontent.com/minggo/Pictures/master/etc1-alpha.png)
图中蓝色部分就是带alpha通道的ETC1图片。
### AudioEngin性能提升
Android平台下AudioEngine使用[OpenSL ES](https://developer.android.com/ndk/guides/audio/opensl-for-android.html)播放声音。从Android 4.2开始OpenSL ES支持解码声音文件为PCM数据引擎正是利用这个以特性来缓存解码后数据以提升性能。因此该性能提升只在Android 4.2及以上版本有效。**需要先preload否则第一次播放性能没有很大提升**。
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance1.png)
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance2.png)
![](https://raw.githubusercontent.com/minggo/Pictures/master/audio/audio-performance3.png)
### 集成[AnySDK][1]
[AnySDK][1]为CP商提供一套第三方SDK接入解决方案整个接入过程不改变任何SDK的功能、特性、参数等对于最终玩家而言是完全透明无感知的。支持的第三方SDK包括**渠道SDK**、**用户系统**、**支付系统**、**广告系统**、**统计系统**、**分享系统**等。
可以通过如下方法集成[AnySDK][1]
```
cocos package import anysdk -p PROJECT_PATH --anysdk
```
详细的讨论可以参考[这个github issue](https://github.com/cocos2d/cocos2d-x/issues/15652)。
`PROJECT_PATH`是游戏工程的根目录,比如`COCOS2DX_ROOT/tests/cpp-empty-test`
### 提升Cocos2d-html5引擎WebGL模式下的性能
通过上面命令后,[AnySDK][1]框架就集成到了游戏项目中可以在代码里调用AnySDK接口接入各种第三方SDK了。[AnySDK][1]的详细介绍和使用方法请参考[AnySDK][1]官网。
该版本大幅提升了Cocos2d-html5引擎在WebGL模式下的性能。引擎的渲染性能、CPU使用量和内存大小都有提升。
### 脏矩形算法
![rendering peformance](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/adverage-time-per-frame.png)
在v3.12中我们通过重构WebGL渲染器大幅度提升了Web引擎的性能在这个版本中我们又实现了脏矩形算法来提升Canvas渲染器的性能。脏矩形算法允许引擎只渲染当前帧中和前一帧不同的区域而不是渲染整个画布大大降低填充率可以同时带来渲染效率的提升以及CPU使用率和耗电量的降低。对于相对静态的游戏画面来说非常有效。这个功能默认是关闭的开启它可以通过下面的代码
![cpu-usage](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/cpu-usage.png)
```
// 开启脏矩形算法
if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
cc.renderer.enableDirtyRegion(true);
// 设置允许用脏矩形算法进行局部渲染的最高脏矩形数量
cc.renderer.setDirtyRegionCountThreshold(6);
}
// 检查脏矩形算法是否开启
var enabled = isDirtyRegionEnabled();
```
![memory-usage](https://raw.githubusercontent.com/minggo/Pictures/master/web-performance-improve/memory-usage.png)
### 支持Android 64位应用
### Android使用clang编译器
该版本提供了Android 64位的第三方库因此可以编译出64位的Android应用。可以使用如下命令编译、运行64位Android程序
[从NDK r11开始Google弃用了gcc](https://developer.android.com/ndk/downloads/revision_history.html)所以cocos2d-x也切换到clang编译器。
```
cocos run -p android --app-abi arm64-v8a
```
建议使用NDK r11c。在测试过程中发现如果使用NDK r10c + clang的话`Node::enumerateChildren()`会崩溃。
### Android切换回gcc 4.9
cocos2d-x 3.12时使用了clang编译器结果发现了[崩溃问题](https://github.com/cocos2d/cocos2d-x/issues/16244)。通过测试发现该问题是由于使用`clang + gnustl_static`造成的因此该版本切换回使用gcc 4.9。当`c++_static`稳定后再切换成clang。
### CURL升级到7.50.0
CURL 7.50.0解决了[在NAT64环境连接IPV4地址格式的IP地址错误](https://github.com/curl/curl/issues/863)问题因此引擎及时升级了CURL版本。
## 其他改动
更完整的改动列表可以阅读[full changelog](https://github.com/cocos2d/cocos2d-x/blob/v3/CHANGELOG)。
[1]: http://www.anysdk.com/

View File

@ -49,18 +49,18 @@ NS_CC_EXT_BEGIN
static Color4F ColorForBody(cpBody *body)
{
if (CP_BODY_TYPE_STATIC == cpBodyGetType(body) || cpBodyIsSleeping(body))
if (CP_BODY_TYPE_STATIC == cpBodyGetType(body) || cpBodyIsSleeping(body))
{
return Color4F(0.5f, 0.5f, 0.5f ,0.5f);
}
return Color4F(0.5f, 0.5f, 0.5f ,0.5f);
}
else if (body->sleeping.idleTime > cpBodyGetSpace(body)->sleepTimeThreshold)
{
return Color4F(0.33f, 0.33f, 0.33f, 0.5f);
}
return Color4F(0.33f, 0.33f, 0.33f, 0.5f);
}
else
{
return Color4F(1.0f, 0.0f, 0.0f, 0.5f);
}
return Color4F(1.0f, 0.0f, 0.0f, 0.5f);
}
}
static Vec2 cpVert2Point(const cpVect &vert)
@ -83,12 +83,12 @@ static Vec2* cpVertArray2ccpArrayN(const cpVect* cpVertArray, unsigned int count
static void DrawShape(cpShape *shape, DrawNode *renderer)
{
cpBody *body = cpShapeGetBody(shape);
Color4F color = ColorForBody(body);
cpBody *body = cpShapeGetBody(shape);
Color4F color = ColorForBody(body);
switch (shape->CP_PRIVATE(klass)->type)
switch (shape->CP_PRIVATE(klass)->type)
{
case CP_CIRCLE_SHAPE:
case CP_CIRCLE_SHAPE:
{
cpCircleShape *circle = (cpCircleShape *)shape;
cpVect center = circle->tc;
@ -97,13 +97,13 @@ static void DrawShape(cpShape *shape, DrawNode *renderer)
renderer->drawSegment(cpVert2Point(center), cpVert2Point(cpvadd(center, cpvmult(cpBodyGetRotation(body), radius))), 1.0, color);
}
break;
case CP_SEGMENT_SHAPE:
case CP_SEGMENT_SHAPE:
{
cpSegmentShape *seg = (cpSegmentShape *)shape;
renderer->drawSegment(cpVert2Point(seg->ta), cpVert2Point(seg->tb), cpfmax(seg->r, 2.0), color);
}
break;
case CP_POLY_SHAPE:
case CP_POLY_SHAPE:
{
cpPolyShape* poly = (cpPolyShape*)shape;
Color4F line = color;
@ -116,17 +116,17 @@ static void DrawShape(cpShape *shape, DrawNode *renderer)
CC_SAFE_DELETE_ARRAY(pPoints);
}
break;
default:
cpAssertHard(false, "Bad assertion in DrawShape()");
}
default:
cpAssertHard(false, "Bad assertion in DrawShape()");
}
}
static Color4F CONSTRAINT_COLOR(0, 1, 0, 0.5);
static void DrawConstraint(cpConstraint *constraint, DrawNode *renderer)
{
cpBody *body_a = cpConstraintGetBodyA(constraint);
cpBody *body_b = cpConstraintGetBodyB(constraint);
cpBody *body_a = cpConstraintGetBodyA(constraint);
cpBody *body_b = cpConstraintGetBodyB(constraint);
if(cpConstraintIsPinJoint(constraint))
{
@ -169,7 +169,7 @@ static void DrawConstraint(cpConstraint *constraint, DrawNode *renderer)
}
else
{
// printf("Cannot draw constraint\n");
// printf("Cannot draw constraint\n");
}
}
#endif // #if CC_ENABLE_CHIPMUNK_INTEGRATION
@ -187,7 +187,7 @@ void PhysicsDebugNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t
DrawNode::clear();
cpSpaceEachShape(_spacePtr, (cpSpaceShapeIteratorFunc)DrawShape, this);
cpSpaceEachConstraint(_spacePtr, (cpSpaceConstraintIteratorFunc)DrawConstraint, this);
cpSpaceEachConstraint(_spacePtr, (cpSpaceConstraintIteratorFunc)DrawConstraint, this);
DrawNode::draw(renderer, transform, flags);
#endif

View File

@ -363,25 +363,25 @@ void PhysicsSprite::setRotation(float fRotation)
void PhysicsSprite::syncPhysicsTransform() const
{
// Although scale is not used by physics engines, it is calculated just in case
// the sprite is animated (scaled up/down) using actions.
// For more info see: http://www.cocos2d-iphone.org/forum/topic/68990
// the sprite is animated (scaled up/down) using actions.
// For more info see: http://www.cocos2d-iphone.org/forum/topic/68990
#if CC_ENABLE_CHIPMUNK_INTEGRATION
cpVect rot = (_ignoreBodyRotation ? cpvforangle(-CC_DEGREES_TO_RADIANS(_rotationX)) : cpBodyGetRotation(_CPBody));
float x = cpBodyGetPosition(_CPBody).x + rot.x * -_anchorPointInPoints.x * _scaleX - rot.y * -_anchorPointInPoints.y * _scaleY;
float y = cpBodyGetPosition(_CPBody).y + rot.y * -_anchorPointInPoints.x * _scaleX + rot.x * -_anchorPointInPoints.y * _scaleY;
cpVect rot = (_ignoreBodyRotation ? cpvforangle(-CC_DEGREES_TO_RADIANS(_rotationX)) : cpBodyGetRotation(_CPBody));
float x = cpBodyGetPosition(_CPBody).x + rot.x * -_anchorPointInPoints.x * _scaleX - rot.y * -_anchorPointInPoints.y * _scaleY;
float y = cpBodyGetPosition(_CPBody).y + rot.y * -_anchorPointInPoints.x * _scaleX + rot.x * -_anchorPointInPoints.y * _scaleY;
if (_ignoreAnchorPointForPosition)
if (_ignoreAnchorPointForPosition)
{
x += _anchorPointInPoints.x;
y += _anchorPointInPoints.y;
}
x += _anchorPointInPoints.x;
y += _anchorPointInPoints.y;
}
float mat[] = { (float)rot.x * _scaleX, (float)rot.y * _scaleX, 0, 0,
(float)-rot.y * _scaleY, (float)rot.x * _scaleY, 0, 0,
0, 0, 1, 0,
x, y, 0, 1};
x, y, 0, 1};
_transform.set(mat);
@ -390,32 +390,32 @@ void PhysicsSprite::syncPhysicsTransform() const
b2Vec2 pos = _pB2Body->GetPosition();
float x = pos.x * _PTMRatio;
float y = pos.y * _PTMRatio;
float x = pos.x * _PTMRatio;
float y = pos.y * _PTMRatio;
if (_ignoreAnchorPointForPosition)
if (_ignoreAnchorPointForPosition)
{
x += _anchorPointInPoints.x;
y += _anchorPointInPoints.y;
}
x += _anchorPointInPoints.x;
y += _anchorPointInPoints.y;
}
// Make matrix
float radians = _pB2Body->GetAngle();
float c = cosf(radians);
float s = sinf(radians);
// Make matrix
float radians = _pB2Body->GetAngle();
float c = cosf(radians);
float s = sinf(radians);
if (!_anchorPointInPoints.isZero())
if (!_anchorPointInPoints.isZero())
{
x += ((c * -_anchorPointInPoints.x * _scaleX) + (-s * -_anchorPointInPoints.y * _scaleY));
y += ((s * -_anchorPointInPoints.x * _scaleX) + (c * -_anchorPointInPoints.y * _scaleY));
}
x += ((c * -_anchorPointInPoints.x * _scaleX) + (-s * -_anchorPointInPoints.y * _scaleY));
y += ((s * -_anchorPointInPoints.x * _scaleX) + (c * -_anchorPointInPoints.y * _scaleY));
}
// Rot, Translate Matrix
// Rot, Translate Matrix
float mat[] = { (float)c * _scaleX, (float)s * _scaleX, 0, 0,
(float)-s * _scaleY, (float)c * _scaleY, 0, 0,
0, 0, 1, 0,
x, y, 0, 1};
x, y, 0, 1};
_transform.set(mat);
#endif

View File

@ -326,6 +326,8 @@
"cocos/audio/android/jni/cddandroidAndroidJavaEngine.h",
"cocos/audio/android/utils/Compat.h",
"cocos/audio/android/utils/Errors.h",
"cocos/audio/android/utils/Utils.cpp",
"cocos/audio/android/utils/Utils.h",
"cocos/audio/apple/AudioCache.h",
"cocos/audio/apple/AudioCache.mm",
"cocos/audio/apple/AudioEngine-inl.h",
@ -1034,9 +1036,10 @@
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxLocalStorage.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxLuaJavaBridge.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxReflectionHelper.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxSound.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxTextInputWraper.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxTextInputWrapper.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxTypefaces.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxVideoHelper.java",
"cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxVideoView.java",

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../cocos2d/cocos/platform/android/java

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

View File

@ -8,9 +8,6 @@ LOCAL_MODULE_FILENAME := libcocos2dlua
LOCAL_SRC_FILES := \
../../../Classes/AppDelegate.cpp \
../../../Classes/ide-support/SimpleConfigParser.cpp \
../../../Classes/ide-support/RuntimeLuaImpl.cpp \
../../../Classes/ide-support/lua_debugger.c \
hellolua/main.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes
@ -19,7 +16,6 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes
# _COCOS_HEADER_ANDROID_END
LOCAL_STATIC_LIBRARIES := cocos2d_lua_static
LOCAL_STATIC_LIBRARIES += cocos2d_simulator_static
# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END
@ -27,7 +23,6 @@ LOCAL_STATIC_LIBRARIES += cocos2d_simulator_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,scripting/lua-bindings/proj.android)
$(call import-module,tools/simulator/libsimulator/proj.android)
# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -1,5 +1,7 @@
/****************************************************************************
Copyright (c) 2015 Chukong Technologies Inc.
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2016 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
http://www.cocos2d-x.org
@ -23,105 +25,8 @@ THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.lua;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.ArrayList;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.provider.Settings;
import android.text.format.Formatter;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
public class AppActivity extends Cocos2dxActivity{
static String hostIPAdress = "0.0.0.0";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(nativeIsLandScape()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
//2.Set the format of window
// Check the wifi is opened when the native is debug.
if(nativeIsDebug())
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(!isNetworkConnected())
{
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("Warning");
builder.setMessage("Please open WIFI for debugging...");
builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
finish();
System.exit(0);
}
});
builder.setNegativeButton("Cancel", null);
builder.setCancelable(true);
builder.show();
}
hostIPAdress = getHostIpAddress();
}
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
ArrayList networkTypes = new ArrayList();
networkTypes.add(ConnectivityManager.TYPE_WIFI);
try {
networkTypes.add(ConnectivityManager.class.getDeclaredField("TYPE_ETHERNET").getInt(null));
} catch (NoSuchFieldException nsfe) {
}
catch (IllegalAccessException iae) {
throw new RuntimeException(iae);
}
if (networkInfo != null && networkTypes.contains(networkInfo.getType())) {
return true;
}
}
return false;
}
public String getHostIpAddress() {
WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
return ((ip & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF));
}
public static String getLocalIpAddress() {
return hostIPAdress;
}
private static native boolean nativeIsLandScape();
private static native boolean nativeIsDebug();
public class AppActivity extends Cocos2dxActivity{
}

View File

@ -23,7 +23,6 @@ LOCAL_STATIC_LIBRARIES := cocos2d_lua_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,scripting/lua-bindings/proj.android)
$(call import-module,tools/simulator/libsimulator/proj.android)
# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

View File

@ -1,7 +1,6 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
Copyright (c) 2010-2016 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
http://www.cocos2d-x.org
@ -26,105 +25,8 @@ THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.lua;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.ArrayList;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.provider.Settings;
import android.text.format.Formatter;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
public class AppActivity extends Cocos2dxActivity{
static String hostIPAdress = "0.0.0.0";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(nativeIsLandScape()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
//2.Set the format of window
// Check the wifi is opened when the native is debug.
if(nativeIsDebug())
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(!isNetworkConnected())
{
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("Warning");
builder.setMessage("Please open WIFI for debugging...");
builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
finish();
System.exit(0);
}
});
builder.setNegativeButton("Cancel", null);
builder.setCancelable(true);
builder.show();
}
hostIPAdress = getHostIpAddress();
}
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
ArrayList networkTypes = new ArrayList();
networkTypes.add(ConnectivityManager.TYPE_WIFI);
try {
networkTypes.add(ConnectivityManager.class.getDeclaredField("TYPE_ETHERNET").getInt(null));
} catch (NoSuchFieldException nsfe) {
}
catch (IllegalAccessException iae) {
throw new RuntimeException(iae);
}
if (networkInfo != null && networkTypes.contains(networkInfo.getType())) {
return true;
}
}
return false;
}
public String getHostIpAddress() {
WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
return ((ip & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF) + "." + ((ip >>>= 8) & 0xFF));
}
public static String getLocalIpAddress() {
return hostIPAdress;
}
private static native boolean nativeIsLandScape();
private static native boolean nativeIsDebug();
public class AppActivity extends Cocos2dxActivity{
}

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../../cocos/platform/android/java

View File

@ -42,6 +42,7 @@ AudioEngineTests::AudioEngineTests()
ADD_TEST_CASE(AudioPerformanceTest);
ADD_TEST_CASE(AudioSwitchStateTest);
ADD_TEST_CASE(AudioSmallFileTest);
ADD_TEST_CASE(AudioPauseResumeAfterPlay);
}
namespace {
@ -803,3 +804,27 @@ std::string AudioSmallFileTest::subtitle() const
{
return "Should not crash";
}
/////////////////////////////////////////////////////////////////////////
bool AudioPauseResumeAfterPlay::init()
{
if (AudioEngineTestDemo::init())
{
int audioId = AudioEngine::play2d("audio/SoundEffectsFX009/FX082.mp3");
AudioEngine::pause(audioId);
AudioEngine::resume(audioId);
return true;
}
return false;
}
std::string AudioPauseResumeAfterPlay::title() const
{
return "pause & resume right after play2d";
}
std::string AudioPauseResumeAfterPlay::subtitle() const
{
return "Should not crash";
}

View File

@ -199,4 +199,15 @@ public:
virtual std::string subtitle() const override;
};
class AudioPauseResumeAfterPlay : public AudioEngineTestDemo
{
public:
CREATE_FUNC(AudioPauseResumeAfterPlay);
virtual bool init() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
#endif /* defined(__NEWAUDIOENGINE_TEST_H_) */

View File

@ -84,7 +84,8 @@ bool UIPageViewTest::init()
pageView->removeItem(0);
pageView->scrollToItem(pageCount - 2);
pageView->addEventListener((PageView::ccPageViewCallback)CC_CALLBACK_2(UIPageViewTest::pageViewEvent, this));
//This method is deprecated, we used here only testing purpose
pageView->addEventListenerPageView(this, pagevieweventselector(UIPageViewTest::pageViewEvent));
_uiLayer->addChild(pageView);
@ -93,11 +94,11 @@ bool UIPageViewTest::init()
return false;
}
void UIPageViewTest::pageViewEvent(Ref *pSender, PageView::EventType type)
void UIPageViewTest::pageViewEvent(Ref *pSender, PageViewEventType type)
{
switch (type)
{
case PageView::EventType::TURNING:
case PAGEVIEW_EVENT_TURNING:
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
@ -199,7 +200,9 @@ bool UIPageViewButtonTest::init()
void UIPageViewButtonTest::onButtonClicked(Ref* sender, Widget::TouchEventType type)
{
log("button %s clicked", static_cast<Button*>(sender)->getName().c_str());
if(type == Widget::TouchEventType::ENDED) {
log("button %s clicked", static_cast<Button*>(sender)->getName().c_str());
}
}

View File

@ -38,7 +38,7 @@ public:
~UIPageViewTest();
virtual bool init() override;
void pageViewEvent(cocos2d::Ref* sender, cocos2d::ui::PageView::EventType type);
void pageViewEvent(cocos2d::Ref* sender, cocos2d::ui::PageViewEventType type);
protected:

View File

@ -839,13 +839,13 @@ void UIHelperSubStringTest::onEnter()
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 7, 0) == "");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 8, 0) == "");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 8, 1) == "");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 1) == "");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 4) == "这里是中");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 8) == "这里是中文测试例");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 100) == "这里是中文测试例");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 2, 5) == "是中文测试");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 6, 2) == "试例");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 6, 100) == "试例");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 1) == "\xe8\xbf\x99");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 4) == "\xe8\xbf\x99\xe9\x87\x8c\xe6\x98\xaf\xe4\xb8\xad");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 8) == "\xe8\xbf\x99\xe9\x87\x8c\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87\xe6\xb5\x8b\xe8\xaf\x95\xe4\xbe\x8b");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 0, 100) == "\xe8\xbf\x99\xe9\x87\x8c\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87\xe6\xb5\x8b\xe8\xaf\x95\xe4\xbe\x8b");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 2, 5) == "\xe6\x98\xaf\xe4\xb8\xad\xe6\x96\x87\xe6\xb5\x8b\xe8\xaf\x95");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 6, 2) == "\xe8\xaf\x95\xe4\xbe\x8b");
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 6, 100) == "\xe8\xaf\x95\xe4\xbe\x8b");
// Error: These cases cause "out of range" error
CC_ASSERT(Helper::getSubStringOfUTF8String(source, 9, 0) == "");

View File

@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
<map version="1.0" orientation="hexagonal" width="5" height="5" tilewidth="175" tileheight="150">
<tileset name="bla" firstgid="1" tilewidth="175" tileheight="150">
<image source="hexa-tiles.png"/>
<map version="1.0" orientation="hexagonal" renderorder="right-down" width="5" height="5" tilewidth="175" tileheight="150" hexsidelength="88" staggeraxis="x" staggerindex="odd" nextobjectid="1">
<tileset firstgid="1" name="bla" tilewidth="175" tileheight="150" tilecount="6" columns="2">
<image source="hexa-tiles.png" width="512" height="512"/>
</tileset>
<layer name="Layer 0" width="5" height="5">
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAAGNiYGBgA2JGIGaC0qxQNiuSGBuUz4amDibGhqQGXQwAD578mGQAAAA=
H4sIAAAAAAAAA2NiYGBgA2JGIGaC0qxQNiuSGBuUz4amDibGhqQGXQwAD578mGQAAAA=
</data>
</layer>
</map>

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../../cocos/platform/android/java

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../../cocos/platform/android/ControllerManualAdapter

View File

@ -157,10 +157,9 @@ bool AppDelegate::applicationDidFinishLaunching()
sc->enableDebugger();
#endif
auto pEngine = ScriptingCore::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(pEngine);
ScriptEngineManager::getInstance()->setScriptEngine(sc);
ScriptingCore::getInstance()->runScript("main.js");
sc->runScript("main.js");
return true;
}

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-9
target=android-10
android.library.reference.1=../../../../cocos/platform/android/java

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../../../cocos/platform/android/java

View File

@ -1,12 +1,14 @@
local targetPlatform = cc.Application:getInstance():getTargetPlatform()
local is64BitIOSDevice = cc.Application:getInstance():is64BitIOSDevice()
print("is64BitIOSDevice:" .. tostring(is64BitIOSDevice))
if cc.PLATFORM_OS_LINUX ~= targetPlatform and cc.PLATFORM_OS_TIZEN ~= targetPlatform and is64BitIOSDevice ~= true then
require("ByteCodeEncryptTest/ByteCodeTest")
require("ByteCodeEncryptTest/ByteCodeAndEncryptTest")
end
if (cc.PLATFORM_OS_IPHONE == targetPlatform or cc.PLATFORM_OS_IPAD == targetPlatform) and is64BitIOSDevice == true then
if (cc.PLATFORM_OS_IPHONE == targetPlatform or cc.PLATFORM_OS_IPAD == targetPlatform or cc.PLATFORM_OS_ANDROID == targetPlatform) and is64BitIOSDevice == true then
require("ByteCodeEncryptTest/ByteCodeAndEncryptTest-arm64")
require("ByteCodeEncryptTest/ByteCodeTest-arm64")
end
@ -65,7 +67,7 @@ local function byteCodeEncryptMainLayer()
item:setEnabled(false)
end
if (cc.PLATFORM_OS_IPHONE == targetPlatform or cc.PLATFORM_OS_IPAD == targetPlatform) and is64BitIOSDevice == true then
if (cc.PLATFORM_OS_ANDROID == targetPlatform or cc.PLATFORM_OS_IPHONE == targetPlatform or cc.PLATFORM_OS_IPAD == targetPlatform) and is64BitIOSDevice == true then
item:setEnabled(true)
end
end

View File

@ -856,6 +856,10 @@ local function OpenGLTestMainLayer()
local loc = gl.getUniformLocation( program, "CC_MVPMatrix")
-- Save the old MVP matrix
local oldUniformTable = gl.getUniform( program, loc )
-- Set the new MVP matrix
gl.uniformMatrix4fv(loc, false, table.getn(pMatrix), pMatrix)
local uniformTable = gl.getUniform( program, loc )
@ -866,6 +870,9 @@ local function OpenGLTestMainLayer()
strFmt = strFmt..strTmp
end
print(strFmt)
-- Revert to the old MVP matrix
gl.uniformMatrix4fv(loc, false, table.getn(oldUniformTable), oldUniformTable)
end
runTest()

View File

@ -11,7 +11,7 @@ require "AssetsManagerTest/AssetsManagerTest"
require "AssetsManagerExTest/AssetsManagerExTest"
require "BillBoardTest/BillBoardTest"
require "BugsTest/BugsTest"
require "ByteCodeEncryptTest/ByteCodeEncryptTest"
-- require "ByteCodeEncryptTest/ByteCodeEncryptTest"
require "Camera3DTest/Camera3DTest"
require "ClickAndMoveTest/ClickAndMoveTest"
require "CocosDenshionTest/CocosDenshionTest"

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-19
target=android-10

View File

@ -8,6 +8,6 @@
# project structure.
# Project target.
target=android-19
target=android-10
android.library.reference.1=../../../cocos/platform/android/java

@ -1 +1 @@
Subproject commit a3738ce6acaa9130dfd6f1d1dc92768bf88cb49a
Subproject commit 9644a22afa162bbdd9cd95ed351a9b35f4cd4f34

View File

@ -7,10 +7,10 @@ prefix = cocos2dx
# all classes will be embedded in that namespace
target_namespace = cc
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.9/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/%(clang_version)s/include
clang_headers = -I%(clangllvmdir)s/%(clang_include)s
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/external
@ -31,7 +31,7 @@ replace_headers = CCComponentJS.h::scripting/js-bindings/manual/component/CCComp
classes = New.* Sprite SpriteBatchNode SpriteFrame SpriteFrameCache Scene Node.* Director Layer.* Menu.* Touch .*Action.* Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* PointArray ToggleVisibility.* RemoveSelf Hide Particle.* Label.* Atlas.* TextureCache.* Texture2D Cardinal.* CatmullRom.* ParallaxNode TileMap.* TMX.* CallFunc CallFuncN RenderTexture GridAction Grid3DAction Grid3D TiledGrid3D GridBase$ .+Grid Shaky3D Waves3D FlipX3D FlipY3D Lens3D Ripple3D PageTurn3D ShakyTiles3D ShatteredTiles3D WavesTiles3D JumpTiles3D Speed ActionManager Set SimpleAudioEngine Scheduler Orbit.* Follow.* Bezier.* CardinalSpline.* Camera.* DrawNode Liquid$ Waves$ ShuffleTiles$ TurnOffTiles$ Split.* Twirl$ FileUtils$ GLProgram GLProgramCache Application ClippingNode MotionStreak TextFieldTTF GLViewProtocol GLView Component ComponentContainer __NodeRGBA __LayerRGBA SAXParser Event(?!.*(Physics).*).* Device Configuration ProtectedNode GLProgramState Image .*Light$ AsyncTaskPool Properties Material Technique RenderState Pass ComponentJS
classes_need_extend = Node __NodeRGBA Layer.* Sprite SpriteBatchNode SpriteFrame Menu MenuItem.* Scene DrawNode Component .*Action.* GridBase Grid3D TiledGrid3D MotionStreak ParticleBatchNode ParticleSystem TextFieldTTF RenderTexture TileMapAtlas TMXLayer TMXTiledMap TMXMapInfo TransitionScene ProgressTimer ParallaxNode Label.* GLProgram Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* Orbit.* Follow.* Bezier.* Hide CallFunc CallFuncN
classes_need_extend = Node Layer.* Sprite SpriteBatchNode SpriteFrame Menu MenuItem.* Scene DrawNode Component .*Action.* GridBase Grid3D TiledGrid3D MotionStreak ParticleBatchNode ParticleSystem TextFieldTTF RenderTexture TileMapAtlas TMXLayer TMXTiledMap TMXMapInfo TransitionScene ProgressTimer ParallaxNode Label.* GLProgram Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn ReverseTime Animate AnimationFrame Animation AnimationCache Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* Orbit.* Follow.* Bezier.* Hide CallFunc CallFuncN
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
@ -167,8 +167,6 @@ rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames ge
rename_classes = ParticleSystemQuad::ParticleSystem,
SimpleAudioEngine::AudioEngine,
__NodeRGBA::NodeRGBA,
__LayerRGBA::LayerRGBA,
SAXParser::PlistParser,
GLProgramCache::ShaderCache,
CallFunc::_CallFunc,
@ -186,7 +184,7 @@ base_classes_to_skip = Ref Clonable
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes = FiniteTimeAction ActionInterval ActionEase EaseRateAction EaseElastic EaseBounce ActionInstant GridAction Grid3DAction TiledGrid3DAction Director SpriteFrameCache TransitionEaseScene Set SimpleAudioEngine FileUtils Application GLViewProtocol GLView ComponentContainer SAXParser Configuration EventListener BaseLight AsyncTaskPool ComponentJS
abstract_classes = Action FiniteTimeAction ActionInterval ActionEase EaseRateAction EaseElastic EaseBounce ActionInstant GridAction Grid3DAction TiledGrid3DAction Director SpriteFrameCache TransitionEaseScene Set SimpleAudioEngine FileUtils Application GLViewProtocol GLView ComponentContainer SAXParser Configuration EventListener BaseLight AsyncTaskPool ComponentJS
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

Some files were not shown because too many files have changed in this diff Show More