Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
bmanGH 2013-11-03 02:42:05 +08:00
commit 5137583fe2
654 changed files with 29861 additions and 22123 deletions

5
.gitignore vendored
View File

@ -22,10 +22,12 @@ Thumbs.db
*.log
[Bb]in
[Dd]ebug/
[Dd]ebug.win32/
*.sbr
*.sdf
obj/
[Rr]elease/
[Rr]elease.win32/
_ReSharper*/
[Tt]est[Rr]esult*
ipch/
@ -68,6 +70,9 @@ xcschememanagement.plist
xcuserdata/
DerivedData/
# Ignore files built by AppCode
.idea/
# Ignore files built by bada
.Simulator-Debug/
.Target-Debug/

14
AUTHORS
View File

@ -592,6 +592,8 @@ Developers:
Prevent nullptr access in AssetsManager
[Android] re-introduce Cocos2dxHelper.runOnGLThread(Runnable)
[Android] added EGL_RENDERABLE_TYPE to OpenGL attributes
Android: add xlargeScreens="true" to supports-screens
Trigger onKeyReleased only after the key has been released.
bmanGH
Use gl caching functions in TexturePVR::createGLTexture()
@ -627,6 +629,18 @@ Developers:
Fixed a bug that CCBReader can't play sequence automatically in JSB.
Could not set next animation in CCBAnimationCompleted callback.
lite3
Fixed a bug that Node's anchor point was changed after being added to ScrollView.
superrad
Clear NoSuchMethodError Exception when JniHelper fails to find methodID
Nite Luo (darkdukey)
Added Mouse Support For Desktop Platforms.
ledyba
Fixed a bug that EventListeners can't be removed sometimes.
Retired Core Developers:
WenSheng Yang
Author of windows port, CCTextField,

View File

@ -8,14 +8,23 @@ cocos2d-x-3.0alpha1 @??? 2013
[FIX] Avoid unnecessary object duplication for Scale9Sprite.
[FIX] create_project.py does not rename/replace template projects completely.
[FIX] Could not set next animation in CCBAnimationCompleted callback.
[FIX] The Node's anchor point was changed after being added to ScrollView.
[FIX] Refactored and improved EventDispatcher.
[NEW] Added Mouse Support For Desktop Platforms.
[FIX] EventListeners can't be removed sometimes.
[Android]
[FIX] Added EGL_RENDERABLE_TYPE to OpenGL attributes
[NEW] Added Cocos2dxHelper.runOnGLThread(Runnable) again
[FIX] Fixed application will crash when pause and resume.
[FIX] Clear NoSuchMethodError Exception when JniHelper fails to find method id
[NEW] Added xlargeScreens="true" to supports-screens
[NEW] Added build/android-build.py to build all Android samples
[Mac]
[FIX] Removed unused CCLOG() from GL initialization
[iOS]
[FIX] Can't click the area that outside of keyboard to close keyboard when using EditBox.
[Desktop]
[FIX] Trigger onKeyReleased only after the key has been released.
[Javascript binding]
[FIX] Fixed a memory leak in ScriptingCore::runScript()
[FIX] sys.localStorage.getItem() does not support non-ascii string.

View File

@ -23,14 +23,15 @@ How to start a new game
-----------------------
1. Download the code from [cocos2d download site][4]
2. Enter `tools/project-creator`
2. Run the `create-multi-platform-projects.py` script
2. Run the `create-projects.py` script
Example:
$ cd cocos2d-x
$ cd cocos2d-x/tools/project-creator
$ ./create-multi-platform-projects.py -p mygame -k com.your_company.mygame -l cpp
$ cd projects/mygame
$ cd ../../projects/mygame
Main features
@ -79,9 +80,6 @@ Runtime Requirements
* Android 2.3+ for Android games
* OS X v10.6+ for Mac games
* Windows 7+ for Win games
* Tizen 2.2+
* Emscripten
* Google Native Client
Running Tests
@ -92,28 +90,26 @@ Select the test you want from Xcode Scheme chooser.
* For OS X / iOS
```
$ cd cocos2d-x/samples
$ cd cocos2d-x/build
$ open samples.xcodeproj
```
* For Linux
```
$ cd cocos2d-x
$ cd cocos2d-x/build
$ ./make-all-linux-projects.sh
```
or open the `cocos2d-x/cocos2dx-qt5.pro` file using QT Creator 5.
* For Windows
Open the `cocos2d-x/cocos2d-win32.vc2012.sln`
Open the `cocos2d-x/build/cocos2d-win32.vc2012.sln`
* For Android
```
$ cd cocos2d-x/samples/Cpp/HelloCpp/proj.android
$ ./build_native.sh
$ cd cocos2d-x/build
$ python ./android-build.py hellocpp
```
Import HelloCpp Android project using Eclipse(released with Android SDK). The path to be imported is `cocos2d-x/samples/Cpp/HelloCpp/proj.android`.

212
build/android-build.py Executable file
View File

@ -0,0 +1,212 @@
#!/usr/bin/python
# android-build.py
# Build android samples
# You can use
# begin
import sys
import os, os.path
import shutil
from optparse import OptionParser
CPP_SAMPLES = ['hellocpp', 'testcpp', 'simplegame', 'assetsmanager']
LUA_SAMPLES = ['hellolua', 'testlua']
JSB_SAMPLES = ['cocosdragon', 'crystalcraze', 'moonwarriors', 'testjavascript', 'watermelonwithme']
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES
def usage():
print "%prog [-n ndk-build-parameter] target\n\
valid target are [hellocpp|testcpp|simplegame|assetsmanager|hellolua|testlua|cocosdragon\
|crystalcraze|moonwarriors|testjavascript|watermelonwithme], of course you can use 'cpp'\
to build all cpp samples, 'lua' to build all lua samples, 'jsb' to build all javascript samples,\
and 'all' for all samples"
def check_environment_variables():
''' Checking the environment NDK_ROOT, which will be used for building
'''
try:
NDK_ROOT = os.environ['NDK_ROOT']
except Exception:
print "NDK_ROOT not defined. Please define NDK_ROOT in your environment"
sys.exit(1)
return NDK_ROOT
def select_toolchain_version():
'''Because ndk-r8e uses gcc4.6 as default. gcc4.6 doesn't support c++11. So we should select gcc4.7 when
using ndk-r8e. But gcc4.7 is removed in ndk-r9, so we should determine whether gcc4.7 exist.
Conclution:
ndk-r8e -> use gcc4.7
ndk-r9 -> use gcc4.8
'''
ndk_root = check_environment_variables()
if os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.8")):
os.environ['NDK_TOOLCHAIN_VERSION'] = '4.8'
print "The Selected NDK toolchain version was 4.8 !"
elif os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.7")):
os.environ['NDK_TOOLCHAIN_VERSION'] = '4.7'
print "The Selected NDK toolchain version was 4.7 !"
else:
print "Couldn't find the gcc toolchain."
exit(1)
def caculate_built_samples(args):
''' Compute the sampels to be built
'cpp' for short of all cpp samples
'lua' for short of all lua smpleas
'jsb' for short of all javascript samples
'''
if 'all' in args:
return ALL_SAMPLES
targets = []
if 'cpp' in args:
targets += CPP_SAMPLES
args.remove('cpp')
if 'lua' in args:
targets += LUA_SAMPLES
args.remove('lua')
if 'jsb' in args:
targets += JSB_SAMPLES
args.remove('jsb')
targets += args
# remove duplicate elements, for example
# python android-build.py cpp hellocpp
targets = set(targets)
return list(targets)
def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param):
ndk_path = os.path.join(ndk_root, "ndk-build")
# windows should use ";" to seperate module paths
platform = sys.platform
if platform == 'win32':
ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root)
else:
ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)
if ndk_build_param == None:
command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path)
else:
command = '%s -C %s %s %s' % (ndk_path, app_android_root, ndk_build_param, ndk_module_path)
os.system(command)
def copy_files(src, dst):
for item in os.listdir(src):
path = os.path.join(src, item)
# Android can not package the file that ends with ".gz"
if not item.startswith('.') and not item.endswith('.gz') and os.path.isfile(path):
shutil.copy(path, dst)
if os.path.isdir(path):
new_dst = os.path.join(dst, item)
os.mkdir(new_dst)
copy_files(path, new_dst)
def copy_resources(target, app_android_root):
# remove app_android_root/assets if it exists
assets_dir = os.path.join(app_android_root, "assets")
if os.path.isdir(assets_dir):
shutil.rmtree(assets_dir)
# copy resources(cpp samples and lua samples)
os.mkdir(assets_dir)
resources_dir = os.path.join(app_android_root, "../Resources")
if os.path.isdir(resources_dir):
copy_files(resources_dir, assets_dir)
# jsb samples should copy javascript files and resources(shared with cocos2d-html5)
if target in JSB_SAMPLES:
resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/javascript/script")
copy_files(resources_dir, assets_dir)
if target == "cocosdragon":
resources_dir = os.path.join(app_android_root, "../../Shared/games/CocosDragonJS/Published files Android")
if target == "crystalcraze":
resources_dir = os.path.join(app_android_root, "../../Shared/games/CrystalCraze/Published-Android")
if target == "moonwarriors":
resources_dir = os.path.join(app_android_root, "../../Shared/games/MoonWarriors/res")
if target == "testjavascript":
resources_dir = os.path.join(app_android_root, "../../Shared/tests/")
if target == "watermelonwithme":
resources_dir = os.path.join(app_android_root, "../../Shared/games/WatermelonWithMe")
copy_files(resources_dir, assets_dir)
# AssetsManager test should also copy javascript files
if target == "assetsmanager":
resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/javascript/script")
copy_files(resources_dir, assets_dir)
# lua samples should copy lua script
if target in LUA_SAMPLES:
resources_dir = os.path.join(app_android_root, "../../../../cocos/scripting/lua/script")
copy_files(resources_dir, assets_dir)
# TestLua shared resources with TestCpp
if target == "testlua":
resources_dir = os.path.join(app_android_root, "../../../Cpp/TestCpp/Resources")
copy_files(resources_dir, assets_dir)
def build_samples(target,ndk_build_param):
ndk_root = check_environment_variables()
select_toolchain_version()
build_targets = caculate_built_samples(target)
current_dir = os.path.dirname(os.path.realpath(__file__))
cocos_root = os.path.join(current_dir, "..")
app_android_root = ''
for target in build_targets:
if target == 'hellocpp':
app_android_root = os.path.join(cocos_root, 'samples/Cpp/HelloCpp/proj.android')
elif target == 'testcpp':
app_android_root = os.path.join(cocos_root, 'samples/Cpp/TestCpp/proj.android')
elif target == 'simplegame':
app_android_root = os.path.join(cocos_root, 'samples/Cpp/SimpleGame/proj.android')
elif target == 'assetsmanager':
app_android_root = os.path.join(cocos_root, 'samples/Cpp/AssetsManagerTest/proj.android')
elif target == 'hellolua':
app_android_root = os.path.join(cocos_root, 'samples/Lua/HelloLua/proj.android')
elif target == 'testlua':
app_android_root = os.path.join(cocos_root, 'samples/Lua/TestLua/proj.android')
elif target == 'cocosdragon':
app_android_root = os.path.join(cocos_root, 'samples/JavaScript/CocosDragonJS/proj.android')
elif target == 'crystalcraze':
app_android_root = os.path.join(cocos_root, 'samples/JavaScript/CrystalCraze/proj.android')
elif target == 'moonwarriors':
app_android_root = os.path.join(cocos_root, 'samples/JavaScript/MoonWarriors/proj.android')
elif target == 'testjavascript':
app_android_root = os.path.join(cocos_root, 'samples/JavaScript/TestJavascript/proj.android')
elif target == 'watermelonwithme':
app_android_root = os.path.join(cocos_root, 'samples/JavaScript/WatermelonWithMe/proj.android')
else:
print 'unknown target: %s' % target
continue
copy_resources(target, app_android_root)
do_build(cocos_root, ndk_root, app_android_root, ndk_build_param)
# -------------- main --------------
if __name__ == '__main__':
#parse the params
parser = OptionParser()
parser.add_option("-n", "--ndk", dest="ndk_build_param", help='parameter for ndk-build')
(opts, args) = parser.parse_args()
if len(args) == 0:
usage()
else:
build_samples(args, opts.ndk_build_param)

View File

@ -1 +1 @@
1c487d29bdc2d80516e86e2ee93b1664e9f7df2f
8c640bf1e2f1cd0a489e6169c930234b809636f2

View File

@ -1 +1 @@
83265c81797ca614f19372a96adf326aeb21b396
b473303312be3b69891020b5fb470dd382f31284

View File

@ -39,6 +39,8 @@ CCEventAcceleration.cpp \
CCEventCustom.cpp \
CCEventDispatcher.cpp \
CCEventKeyboard.cpp \
CCEventMouse.cpp \
CCEventListenerMouse.cpp \
CCEventListener.cpp \
CCEventListenerAcceleration.cpp \
CCEventListenerCustom.cpp \

View File

@ -59,7 +59,8 @@ THE SOFTWARE.
#include "platform/CCImage.h"
#include "CCEGLView.h"
#include "CCConfiguration.h"
#include "CCEventDispatcher.h"
#include "CCFontFreeType.h"
/**
Position of the FPS
@ -143,6 +144,8 @@ bool Director::init(void)
_actionManager = new ActionManager();
_scheduler->scheduleUpdateForTarget(_actionManager, Scheduler::PRIORITY_SYSTEM, false);
_eventDispatcher = new EventDispatcher();
// create autorelease pool
PoolManager::sharedPoolManager()->push();
@ -162,6 +165,7 @@ Director::~Director(void)
CC_SAFE_RELEASE(_scenesStack);
CC_SAFE_RELEASE(_scheduler);
CC_SAFE_RELEASE(_actionManager);
CC_SAFE_RELEASE(_eventDispatcher);
// pop the autorelease pool
PoolManager::sharedPoolManager()->pop();
@ -229,8 +233,6 @@ void Director::setGLDefaultValues()
// Draw the Scene
void Director::drawScene()
{
Node::resetEventPriorityIndex();
// calculate "global" dt
calculateDeltaTime();
@ -685,6 +687,8 @@ void Director::purgeDirector()
// purge bitmap cache
LabelBMFont::purgeCachedData();
FontFreeType::shutdownFreeType();
// purge all managed caches
DrawPrimitives::free();
AnimationCache::destroyInstance();
@ -697,7 +701,6 @@ void Director::purgeDirector()
// cocos2d-x specific data structures
UserDefault::destroyInstance();
NotificationCenter::destroyInstance();
EventDispatcher::destroyInstance();
GL::invalidateStateCache();
@ -968,6 +971,21 @@ ActionManager* Director::getActionManager() const
return _actionManager;
}
EventDispatcher* Director::getEventDispatcher() const
{
return _eventDispatcher;
}
void Director::setEventDispatcher(EventDispatcher* dispatcher)
{
if (_eventDispatcher != dispatcher)
{
CC_SAFE_RETAIN(dispatcher);
CC_SAFE_RELEASE(_eventDispatcher);
_eventDispatcher = dispatcher;
}
}
/***************************************************
* implementation of DisplayLinkDirector
**************************************************/

View File

@ -53,10 +53,7 @@ class DirectorDelegate;
class Node;
class Scheduler;
class ActionManager;
class TouchDispatcher;
class KeyboardDispatcher;
class KeypadDispatcher;
class Accelerometer;
class EventDispatcher;
/**
@brief Class that creates and handles the main Window and manages how
@ -351,6 +348,17 @@ public:
@since v2.0
*/
void setActionManager(ActionManager* actionManager);
/** Gets the EventDispatcher associated with this director
@since v3.0
*/
EventDispatcher* getEventDispatcher() const;
/** Sets the EventDispatcher associated with this director
@since v3.0
*/
void setEventDispatcher(EventDispatcher* dispatcher);
/* Gets delta time since last tick to main loop */
float getDeltaTime() const;
@ -384,6 +392,11 @@ protected:
*/
ActionManager* _actionManager;
/** EventDispatcher associated with this director
@since v3.0
*/
EventDispatcher* _eventDispatcher;
/* delta time since last tick to main loop */
float _deltaTime;

View File

@ -26,7 +26,7 @@
NS_CC_BEGIN
Event::Event(const std::string& type)
Event::Event(Type type)
: _type(type)
, _isStopped(false)
, _currentTarget(nullptr)

View File

@ -40,15 +40,25 @@ class Node;
*/
class Event
{
public:
enum class Type
{
TOUCH,
KEYBOARD,
ACCELERATION,
MOUSE,
CUSTOM
};
protected:
/** Constructor */
Event(const std::string& type);
Event(Type type);
public:
/** Destructor */
virtual ~Event();
/** Gets the event type */
inline const std::string& getType() const { return _type; };
inline Type getType() const { return _type; };
/** Stops propagation for current event */
inline void stopPropagation() { _isStopped = true; };
@ -67,7 +77,8 @@ protected:
/** Sets current target */
inline void setCurrentTarget(Node* target) { _currentTarget = target; };
std::string _type; ///< Event type
Type _type; ///< Event type
bool _isStopped; ///< whether the event has been stopped.
Node* _currentTarget; ///< Current target

View File

@ -26,10 +26,8 @@
NS_CC_BEGIN
const char* EventAcceleration::EVENT_TYPE = "AccelerometerEvent";
EventAcceleration::EventAcceleration(Acceleration acc)
: Event(EVENT_TYPE)
: Event(Type::ACCELERATION)
, _acc(acc)
{
}

View File

@ -33,7 +33,6 @@ NS_CC_BEGIN
class EventAcceleration : public Event
{
public:
static const char* EVENT_TYPE;
EventAcceleration(Acceleration acc);

View File

@ -23,12 +23,15 @@
****************************************************************************/
#include "CCEventCustom.h"
#include "ccMacros.h"
#include <functional>
NS_CC_BEGIN
EventCustom::EventCustom(const std::string& eventName)
: Event(eventName)
: Event(Type::CUSTOM)
, _userData(nullptr)
, _eventName(eventName)
{
}

View File

@ -35,14 +35,17 @@ public:
/** Constructor */
EventCustom(const std::string& eventName);
/** Set user data */
/** Sets user data */
inline void setUserData(void* data) { _userData = data; };
/** Get user data */
/** Gets user data */
inline void* getUserData() const { return _userData; };
/** Gets event name */
inline const std::string& getEventName() const { return _eventName; };
protected:
void* _userData; ///< User data
std::string _eventName;
};
NS_CC_END

File diff suppressed because it is too large Load Diff

View File

@ -27,10 +27,11 @@
#include "CCPlatformMacros.h"
#include "CCEventListener.h"
#include "CCEvent.h"
#include <functional>
#include <string>
#include <map>
#include <unordered_map>
#include <list>
#include <vector>
@ -49,15 +50,9 @@ event listeners can be added and removed even
from within an EventListener, while events are being
dispatched.
*/
class EventDispatcher
class EventDispatcher : public Object
{
public:
/** Gets the singleton of EventDispatcher */
static EventDispatcher* getInstance();
/** Destroys the singleton of EventDispatcher */
static void destroyInstance();
/** Adds a event listener for a specified event with the priority of scene graph.
* @param listener The listener of a specified event.
* @param node The priority of the listener is based on the draw order of this node.
@ -79,11 +74,14 @@ public:
*/
void removeEventListener(EventListener* listener);
/** Removes all listeners with the same event type */
void removeListenersForEventType(const std::string& eventType);
/** Removes all listeners with the same event listener type */
void removeEventListeners(EventListener::Type listenerType);
/** Removes all custom listeners with the same event name */
void removeCustomEventListeners(const std::string& customEventName);
/** Removes all listeners */
void removeAllListeners();
void removeAllEventListeners();
/** Sets listener's priority with fixed value. */
void setPriority(EventListener* listener, int fixedPriority);
@ -98,59 +96,134 @@ public:
* Also removes all EventListeners marked for deletion from the
* event dispatcher list.
*/
void dispatchEvent(Event* event, bool forceSortListeners = false);
void dispatchEvent(Event* event);
void setDirtyForEventType(const std::string& eventType, bool isDirty);
bool isDirtyForEventType(const std::string& eventType);
public:
/** Constructor of EventDispatcher */
EventDispatcher();
/** Destructor of EventDispatcher */
~EventDispatcher();
private:
struct EventListenerItem
friend class Node;
/** Sets the dirty flag for a node. */
void setDirtyForNode(Node* node);
/** Notifys event dispatcher that the node has been paused. */
void pauseTarget(Node* node);
/** Notifys event dispatcher that the node has been resumed. */
void resumeTarget(Node* node);
/** Notifys event dispatcher that the node has been deleted. */
void cleanTarget(Node* node);
/**
* The vector to store event listeners with scene graph based priority and fixed priority.
*/
class EventListenerVector
{
int fixedPriority; // The higher the number, the higher the priority
Node* node; // Weak reference.
EventListener* listener;
~EventListenerItem();
public:
EventListenerVector();
~EventListenerVector();
size_t size() const;
bool empty() const;
void push_back(EventListener* item);
void clearSceneGraphListeners();
void clearFixedListeners();
void clear();
inline std::vector<EventListener*>* getFixedPriorityListeners() const { return _fixedListeners; };
inline std::vector<EventListener*>* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; };
inline int getGt0Index() const { return _gt0Index; };
inline void setGt0Index(int index) { _gt0Index = index; };
private:
std::vector<EventListener*>* _fixedListeners;
std::vector<EventListener*>* _sceneGraphListeners;
int _gt0Index;
};
/** Constructor of EventDispatcher */
EventDispatcher();
/** Adds event listener with item */
void addEventListenerWithItem(EventListenerItem* item);
void addEventListener(EventListener* listener);
/** Gets event the listener list for the event listener type. */
EventListenerVector* getListeners(EventListener::ListenerID listenerID);
/** Update dirty flag */
void updateDirtyFlagForSceneGraph();
/** Removes all listeners with the same event listener ID */
void removeEventListenersForListenerID(EventListener::ListenerID listenerID);
/** Sort event listener */
void sortEventListeners(EventListener::ListenerID listenerID);
/** Sorts the listeners of specified type by scene graph priority */
void sortEventListenersOfSceneGraphPriority(EventListener::ListenerID listenerID);
/** Sorts the listeners of specified type by fixed priority */
void sortEventListenersOfFixedPriority(EventListener::ListenerID listenerID);
/** Updates all listeners
* 1) Removes all listener items that have been marked as 'removed' when dispatching event.
* 2) Adds all listener items that have been marked as 'added' when dispatching event.
*/
void updateListeners(Event* event);
/** Touch event needs to be processed different with other events since it needs support ALL_AT_ONCE and ONE_BY_NONE mode. */
void dispatchTouchEvent(EventTouch* event);
/** Gets event the listener list for the event type. */
std::vector<EventListenerItem*>* getListenerItemsForType(const std::string& eventType);
/** Associates node with event listener */
void associateNodeAndEventListener(Node* node, EventListener* listener);
/** Sorts the listeners of specified type by priority */
void sortAllEventListenerItemsForType(const std::string& eventType);
/** Dissociates node with event listener */
void dissociateNodeAndEventListener(Node* node, EventListener* listener);
/** Updates all listener items
* 1) Removes all listener items that have been marked as 'removed' when dispatching event.
* 2) Adds all listener items that have been marked as 'added' when dispatching event.
*/
void updateListenerItems();
private:
/**
* Listeners map.
*/
std::map<std::string, std::vector<EventListenerItem*>*> _listeners;
/** Dispatches event to listeners with a specified listener type */
void dispatchEventToListeners(EventListenerVector* listeners, std::function<bool(EventListener*)> onEvent);
/// Priority dirty flag
std::map<std::string, bool> _priorityDirtyFlagMap;
enum class DirtyFlag
{
NONE = 0,
FIXED_PRITORY = 1 << 0,
SCENE_GRAPH_PRIORITY = 1 << 1,
ALL = FIXED_PRITORY | SCENE_GRAPH_PRIORITY
};
std::vector<EventListenerItem*> _toAddedListeners;
/** Sets the dirty flag for a specified listener ID */
void setDirty(EventListener::ListenerID listenerID, DirtyFlag flag);
int _inDispatch; ///< Whether it's in dispatching event
bool _isEnabled; ///< Whether to enable dispatching event
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */
void visitTarget(Node* node);
private:
/** Listeners map */
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listeners;
/** The map of dirty flag */
std::unordered_map<EventListener::ListenerID, DirtyFlag> _priorityDirtyFlagMap;
/** The map of node and event listeners */
std::unordered_map<Node*, std::vector<EventListener*>*> _nodeListenersMap;
/** The map of node and its event priority */
std::unordered_map<Node*, int> _nodePriorityMap;
/** The listeners to be added after dispatching event */
std::vector<EventListener*> _toAddedListeners;
/** The nodes were associated with scene graph based priority listeners */
std::set<Node*> _dirtyNodes;
/** Whether the dispatcher is dispatching event */
int _inDispatch;
/** Whether to enable dispatching event */
bool _isEnabled;
int _nodePriorityIndex;
};

View File

@ -27,6 +27,10 @@
NS_CC_BEGIN
const char* EventKeyboard::EVENT_TYPE = "KeyboardEvent";
EventKeyboard::EventKeyboard(KeyCode keyCode, bool isPressed)
: Event(Type::KEYBOARD)
, _keyCode(keyCode)
, _isPressed(isPressed)
{}
NS_CC_END

View File

@ -196,13 +196,7 @@ public:
KEY_SEARCH = 0xFFAA
};
static const char* EVENT_TYPE;
EventKeyboard(KeyCode keyCode, bool isPressed)
: Event(EVENT_TYPE)
, _keyCode(keyCode)
, _isPressed(isPressed)
{};
EventKeyboard(KeyCode keyCode, bool isPressed);
private:
KeyCode _keyCode;

View File

@ -35,16 +35,18 @@ EventListener::~EventListener()
CCLOGINFO("In the destructor of EventListener. %p", this);
}
bool EventListener::init(const std::string& t, std::function<void(Event*)> callback)
bool EventListener::init(Type t, ListenerID listenerID, std::function<void(Event*)> callback)
{
_onEvent = callback;
_type = t;
_listenerID = listenerID;
_isRegistered = false;
_paused = true;
return true;
}
bool EventListener::checkAvaiable()
bool EventListener::checkAvailable()
{
return (_onEvent != nullptr);
}

View File

@ -31,40 +31,78 @@
#include <functional>
#include <string>
#include <memory>
#include <set>
NS_CC_BEGIN
class Event;
class Node;
/**
* The base class of event listener.
* If you need custom listener which with different callback, you need to inherit this class.
* For instance, you could refer to AccelerationEventListener, KeyboardEventListener or TouchEventListener, CustomEventListener.
* For instance, you could refer to EventListenerAcceleration, EventListenerKeyboard, EventListenerTouchOneByOne, EventListenerCustom.
*/
class EventListener : public Object
{
public:
enum class Type
{
UNKNOWN,
TOUCH_ONE_BY_ONE,
TOUCH_ALL_AT_ONCE,
KEYBOARD,
MOUSE,
ACCELERATION,
CUSTOM
};
typedef int ListenerID;
protected:
/** Constructor */
EventListener();
/** Initializes event with type and callback function */
bool init(const std::string& t, std::function<void(Event*)>callback);
bool init(Type t, ListenerID listenerID, std::function<void(Event*)>callback);
public:
/** Destructor */
virtual ~EventListener();
/** Checks whether the listener is available. */
virtual bool checkAvaiable() = 0;
virtual bool checkAvailable() = 0;
/** Clones the listener, its subclasses have to override this method. */
virtual EventListener* clone() = 0;
protected:
inline void setPaused(bool paused) { _paused = paused; };
inline bool isPaused() const { return _paused; };
inline void setRegistered(bool registered) { _isRegistered = registered; };
inline bool isRegistered() const { return _isRegistered; };
inline Type getType() const { return _type; };
inline ListenerID getListenerID() const { return _listenerID; };
inline void setFixedPriority(int fixedPriority) { _fixedPriority = fixedPriority; };
inline int getFixedPriority() const { return _fixedPriority; };
inline void setSceneGraphPriority(Node* node) { _node = node; };
inline Node* getSceneGraphPriority() const { return _node; };
std::function<void(Event*)> _onEvent; /// Event callback function
std::string _type; /// Event type
bool _isRegistered; /// Whether the listener has been added to dispatcher.
Type _type; /// Event listener type
ListenerID _listenerID; /// Event listener ID
bool _isRegistered; /// Whether the listener has been added to dispatcher.
// The priority of event listener
int _fixedPriority; // The higher the number, the higher the priority, 0 is for scene graph base priority.
Node* _node; // scene graph based priority
bool _paused; // Whether the listener is paused
friend class EventDispatcher;
friend class Node;
};
NS_CC_END

View File

@ -37,7 +37,7 @@ EventListenerAcceleration::~EventListenerAcceleration()
CCLOGINFO("In the destructor of AccelerationEventListener. %p", this);
}
EventListenerAcceleration* EventListenerAcceleration::create(std::function<void(Acceleration*, Event* event)> callback)
EventListenerAcceleration* EventListenerAcceleration::create(std::function<void(Acceleration*, Event*)> callback)
{
EventListenerAcceleration* ret = new EventListenerAcceleration();
if (ret && ret->init(callback))
@ -59,7 +59,7 @@ bool EventListenerAcceleration::init(std::function<void(Acceleration*, Event* ev
this->onAccelerationEvent(&accEvent->_acc, event);
};
if (EventListener::init(EventAcceleration::EVENT_TYPE, listener))
if (EventListener::init(Type::ACCELERATION, static_cast<ListenerID>(Type::ACCELERATION), listener))
{
onAccelerationEvent = callback;
return true;
@ -84,7 +84,7 @@ EventListenerAcceleration* EventListenerAcceleration::clone()
return ret;
}
bool EventListenerAcceleration::checkAvaiable()
bool EventListenerAcceleration::checkAvailable()
{
CCASSERT(onAccelerationEvent, "");

View File

@ -33,12 +33,12 @@ NS_CC_BEGIN
class EventListenerAcceleration : public EventListener
{
public:
static EventListenerAcceleration* create(std::function<void(Acceleration*, Event* event)> callback);
static EventListenerAcceleration* create(std::function<void(Acceleration*, Event*)> callback);
virtual ~EventListenerAcceleration();
/// Overrides
virtual EventListenerAcceleration* clone() override;
virtual bool checkAvaiable() override;
virtual bool checkAvailable() override;
private:
EventListenerAcceleration();

View File

@ -35,7 +35,7 @@ EventListenerCustom::EventListenerCustom()
EventListenerCustom* EventListenerCustom::create(const std::string& eventName, std::function<void(EventCustom*)> callback)
{
EventListenerCustom* ret = new EventListenerCustom();
if (ret && ret->init(eventName, callback))
if (ret && ret->init(std::hash<std::string>()(eventName), callback))
{
ret->autorelease();
}
@ -46,7 +46,7 @@ EventListenerCustom* EventListenerCustom::create(const std::string& eventName, s
return ret;
}
bool EventListenerCustom::init(const std::string& eventName, std::function<void(EventCustom*)>callback)
bool EventListenerCustom::init(ListenerID listenerId, std::function<void(EventCustom*)>callback)
{
bool ret = false;
@ -59,7 +59,7 @@ bool EventListenerCustom::init(const std::string& eventName, std::function<void(
}
};
if (EventListener::init(eventName, listener))
if (EventListener::init(EventListener::Type::CUSTOM, listenerId, listener))
{
ret = true;
}
@ -69,7 +69,7 @@ bool EventListenerCustom::init(const std::string& eventName, std::function<void(
EventListenerCustom* EventListenerCustom::clone()
{
EventListenerCustom* ret = new EventListenerCustom();
if (ret && ret->init(_type, _onCustomEvent))
if (ret && ret->init(_listenerID, _onCustomEvent))
{
ret->autorelease();
}
@ -80,10 +80,10 @@ EventListenerCustom* EventListenerCustom::clone()
return ret;
}
bool EventListenerCustom::checkAvaiable()
bool EventListenerCustom::checkAvailable()
{
bool ret = false;
if (EventListener::checkAvaiable() && _onCustomEvent != nullptr)
if (EventListener::checkAvailable() && _onCustomEvent != nullptr)
{
ret = true;
}

View File

@ -33,21 +33,21 @@ class EventCustom;
/**
* Usage:
* auto dispatcher = EventDispatcher::getInstance();
* auto dispatcher = Director::getInstance()->getEventDispatcher();
* Adds a listener:
*
* auto callback = [](CustomEvent* event){ do_some_thing(); };
* auto listener = CustomEventListener::create(callback);
* auto callback = [](EventCustom* event){ do_some_thing(); };
* auto listener = EventListenerCustom::create(callback);
* dispatcher->addEventListenerWithSceneGraphPriority(listener, one_node);
*
* Dispatchs a custom event:
*
* Event event("your_event_type");
* EventCustom event("your_event_type");
* dispatcher->dispatchEvent(&event);
*
* Removes a listener
*
* dispatcher->removeListener(listener);
* dispatcher->removeEventListener(listener);
*/
class EventListenerCustom : public EventListener
{
@ -59,7 +59,7 @@ public:
static EventListenerCustom* create(const std::string& eventName, std::function<void(EventCustom*)> callback);
/// Overrides
virtual bool checkAvaiable() override;
virtual bool checkAvailable() override;
virtual EventListenerCustom* clone() override;
protected:
@ -67,7 +67,7 @@ protected:
EventListenerCustom();
/** Initializes event with type and callback function */
bool init(const std::string& eventName, std::function<void(EventCustom*)> callback);
bool init(ListenerID listenerId, std::function<void(EventCustom*)> callback);
std::function<void(EventCustom*)> _onCustomEvent;
};

View File

@ -29,7 +29,7 @@
NS_CC_BEGIN
bool EventListenerKeyboard::checkAvaiable()
bool EventListenerKeyboard::checkAvailable()
{
CCASSERT(onKeyPressed && onKeyReleased, "");
@ -88,7 +88,7 @@ bool EventListenerKeyboard::init()
}
};
if (EventListener::init(EventKeyboard::EVENT_TYPE, listener))
if (EventListener::init(Type::KEYBOARD, static_cast<ListenerID>(Type::KEYBOARD), listener))
{
return true;
}

View File

@ -40,10 +40,10 @@ public:
/// Overrides
virtual EventListenerKeyboard* clone() override;
virtual bool checkAvaiable() override;
virtual bool checkAvailable() override;
std::function<void(EventKeyboard::KeyCode, Event* event)> onKeyPressed;
std::function<void(EventKeyboard::KeyCode, Event* event)> onKeyReleased;
std::function<void(EventKeyboard::KeyCode, Event*)> onKeyPressed;
std::function<void(EventKeyboard::KeyCode, Event*)> onKeyReleased;
private:
EventListenerKeyboard();
bool init();

View File

@ -0,0 +1,110 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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 "CCEventListenerMouse.h"
NS_CC_BEGIN
bool EventListenerMouse::checkAvailable()
{
return true;
}
EventListenerMouse* EventListenerMouse::create()
{
auto ret = new EventListenerMouse();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
EventListenerMouse* EventListenerMouse::clone()
{
auto ret = new EventListenerMouse();
if (ret && ret->init())
{
ret->autorelease();
ret->onMouseUp = onMouseUp;
ret->onMouseDown = onMouseDown;
ret->onMouseMove = onMouseMove;
ret->onMouseScroll = onMouseScroll;
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
EventListenerMouse::EventListenerMouse()
: onMouseUp(nullptr)
, onMouseDown(nullptr)
, onMouseMove(nullptr)
, onMouseScroll(nullptr)
{
}
bool EventListenerMouse::init()
{
auto listener = [this](Event* event){
auto mouseEvent = static_cast<EventMouse*>(event);
switch (mouseEvent->_mouseEventType)
{
case EventMouse::MouseEventType::MOUSE_DOWN:
if(onMouseDown != nullptr)
onMouseDown(event);
break;
case EventMouse::MouseEventType::MOUSE_UP:
if(onMouseUp != nullptr)
onMouseUp(event);
break;
case EventMouse::MouseEventType::MOUSE_MOVE:
if(onMouseMove != nullptr)
onMouseMove(event);
break;
case EventMouse::MouseEventType::MOUSE_SCROLL:
if(onMouseScroll != nullptr)
onMouseScroll(event);
break;
default:
break;
}
};
if (EventListener::init(Type::MOUSE, static_cast<ListenerID>(Type::MOUSE), listener))
{
return true;
}
return false;
}
NS_CC_END

View File

@ -0,0 +1,57 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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 "CCEventListener.h"
#include "CCEventMouse.h"
#ifndef __cocos2d_libs__CCMouseEventListener__
#define __cocos2d_libs__CCMouseEventListener__
NS_CC_BEGIN
class Event;
class EventListenerMouse : public EventListener
{
public:
static EventListenerMouse* create();
/// Overrides
virtual EventListenerMouse* clone() override;
virtual bool checkAvailable() override;
std::function<void(Event* event)> onMouseDown;
std::function<void(Event* event)> onMouseUp;
std::function<void(Event* event)> onMouseMove;
std::function<void(Event* event)> onMouseScroll;
private:
EventListenerMouse();
bool init();
};
NS_CC_END
#endif /* defined(__cocos2d_libs__CCMouseEventListener__) */

View File

@ -30,46 +30,39 @@
NS_CC_BEGIN
EventListenerTouch::EventListenerTouch()
EventListenerTouchOneByOne::EventListenerTouchOneByOne()
: onTouchBegan(nullptr)
, onTouchMoved(nullptr)
, onTouchEnded(nullptr)
, onTouchCancelled(nullptr)
, onTouchesBegan(nullptr)
, onTouchesMoved(nullptr)
, onTouchesEnded(nullptr)
, onTouchesCancelled(nullptr)
, _needSwallow(false)
, _dispatchMode(Touch::DispatchMode::ALL_AT_ONCE)
{
}
EventListenerTouch::~EventListenerTouch()
EventListenerTouchOneByOne::~EventListenerTouchOneByOne()
{
CCLOGINFO("In the destructor of TouchEventListener, %p", this);
CCLOGINFO("In the destructor of EventListenerTouchOneByOne, %p", this);
}
bool EventListenerTouch::init(Touch::DispatchMode mode)
bool EventListenerTouchOneByOne::init()
{
if (EventListener::init(EventTouch::EVENT_TYPE, nullptr))
if (EventListener::init(Type::TOUCH_ONE_BY_ONE, static_cast<ListenerID>(Type::TOUCH_ONE_BY_ONE), nullptr))
{
_dispatchMode = mode;
return true;
}
return false;
}
void EventListenerTouch::setSwallowTouches(bool needSwallow)
void EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow)
{
CCASSERT(_dispatchMode == Touch::DispatchMode::ONE_BY_ONE, "Swallow touches only available in OneByOne mode.");
_needSwallow = needSwallow;
}
EventListenerTouch* EventListenerTouch::create(Touch::DispatchMode mode)
EventListenerTouchOneByOne* EventListenerTouchOneByOne::create()
{
auto ret = new EventListenerTouch();
if (ret && ret->init(mode))
auto ret = new EventListenerTouchOneByOne();
if (ret && ret->init())
{
ret->autorelease();
}
@ -80,38 +73,22 @@ EventListenerTouch* EventListenerTouch::create(Touch::DispatchMode mode)
return ret;
}
bool EventListenerTouch::checkAvaiable()
bool EventListenerTouchOneByOne::checkAvailable()
{
if (_dispatchMode == Touch::DispatchMode::ALL_AT_ONCE)
if (onTouchBegan == nullptr && onTouchMoved == nullptr
&& onTouchEnded == nullptr && onTouchCancelled == nullptr)
{
if (onTouchesBegan == nullptr && onTouchesMoved == nullptr
&& onTouchesEnded == nullptr && onTouchesCancelled == nullptr)
{
CCASSERT(false, "Invalid TouchEventListener.");
return false;
}
}
else if (_dispatchMode == Touch::DispatchMode::ONE_BY_ONE)
{
if (onTouchBegan == nullptr && onTouchMoved == nullptr
&& onTouchEnded == nullptr && onTouchCancelled == nullptr)
{
CCASSERT(false, "Invalid TouchEventListener.");
return false;
}
}
else
{
CCASSERT(false, "");
CCASSERT(false, "Invalid TouchEventListener.");
return false;
}
return true;
}
EventListenerTouch* EventListenerTouch::clone()
EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()
{
auto ret = new EventListenerTouch();
if (ret && ret->init(_dispatchMode))
auto ret = new EventListenerTouchOneByOne();
if (ret && ret->init())
{
ret->autorelease();
@ -119,13 +96,8 @@ EventListenerTouch* EventListenerTouch::clone()
ret->onTouchMoved = onTouchMoved;
ret->onTouchEnded = onTouchEnded;
ret->onTouchCancelled = onTouchCancelled;
ret->onTouchesBegan = onTouchesBegan;
ret->onTouchesMoved = onTouchesMoved;
ret->onTouchesEnded = onTouchesEnded;
ret->onTouchesCancelled = onTouchesCancelled;
ret->_claimedTouches = _claimedTouches;
ret->_dispatchMode = _dispatchMode;
ret->_needSwallow = _needSwallow;
}
else
@ -135,4 +107,73 @@ EventListenerTouch* EventListenerTouch::clone()
return ret;
}
/////////
EventListenerTouchAllAtOnce::EventListenerTouchAllAtOnce()
: onTouchesBegan(nullptr)
, onTouchesMoved(nullptr)
, onTouchesEnded(nullptr)
, onTouchesCancelled(nullptr)
{
}
EventListenerTouchAllAtOnce::~EventListenerTouchAllAtOnce()
{
CCLOGINFO("In the destructor of EventListenerTouchAllAtOnce, %p", this);
}
bool EventListenerTouchAllAtOnce::init()
{
if (EventListener::init(Type::TOUCH_ALL_AT_ONCE, static_cast<ListenerID>(Type::TOUCH_ALL_AT_ONCE), nullptr))
{
return true;
}
return false;
}
EventListenerTouchAllAtOnce* EventListenerTouchAllAtOnce::create()
{
auto ret = new EventListenerTouchAllAtOnce();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
bool EventListenerTouchAllAtOnce::checkAvailable()
{
if (onTouchesBegan == nullptr && onTouchesMoved == nullptr
&& onTouchesEnded == nullptr && onTouchesCancelled == nullptr)
{
CCASSERT(false, "Invalid TouchEventListener.");
return false;
}
return true;
}
EventListenerTouchAllAtOnce* EventListenerTouchAllAtOnce::clone()
{
auto ret = new EventListenerTouchAllAtOnce();
if (ret && ret->init())
{
ret->autorelease();
ret->onTouchesBegan = onTouchesBegan;
ret->onTouchesMoved = onTouchesMoved;
ret->onTouchesEnded = onTouchesEnded;
ret->onTouchesCancelled = onTouchesCancelled;
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
NS_CC_END

View File

@ -33,20 +33,19 @@
NS_CC_BEGIN
class EventListenerTouch : public EventListener
class EventListenerTouchOneByOne : public EventListener
{
public:
static EventListenerTouch* create(Touch::DispatchMode mode);
static EventListenerTouchOneByOne* create();
virtual ~EventListenerTouchOneByOne();
void setSwallowTouches(bool needSwallow);
/// Overrides
virtual EventListenerTouch* clone() override;
virtual bool checkAvaiable() override;
virtual ~EventListenerTouch();
private:
EventListenerTouch();
bool init(Touch::DispatchMode mode);
virtual EventListenerTouchOneByOne* clone() override;
virtual bool checkAvailable() override;
//
public:
std::function<bool(Touch*, Event*)> onTouchBegan;
@ -54,17 +53,39 @@ public:
std::function<void(Touch*, Event*)> onTouchEnded;
std::function<void(Touch*, Event*)> onTouchCancelled;
private:
EventListenerTouchOneByOne();
bool init();
std::vector<Touch*> _claimedTouches;
bool _needSwallow;
friend class EventDispatcher;
};
class EventListenerTouchAllAtOnce : public EventListener
{
public:
static const ListenerID ID = static_cast<ListenerID>(Type::TOUCH_ALL_AT_ONCE);
static EventListenerTouchAllAtOnce* create();
virtual ~EventListenerTouchAllAtOnce();
/// Overrides
virtual EventListenerTouchAllAtOnce* clone() override;
virtual bool checkAvailable() override;
//
public:
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesBegan;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesMoved;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesEnded;
std::function<void(const std::vector<Touch*>&, Event*)> onTouchesCancelled;
void setSwallowTouches(bool needSwallow);
private:
std::vector<Touch*> _claimedTouches;
bool _needSwallow;
Touch::DispatchMode _dispatchMode;
EventListenerTouchAllAtOnce();
bool init();
private:
friend class EventDispatcher;
};

41
cocos/2d/CCEventMouse.cpp Normal file
View File

@ -0,0 +1,41 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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 "CCEventMouse.h"
NS_CC_BEGIN
EventMouse::EventMouse(MouseEventType mouseEventCode)
: Event(Type::MOUSE)
, _mouseEventType(mouseEventCode)
, _mouseButton(0)
, _x(0.0f)
, _y(0.0f)
, _scrollX(0.0f)
, _scrollY(0.0f)
{
};
NS_CC_END

83
cocos/2d/CCEventMouse.h Normal file
View File

@ -0,0 +1,83 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __cocos2d_libs__CCMouseEvent__
#define __cocos2d_libs__CCMouseEvent__
#include "CCEvent.h"
#define MOUSE_BUTTON_LEFT 0
#define MOUSE_BUTTON_RIGHT 1
#define MOUSE_BUTTON_MIDDLE 2
#define MOUSE_BUTTON_4 3
#define MOUSE_BUTTON_5 4
#define MOUSE_BUTTON_6 5
#define MOUSE_BUTTON_7 6
#define MOUSE_BUTTON_8 7
NS_CC_BEGIN
class EventMouse : public Event
{
public:
/**
* Different types of MouseEvent
*/
enum class MouseEventType
{
MOUSE_NONE,
MOUSE_DOWN,
MOUSE_UP,
MOUSE_MOVE,
MOUSE_SCROLL,
};
EventMouse(MouseEventType mouseEventCode);
/** Set mouse scroll data */
inline void setScrollData(float scrollX, float scrollY) { _scrollX = scrollX; _scrollY = scrollY; };
inline float getScrollX() { return _scrollX; };
inline float getScrollY() { return _scrollY; };
inline void setCursorPosition(float x, float y) { _x = x; _y = y; };
inline void setMouseButton(int button) { _mouseButton = button; };
inline int getMouseButton() { return _mouseButton; };
inline float getCursorX() { return _x; };
inline float getCursorY() { return _y; };
private:
MouseEventType _mouseEventType;
int _mouseButton;
float _x;
float _y;
float _scrollX;
float _scrollY;
friend class EventListenerMouse;
};
NS_CC_END
#endif /* defined(__cocos2d_libs__CCMouseEvent__) */

View File

@ -26,6 +26,10 @@
NS_CC_BEGIN
const char* EventTouch::EVENT_TYPE = "TouchEvent";
EventTouch::EventTouch()
: Event(Type::TOUCH)
{
_touches.reserve(MAX_TOUCHES);
}
NS_CC_END

View File

@ -36,7 +36,6 @@ NS_CC_BEGIN
class EventTouch : public Event
{
public:
static const char* EVENT_TYPE;
static const int MAX_TOUCHES = 5;
enum class EventCode
@ -47,11 +46,7 @@ public:
CANCELLED
};
EventTouch()
: Event(EVENT_TYPE)
{
_touches.reserve(MAX_TOUCHES);
}
EventTouch();
EventCode getEventCode() { return _eventCode; };
std::vector<Touch*> getTouches() { return _touches; };

View File

@ -73,13 +73,15 @@ void Font::setCurrentGlyphCollection(GlyphCollection glyphs, const char *customG
break;
default:
if (customGlyphs)
{
int lenght = strlen(customGlyphs);
_customGlyphs = new char [lenght + 2];
memcpy(_customGlyphs, customGlyphs, lenght);
int lenght = strlen(customGlyphs);
_customGlyphs = new char [lenght + 2];
memcpy(_customGlyphs, customGlyphs, lenght);
_customGlyphs[lenght] = 0;
_customGlyphs[lenght+1] = 0;
_customGlyphs[lenght] = 0;
_customGlyphs[lenght+1] = 0;
}
break;
}

View File

@ -9,18 +9,41 @@
#include "cocos2d.h"
#include "CCFontAtlas.h"
#include "CCFont.h"
#include "CCFontFreeType.h"
NS_CC_BEGIN
FontAtlas::FontAtlas(Font &theFont) : _font(theFont)
FontAtlas::FontAtlas(Font &theFont) :
_font(&theFont),
_currentPageData(nullptr)
{
_font.retain();
_font->retain();
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
if (fontTTf && fontTTf->isDynamicGlyphCollection())
{
_currentPageLineHeight = _font->getFontMaxHeight();
_commonLineHeight = _currentPageLineHeight * 0.8f;
Texture2D * tex = new Texture2D;
_currentPage = 0;
_currentPageOrigX = 0;
_currentPageOrigY = 0;
_letterPadding = 5;
_currentPageDataSize = (1024 * 1024 * 4);
_currentPageData = new unsigned char[_currentPageDataSize];
memset(_currentPageData, 0, _currentPageDataSize);
addTexture(*tex,0);
tex->release();
}
}
FontAtlas::~FontAtlas()
{
_font.release();
_font->release();
relaseTextures();
delete []_currentPageData;
}
void FontAtlas::relaseTextures()
@ -51,6 +74,146 @@ bool FontAtlas::getLetterDefinitionForChar(unsigned short letteCharUTF16, FontL
}
}
bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
{
if(_currentPageData == nullptr)
return false;
FontFreeType* fontTTf = (FontFreeType*)_font;
std::vector<FontLetterDefinition> fontDefs;
int length = cc_wcslen(utf16String);
//find out new letter
for (int i = 0; i < length; ++i)
{
auto outIterator = _fontLetterDefinitions.find(utf16String[i]);
if (outIterator == _fontLetterDefinitions.end())
{
Rect tempRect;
FontLetterDefinition tempDef;
tempDef.offsetX = 0;
tempDef.anchorX = 0.0f;
tempDef.anchorY = 1.0f;
if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect))
{
tempDef.validDefinition = false;
tempDef.letteCharUTF16 = utf16String[i];
tempDef.commonLineHeight = 0;
tempDef.width = 0;
tempDef.height = 0;
tempDef.U = 0;
tempDef.V = 0;
tempDef.offsetY = 0;
tempDef.textureID = 0;
}
else
{
tempDef.validDefinition = true;
tempDef.letteCharUTF16 = utf16String[i];
tempDef.width = tempRect.size.width + _letterPadding;
tempDef.height = _currentPageLineHeight - 1;
tempDef.offsetY = tempRect.origin.y;
tempDef.commonLineHeight = _currentPageLineHeight;
}
fontDefs.push_back(tempDef);
}
}
float scaleFactor = CC_CONTENT_SCALE_FACTOR();
int newLetterCount = fontDefs.size();
float glyphWidth;
for (int i = 0; i < newLetterCount; ++i)
{
if (fontDefs[i].validDefinition)
{
_currentPageOrigX += _letterPadding;
glyphWidth = fontDefs[i].width - _letterPadding;
if (_currentPageOrigX + glyphWidth > 1024)
{
_currentPageOrigY += _currentPageLineHeight;
if(_currentPageOrigY >= 1024)
{
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, Texture2D::PixelFormat::RGBA8888, 1024, 1024, Size(1024, 1024) );
_currentPageOrigX = 0;
_currentPageOrigY = 0;
delete []_currentPageData;
_currentPageData = new unsigned char[_currentPageDataSize];
if(_currentPageData == nullptr)
return false;
memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++;
Texture2D* tex = new Texture2D;
addTexture(*tex,_currentPage);
tex->release();
}
}
renderCharAt(fontDefs[i].letteCharUTF16,_currentPageOrigX,_currentPageOrigY,_currentPageData,1024);
fontDefs[i].U = _currentPageOrigX - 1;
fontDefs[i].V = _currentPageOrigY;
fontDefs[i].textureID = _currentPage;
// take from pixels to points
fontDefs[i].width = fontDefs[i].width / scaleFactor;
fontDefs[i].height = fontDefs[i].height / scaleFactor;
fontDefs[i].U = fontDefs[i].U / scaleFactor;
fontDefs[i].V = fontDefs[i].V / scaleFactor;
}
else
glyphWidth = 0;
this->addLetterDefinition(fontDefs[i]);
_currentPageOrigX += glyphWidth;
}
if(newLetterCount > 0)
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, Texture2D::PixelFormat::RGBA8888, 1024, 1024, Size(1024, 1024) );
return true;
}
bool FontAtlas::renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize)
{
unsigned char *sourceBitmap = 0;
int sourceWidth = 0;
int sourceHeight = 0;
// get the glyph's bitmap
sourceBitmap = _font->getGlyphBitmap(charToRender, sourceWidth, sourceHeight);
if (!sourceBitmap)
return false;
int iX = posX;
int iY = posY;
for (int y = 0; y < sourceHeight; ++y)
{
int bitmap_y = y * sourceWidth;
for (int x = 0; x < sourceWidth; ++x)
{
unsigned char cTemp = sourceBitmap[bitmap_y + x];
// the final pixel
int iTemp = cTemp << 24 | cTemp << 16 | cTemp << 8 | cTemp;
*(int*) &destMemory[(iX + ( iY * destSize ) ) * 4] = iTemp;
iX += 1;
}
iX = posX;
iY += 1;
}
//everything good
return true;
}
void FontAtlas::addTexture(Texture2D &texture, int slot)
{
texture.retain();
@ -72,7 +235,7 @@ void FontAtlas::setCommonLineHeight(float newHeight)
_commonLineHeight = newHeight;
}
Font & FontAtlas::getFont() const
const Font * FontAtlas::getFont() const
{
return _font;
}

View File

@ -63,21 +63,32 @@ public:
void addLetterDefinition(const FontLetterDefinition &letterDefinition);
bool getLetterDefinitionForChar(unsigned short letteCharUTF16, FontLetterDefinition &outDefinition);
bool prepareLetterDefinitions(unsigned short *utf16String);
void addTexture(Texture2D &texture, int slot);
float getCommonLineHeight() const;
void setCommonLineHeight(float newHeight);
Texture2D & getTexture(int slot);
Font & getFont() const;
const Font * getFont() const;
private:
bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize);
void relaseTextures();
std::map<int, Texture2D *> _atlasTextures;
std::map<unsigned short, FontLetterDefinition> _fontLetterDefinitions;
float _commonLineHeight;
Font & _font;
Font * _font;
// Dynamic GlyphCollection related stuff
int _currentPage;
unsigned char *_currentPageData;
int _currentPageDataSize;
float _currentPageOrigX;
float _currentPageOrigY;
float _currentPageLineHeight;
float _letterPadding;
};

View File

@ -16,11 +16,6 @@ NS_CC_BEGIN
FontAtlas * FontAtlasFactory::createAtlasFromTTF(const char* fntFilePath, int fontSize, GlyphCollection glyphs, const char *customGlyphs)
{
if( glyphs == GlyphCollection::DYNAMIC )
{
log("ERROR: GlyphCollection::DYNAMIC is not supported yet!");
return nullptr;
}
Font *font = Font::createWithTTF(fntFilePath, fontSize, glyphs, customGlyphs);
if (font)
@ -34,9 +29,14 @@ FontAtlas * FontAtlasFactory::createAtlasFromFNT(const char* fntFilePath)
Font *font = Font::createWithFNT(fntFilePath);
if(font)
return font->createFontAtlas();
{
FontAtlas * atlas = font->createFontAtlas();
return atlas;
}
else
{
return nullptr;
}
}
NS_CC_END

View File

@ -49,6 +49,7 @@ FontDefinitionTTF* FontDefinitionTTF::create(Font *font, int textureSize)
if (ret->initDefinition(font, glyph, textureSize))
{
ret->autorelease();
return ret;
}
else

View File

@ -32,14 +32,13 @@ FontFNT * FontFNT::create(const char* fntFilePath)
delete newConf;
return nullptr;
}
tempFont->autorelease();
return tempFont;
}
FontFNT::~FontFNT()
{
if (_configuration)
_configuration->release();
}
Size * FontFNT::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const
@ -176,7 +175,7 @@ FontAtlas * FontFNT::createFontAtlas()
tempDefinition.anchorX = 0.5f;
tempDefinition.anchorY = 0.5f;
tempDefinition.validDefinition = true;
// add the new definition
tempAtlas->addLetterDefinition(tempDefinition);
}

View File

@ -1,28 +1,29 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
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:
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 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.
****************************************************************************/
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 <stdio.h>
#include <algorithm>
#include "ccUTF8.h"
#include "CCFontFreeType.h"
@ -38,13 +39,11 @@ bool FontFreeType::_FTInitialized = false;
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs)
{
if( glyphs == GlyphCollection::DYNAMIC )
{
log("ERROR: GlyphCollection::DYNAMIC is not supported yet!");
return nullptr;
}
bool dynamicGlyphCollection = false;
if(glyphs == GlyphCollection::DYNAMIC)
dynamicGlyphCollection = true;
FontFreeType *tempFont = new FontFreeType();
FontFreeType *tempFont = new FontFreeType(dynamicGlyphCollection);
if (!tempFont)
return nullptr;
@ -56,7 +55,6 @@ FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, G
delete tempFont;
return nullptr;
}
return tempFont;
}
@ -79,6 +77,7 @@ void FontFreeType::shutdownFreeType()
if (_FTInitialized == true)
{
FT_Done_FreeType(_FTlibrary);
_FTInitialized = false;
}
}
@ -88,25 +87,25 @@ FT_Library FontFreeType::getFTLibrary()
return _FTlibrary;
}
FontFreeType::FontFreeType() : _letterPadding(5)
FontFreeType::FontFreeType(bool dynamicGlyphCollection)
: _letterPadding(5),
_ttfData(nullptr),
_dynamicGlyphCollection(dynamicGlyphCollection),
_fontRef(nullptr)
{
}
bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
{
int dpi = 72;
int len = 0;
unsigned char* data = FileUtils::getInstance()->getFileData(fontName.c_str(), "rb", (unsigned long *)(&len));
if (!data)
return false;
// create the new face
FT_Face face;
int len = 0;
_ttfData = FileUtils::getInstance()->getFileData(fontName.c_str(), "rb", (unsigned long *)(&len));
if (!_ttfData)
return false;
// create the face from the data
if (FT_New_Memory_Face(getFTLibrary(), data, len, 0, &face ))
if (FT_New_Memory_Face(getFTLibrary(), _ttfData, len, 0, &face ))
return false;
//we want to use unicode
@ -114,8 +113,9 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
return false;
// set the requested font size
int fontSizePoints = (int)(64.f * fontSize);
if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi))
int dpi = 72;
int fontSizePoints = (int)(64.f * fontSize);
if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi))
return false;
// store the face globally
@ -130,22 +130,36 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
FontFreeType::~FontFreeType()
{
// release the font
// TO DO
if (_fontRef)
{
FT_Done_Face(_fontRef);
}
if (_ttfData)
{
delete _ttfData;
_ttfData = nullptr;
}
}
FontAtlas * FontFreeType::createFontAtlas()
{
FontDefinitionTTF *def = FontDefinitionTTF::create(this);
if (_dynamicGlyphCollection)
{
FontAtlas *atlas = new FontAtlas(*this);
this->release();
return atlas;
}
else
{
FontDefinitionTTF *def = FontDefinitionTTF::create(this);
if (!def)
return nullptr;
if (!def)
return nullptr;
FontAtlas *atlas = def->createFontAtlas();
FontAtlas *atlas = def->createFontAtlas();
// release the font definition, we don't need it anymore
def->release();
return atlas;
return atlas;
}
}
bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect) const

View File

@ -40,6 +40,8 @@ public:
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs);
static void shutdownFreeType();
virtual FontAtlas * createFontAtlas() override;
virtual Size * getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual GlyphDef * getGlyphDefintionsForText(const char *text, int &outNumGlyphs, bool UTF16text = false) const override;
@ -47,20 +49,21 @@ public:
virtual int getFontMaxHeight() const override;
virtual int getLetterPadding() const override;
bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const;
inline bool isDynamicGlyphCollection() { return _dynamicGlyphCollection;}
protected:
FontFreeType();
FontFreeType(bool dynamicGlyphCollection = false);
virtual ~FontFreeType();
bool createFontObject(const std::string &fontName, int fontSize);
private:
bool initFreeType();
void shutdownFreeType();
FT_Library getFTLibrary();
bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const;
int getAdvanceForChar(unsigned short theChar) const;
int getBearingXForChar(unsigned short theChar) const;
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
@ -70,7 +73,8 @@ private:
FT_Face _fontRef;
const int _letterPadding;
std::string _fontName;
unsigned char* _ttfData;
bool _dynamicGlyphCollection;
};
NS_CC_END

View File

@ -75,7 +75,7 @@ GLProgram::GLProgram()
, _vertShader(0)
, _fragShader(0)
, _hashForUniforms(NULL)
, _usesTime(false)
, _flags()
{
memset(_uniforms, 0, sizeof(_uniforms));
}
@ -223,27 +223,30 @@ void GLProgram::addAttribute(const char* attributeName, GLuint index)
void GLProgram::updateUniforms()
{
_uniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX);
_uniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_MV_MATRIX);
_uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_MVP_MATRIX);
_uniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX);
_uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX);
_uniforms[GLProgram::UNIFORM_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_TIME);
_uniforms[GLProgram::UNIFORM_SIN_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_SIN_TIME);
_uniforms[GLProgram::UNIFORM_COS_TIME] = glGetUniformLocation(_program, GLProgram::UNIFORM_NAME_COS_TIME);
_uniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME);
_uniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME);
_uniforms[UNIFORM_COS_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_COS_TIME);
_usesTime = (
_uniforms[GLProgram::UNIFORM_TIME] != -1 ||
_uniforms[GLProgram::UNIFORM_SIN_TIME] != -1 ||
_uniforms[GLProgram::UNIFORM_COS_TIME] != -1
);
_uniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01);
_uniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01);
_uniforms[UNIFORM_SAMPLER] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER);
_flags.usesMVP = _uniforms[UNIFORM_MVP_MATRIX] != -1;
_flags.usesMV = (_uniforms[UNIFORM_MV_MATRIX] != -1 && _uniforms[UNIFORM_P_MATRIX] != -1 );
_flags.usesTime = (
_uniforms[UNIFORM_TIME] != -1 ||
_uniforms[UNIFORM_SIN_TIME] != -1 ||
_uniforms[UNIFORM_COS_TIME] != -1
);
_flags.usesRandom = _uniforms[UNIFORM_RANDOM01] != -1;
this->use();
// Since sample most probably won't change, set it to 0 now.
this->setUniformLocationWith1i(_uniforms[GLProgram::UNIFORM_SAMPLER], 0);
this->setUniformLocationWith1i(_uniforms[UNIFORM_SAMPLER], 0);
}
bool GLProgram::link()
@ -545,19 +548,23 @@ void GLProgram::setUniformsForBuiltins()
{
kmMat4 matrixP;
kmMat4 matrixMV;
kmMat4 matrixMVP;
kmGLGetMatrix(KM_GL_PROJECTION, &matrixP);
kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV);
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1);
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1);
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1);
if(_flags.usesMVP) {
kmMat4 matrixMVP;
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1);
}
if(_usesTime)
{
if(_flags.usesMV) {
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1);
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1);
}
if(_flags.usesTime) {
Director *director = Director::getInstance();
// This doesn't give the most accurate global time value.
// Cocos2D doesn't store a high precision time value, so this will have to do.
@ -569,10 +576,8 @@ void GLProgram::setUniformsForBuiltins()
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_COS_TIME], time/8.0, time/4.0, time/2.0, cosf(time));
}
if (_uniforms[GLProgram::UNIFORM_RANDOM01] != -1)
{
if(_flags.usesRandom)
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
}
}
void GLProgram::reset()

View File

@ -250,7 +250,16 @@ private:
GLuint _fragShader;
GLint _uniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms;
bool _usesTime;
struct flag_struct {
unsigned int usesTime:1;
unsigned int usesMVP:1;
unsigned int usesMV:1;
unsigned int usesRandom:1;
// handy way to initialize the bitfield
flag_struct() { memset(this, 0, sizeof(*this)); }
} _flags;
};
// end of shaders group

View File

@ -46,8 +46,6 @@ Label* Label::createWithTTF( const char* label, const char* fontFilePath, int fo
}
return nullptr;
return 0;
}
Label* Label::createWithBMFont( const char* label, const char* bmfontFilePath, TextHAlignment alignment, int lineSize)
@ -95,8 +93,8 @@ Label* Label::createWithAtlas(FontAtlas *atlas, TextHAlignment alignment, int li
}
Label::Label(FontAtlas *atlas, TextHAlignment alignment)
: _currentUTF8String(0)
, _originalUTF8String(0)
: _currentUTF16String(0)
, _originalUTF16String(0)
, _fontAtlas(atlas)
, _alignment(alignment)
, _lineBreakWithoutSpaces(false)
@ -107,32 +105,32 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment)
, _cascadeOpacityEnabled(true)
, _displayedOpacity(255)
, _realOpacity(255)
, _isOpacityModifyRGB(false)
, _isOpacityModifyRGB(true)
,_reusedLetter(nullptr)
{
}
Label::~Label()
{
CC_SAFE_RELEASE(_spriteArray);
CC_SAFE_RELEASE(_spriteArrayCache);
if (_currentUTF8String)
delete [] _currentUTF8String;
if (_advances)
delete [] _advances;
delete [] _currentUTF16String;
delete [] _originalUTF16String;
delete [] _advances;
if (_fontAtlas)
FontAtlasCache::releaseFontAtlas(_fontAtlas);
delete _reusedLetter;
}
bool Label::init()
{
_spriteArray = Array::createWithCapacity(30);
_spriteArrayCache = Array::createWithCapacity(30);
_spriteArray->retain();
_spriteArrayCache->retain();
if(_fontAtlas)
{
_reusedLetter = new Sprite;
_reusedLetter->initWithTexture(&_fontAtlas->getTexture(0));
_reusedLetter->setOpacityModifyRGB(_isOpacityModifyRGB);
return SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), 30);
}
return true;
}
@ -151,14 +149,10 @@ bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment
// reset the string
resetCurrentString();
_width = lineWidth;
_alignment = alignment;
_lineBreakWithoutSpaces = lineBreakWithoutSpaces;
// release all the sprites
moveAllSpritesToCache();
// store locally common line height
_commonLineHeight = _fontAtlas->getCommonLineHeight();
if (_commonLineHeight <= 0)
@ -169,11 +163,8 @@ bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment
if(!utf16String)
return false;
numLetter = cc_wcslen(utf16String);
SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), numLetter);
_cascadeColorEnabled = true;
//
setCurrentString(utf16String);
setOriginalString(utf16String);
@ -248,29 +239,54 @@ void Label::setScaleY(float scaleY)
void Label::alignText()
{
hideAllLetters();
if(_textureAtlas)
_textureAtlas->removeAllQuads();
_fontAtlas->prepareLetterDefinitions(_currentUTF16String);
LabelTextFormatter::createStringSprites(this);
if( LabelTextFormatter::multilineText(this) )
{
hideAllLetters();
LabelTextFormatter::createStringSprites(this);
}
LabelTextFormatter::alignText(this);
}
void Label::hideAllLetters()
{
Object* Obj = NULL;
CCARRAY_FOREACH(_spriteArray, Obj)
int strLen = cc_wcslen(_currentUTF16String);
if (_children && _children->count() != 0)
{
((Sprite *)Obj)->setVisible(false);
for (auto child: *_children)
{
Node* pNode = static_cast<Node*>( child );
if (pNode)
{
int tag = pNode->getTag();
if(tag < 0 || tag >= strLen)
SpriteBatchNode::removeChild(pNode, true);
}
}
}
_reusedLetter->setBatchNode(nullptr);
CCARRAY_FOREACH(_spriteArrayCache, Obj)
int vaildIndex = 0;
Sprite* child = nullptr;
Rect uvRect;
for (int ctr = 0; ctr < strLen; ++ctr)
{
((Sprite *)Obj)->setVisible(false);
if (_lettersInfo[ctr].def.validDefinition)
{
child = static_cast<Sprite*>( this->getChildByTag(ctr) );
if (child)
{
uvRect.size.height = _lettersInfo[ctr].def.height;
uvRect.size.width = _lettersInfo[ctr].def.width;
uvRect.origin.x = _lettersInfo[ctr].def.U;
uvRect.origin.y = _lettersInfo[ctr].def.V;
child->setTexture(&_fontAtlas->getTexture(_lettersInfo[ctr].def.textureID));
child->setTextureRect(uvRect);
}
updateSpriteWithLetterDefinition(_reusedLetter,_lettersInfo[ctr].def,&_fontAtlas->getTexture(_lettersInfo[ctr].def.textureID));
_reusedLetter->setPosition(_lettersInfo[ctr].position);
insertQuadFromSprite(_reusedLetter,vaildIndex++);
}
}
}
@ -282,10 +298,8 @@ bool Label::computeAdvancesForString(unsigned short int *stringToRender)
_advances = 0;
}
Font &theFont = _fontAtlas->getFont();
int letterCount = 0;
_advances = theFont.getAdvancesForTextUTF16(stringToRender, letterCount);
_advances = _fontAtlas->getFont()->getAdvancesForTextUTF16(stringToRender, letterCount);
if(!_advances)
return false;
@ -295,17 +309,17 @@ bool Label::computeAdvancesForString(unsigned short int *stringToRender)
bool Label::setOriginalString(unsigned short *stringToSet)
{
if (_originalUTF8String)
if (_originalUTF16String)
{
delete [] _originalUTF8String;
_originalUTF8String = 0;
delete [] _originalUTF16String;
_originalUTF16String = 0;
}
int newStringLenght = cc_wcslen(stringToSet);
_originalUTF8String = new unsigned short int [newStringLenght + 1];
memset(_originalUTF8String, 0, (newStringLenght + 1) * 2);
memcpy(_originalUTF8String, stringToSet, (newStringLenght * 2));
_originalUTF8String[newStringLenght] = 0;
_originalUTF16String = new unsigned short int [newStringLenght + 1];
memset(_originalUTF16String, 0, (newStringLenght + 1) * 2);
memcpy(_originalUTF16String, stringToSet, (newStringLenght * 2));
_originalUTF16String[newStringLenght] = 0;
return true;
}
@ -313,65 +327,36 @@ bool Label::setOriginalString(unsigned short *stringToSet)
bool Label::setCurrentString(unsigned short *stringToSet)
{
// set the new string
if (_currentUTF8String)
if (_currentUTF16String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
delete [] _currentUTF16String;
_currentUTF16String = 0;
}
//
_currentUTF8String = stringToSet;
_currentUTF16String = stringToSet;
// compute the advances
return computeAdvancesForString(stringToSet);
}
void Label::resetCurrentString()
{
if ((!_currentUTF8String) && (!_originalUTF8String))
if ((!_currentUTF16String) && (!_originalUTF16String))
return;
// set the new string
if (_currentUTF8String)
if (_currentUTF16String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
delete [] _currentUTF16String;
_currentUTF16String = 0;
}
int stringLenght = cc_wcslen(_originalUTF8String);
_currentUTF8String = new unsigned short int [stringLenght + 1];
memcpy(_currentUTF8String, _originalUTF8String, stringLenght * 2);
_currentUTF8String[stringLenght] = 0;
int stringLenght = cc_wcslen(_originalUTF16String);
_currentUTF16String = new unsigned short int [stringLenght + 1];
memcpy(_currentUTF16String, _originalUTF16String, stringLenght * 2);
_currentUTF16String[stringLenght] = 0;
}
Sprite * Label::createNewSpriteFromLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
Rect uvRect;
uvRect.size.height = theDefinition.height;
uvRect.size.width = theDefinition.width;
uvRect.origin.x = theDefinition.U;
uvRect.origin.y = theDefinition.V;
SpriteFrame *pFrame = SpriteFrame::createWithTexture(theTexture, uvRect);
Sprite *tempSprite = getSprite();
if (!tempSprite)
return 0;
tempSprite->initWithSpriteFrame(pFrame);
tempSprite->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
tempSprite->setBatchNode(this);
// Apply label properties
tempSprite->setOpacityModifyRGB(_isOpacityModifyRGB);
// Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on
tempSprite->updateDisplayedColor(_displayedColor);
tempSprite->updateDisplayedOpacity(_displayedOpacity);
return tempSprite;
}
Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
if (!spriteToUpdate)
@ -389,143 +374,93 @@ Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const F
SpriteFrame *frame = SpriteFrame::createWithTexture(theTexture, uvRect);
if (frame)
{
spriteToUpdate->setBatchNode(this);
spriteToUpdate->setTexture(theTexture);
spriteToUpdate->setDisplayFrame(frame);
spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
spriteToUpdate->setBatchNode(this);
}
return spriteToUpdate;
}
}
Sprite * Label::getSpriteForLetter(unsigned short int newLetter)
bool Label::recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex)
{
if (!_fontAtlas)
return 0;
if (spriteIndex >= _lettersInfo.size())
{
LetterInfo tmpInfo;
_lettersInfo.push_back(tmpInfo);
}
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *newSprite = createNewSpriteFromLetterDefinition(tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
this->addChild(newSprite);
return newSprite;
}
else
{
return 0;
}
_fontAtlas->getLetterDefinitionForChar(theChar, _lettersInfo[spriteIndex].def);
_lettersInfo[spriteIndex].position = point;
_lettersInfo[spriteIndex].contentSize.width = _lettersInfo[spriteIndex].def.width;
_lettersInfo[spriteIndex].contentSize.height = _lettersInfo[spriteIndex].def.height;
return _lettersInfo[spriteIndex].def.validDefinition;
}
Sprite * Label::updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter)
bool Label::recordPlaceholderInfo(int spriteIndex)
{
if (!spriteToUpdate || !_fontAtlas)
return 0;
else
if (spriteIndex >= _lettersInfo.size())
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *pNewSprite = updateSpriteWithLetterDefinition(spriteToUpdate, tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
return pNewSprite;
}
else
{
return 0;
}
LetterInfo tmpInfo;
_lettersInfo.push_back(tmpInfo);
}
_lettersInfo[spriteIndex].def.validDefinition = false;
return false;
}
void Label::moveAllSpritesToCache()
void Label::addChild(Node * child, int zOrder/* =0 */, int tag/* =0 */)
{
Object* pObj = NULL;
CCARRAY_FOREACH(_spriteArray, pObj)
{
((Sprite *)pObj)->removeFromParent();
_spriteArrayCache->addObject(pObj);
}
_spriteArray->removeAllObjects();
}
Sprite * Label::getSprite()
{
if (_spriteArrayCache->count())
{
Sprite *retSprite = static_cast<Sprite *>(_spriteArrayCache->getLastObject());
_spriteArrayCache->removeLastObject();
return retSprite;
}
else
{
Sprite *retSprite = new Sprite;
return retSprite;
}
CCASSERT(0, "addChild: is not supported on Label.");
}
///// PROTOCOL STUFF
Sprite * Label::getSpriteChild(int ID) const
Sprite * Label::getLetter(int ID)
{
Object* pObj = NULL;
CCARRAY_FOREACH(_spriteArray, pObj)
if (ID < getStringLenght())
{
Sprite *pSprite = (Sprite *)pObj;
if ( pSprite->getTag() == ID)
if(_lettersInfo[ID].def.validDefinition == false)
return nullptr;
Sprite* sp = static_cast<Sprite*>(this->getChildByTag(ID));
if (!sp)
{
return pSprite;
Rect uvRect;
uvRect.size.height = _lettersInfo[ID].def.height;
uvRect.size.width = _lettersInfo[ID].def.width;
uvRect.origin.x = _lettersInfo[ID].def.U;
uvRect.origin.y = _lettersInfo[ID].def.V;
sp = new Sprite();
sp->initWithTexture(&_fontAtlas->getTexture(_lettersInfo[ID].def.textureID),uvRect);
sp->setBatchNode(this);
sp->setAnchorPoint(Point(_lettersInfo[ID].def.anchorX, _lettersInfo[ID].def.anchorY));
sp->setPosition(_lettersInfo[ID].position);
sp->setOpacity(_realOpacity);
this->addSpriteWithoutQuad(sp, ID, ID);
sp->release();
}
}
return 0;
}
Array* Label::getChildrenLetters() const
{
return _spriteArray;
}
Sprite * Label::getSpriteForChar(unsigned short int theChar, int spriteIndexHint)
{
// ret sprite
Sprite *retSprite = 0;
// look for already existing sprites
retSprite = getSpriteChild(spriteIndexHint);
if (!retSprite)
{
retSprite = getSpriteForLetter(theChar);
if (!retSprite)
return 0;
if (retSprite)
retSprite->setTag(spriteIndexHint);
_spriteArray->addObject(retSprite);
return sp;
}
// the sprite is now visible
retSprite->setVisible(true);
// set the right texture letter to the sprite
updateSpriteForLetter(retSprite, theChar);
// we are done here
return retSprite;
return nullptr;
}
float Label::getLetterPosXLeft( Sprite* sp ) const
float Label::getLetterPosXLeft( int index ) const
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX - (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
return _lettersInfo[index].position.x * _scaleX - (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX);
}
float Label::getLetterPosXRight( Sprite* sp ) const
float Label::getLetterPosXRight( int index ) const
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX + (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
return _lettersInfo[index].position.x * _scaleX + (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX);
}
int Label::getCommonLineHeight() const
@ -578,7 +513,7 @@ int Label::getAdvanceForChar(unsigned short c, int hintPositionInString) const
Rect Label::getRectForChar(unsigned short c) const
{
return _fontAtlas->getFont().getRectForChar(c);
return _fontAtlas->getFont()->getRectForChar(c);
}
// string related stuff
@ -586,14 +521,14 @@ int Label::getStringNumLines() const
{
int quantityOfLines = 1;
unsigned int stringLen = _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0;
if (stringLen == 0)
return (-1);
// count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i)
{
unsigned short c = _currentUTF8String[i];
unsigned short c = _currentUTF16String[i];
if (c == '\n')
{
quantityOfLines++;
@ -605,17 +540,17 @@ int Label::getStringNumLines() const
int Label::getStringLenght() const
{
return _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
return _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0;
}
unsigned short Label::getCharAtStringPosition(int position) const
{
return _currentUTF8String[position];
return _currentUTF16String[position];
}
unsigned short * Label::getUTF8String() const
{
return _currentUTF8String;
return _currentUTF16String;
}
void Label::assignNewUTF8String(unsigned short *newString)
@ -663,8 +598,7 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
_isOpacityModifyRGB = isOpacityModifyRGB;
if (_children && _children->count() != 0)
{
Object* child;
CCARRAY_FOREACH(_children, child)
for (auto child: *_children)
{
Node* pNode = static_cast<Node*>( child );
if (pNode)
@ -677,6 +611,7 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
}
}
}
_reusedLetter->setOpacityModifyRGB(true);
}
unsigned char Label::getOpacity() const
@ -692,7 +627,7 @@ unsigned char Label::getDisplayedOpacity() const
void Label::setOpacity(GLubyte opacity)
{
_displayedOpacity = _realOpacity = opacity;
_reusedLetter->setOpacity(opacity);
if( _cascadeOpacityEnabled ) {
GLubyte parentOpacity = 255;
RGBAProtocol* pParent = dynamic_cast<RGBAProtocol*>(_parent);
@ -707,12 +642,28 @@ void Label::updateDisplayedOpacity(GLubyte parentOpacity)
{
_displayedOpacity = _realOpacity * parentOpacity/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
for (auto child: *_children)
{
Sprite *item = static_cast<Sprite*>( pObj );
Sprite *item = static_cast<Sprite*>( child );
item->updateDisplayedOpacity(_displayedOpacity);
}
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
int count = _textureAtlas->getTotalQuads();
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
if (_isOpacityModifyRGB)
{
color4.r *= _displayedOpacity/255.0f;
color4.g *= _displayedOpacity/255.0f;
color4.b *= _displayedOpacity/255.0f;
}
for (int index = 0; index < count; ++index)
{
quads[index].bl.colors = color4;
quads[index].br.colors = color4;
quads[index].tl.colors = color4;
quads[index].tr.colors = color4;
_textureAtlas->updateQuad(&quads[index], index);
}
}
bool Label::isCascadeOpacityEnabled() const
@ -738,7 +689,7 @@ const Color3B& Label::getDisplayedColor() const
void Label::setColor(const Color3B& color)
{
_displayedColor = _realColor = color;
_reusedLetter->setColor(color);
if( _cascadeColorEnabled )
{
Color3B parentColor = Color3B::WHITE;
@ -757,12 +708,31 @@ void Label::updateDisplayedColor(const Color3B& parentColor)
_displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
for (auto child: *_children)
{
Sprite *item = static_cast<Sprite*>( pObj );
Sprite *item = static_cast<Sprite*>( child );
item->updateDisplayedColor(_displayedColor);
}
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
int count = _textureAtlas->getTotalQuads();
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
// special opacity for premultiplied textures
if (_isOpacityModifyRGB)
{
color4.r *= _displayedOpacity/255.0f;
color4.g *= _displayedOpacity/255.0f;
color4.b *= _displayedOpacity/255.0f;
}
for (int index=0; index<count; ++index)
{
quads[index].bl.colors = color4;
quads[index].br.colors = color4;
quads[index].tl.colors = color4;
quads[index].tr.colors = color4;
_textureAtlas->updateQuad(&quads[index], index);
}
}
bool Label::isCascadeColorEnabled() const

View File

@ -82,12 +82,13 @@ public:
virtual unsigned char getDisplayedOpacity() const override;
// CCLabelTextFormat protocol implementation
virtual Sprite * getSpriteChild(int ID) const override;
virtual Array * getChildrenLetters() const override;
virtual Sprite * getSpriteForChar(unsigned short int theChar, int spriteIndexHint) override;
virtual float getLetterPosXLeft( Sprite* sp ) const override;
virtual float getLetterPosXRight( Sprite* sp ) const override;
virtual std::vector<LetterInfo> *getLettersInfo() override { return &_lettersInfo; };
virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex) override;
virtual bool recordPlaceholderInfo(int spriteIndex) override;
virtual float getLetterPosXLeft( int index ) const override;
virtual float getLetterPosXRight( int index ) const override;
virtual Sprite * getLetter(int ID) override;
// font related stuff
virtual int getCommonLineHeight() const override;
@ -113,6 +114,7 @@ public:
// carloX
const char * getString() const { return "not implemented"; }
void addChild(Node * child, int zOrder=0, int tag=0);
private:
/**
@ -130,28 +132,25 @@ private:
bool init();
void alignText();
void hideAllLetters();
void moveAllSpritesToCache();
bool computeAdvancesForString(unsigned short int *stringToRender);
bool setCurrentString(unsigned short *stringToSet);
bool setOriginalString(unsigned short *stringToSet);
void resetCurrentString();
Sprite * getSprite();
Sprite * createNewSpriteFromLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * getSpriteForLetter(unsigned short int newLetter);
Sprite * updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter);
Array * _spriteArray;
Array * _spriteArrayCache;
//! used for optimization
Sprite *_reusedLetter;
std::vector<LetterInfo> _lettersInfo;
float _commonLineHeight;
bool _lineBreakWithoutSpaces;
float _width;
TextHAlignment _alignment;
unsigned short int * _currentUTF8String;
unsigned short int * _originalUTF8String;
unsigned short int * _currentUTF16String;
unsigned short int * _originalUTF16String;
Size * _advances;
FontAtlas * _fontAtlas;
Color3B _displayedColor;

View File

@ -24,19 +24,31 @@
#ifndef _CCLabelTextFormatProtocol_h_
#define _CCLabelTextFormatProtocol_h_
#include "CCFontAtlas.h"
#include <vector>
NS_CC_BEGIN
struct LetterInfo
{
FontLetterDefinition def;
Point position;
Size contentSize;
bool visible;
};
class CC_DLL LabelTextFormatProtocol
{
public:
virtual bool recordLetterInfo(const cocos2d::Point& point,unsigned short int theChar, int spriteIndex) = 0;
virtual bool recordPlaceholderInfo(int spriteIndex) = 0;
virtual std::vector<LetterInfo> *getLettersInfo() = 0;
virtual float getLetterPosXLeft(int index) const = 0;
virtual float getLetterPosXRight(int index) const = 0;
// sprite related stuff
virtual cocos2d::Sprite *getSpriteChild(int ID) const = 0;
virtual cocos2d::Array *getChildrenLetters() const = 0;
virtual cocos2d::Sprite *getSpriteForChar(unsigned short int theChar, int spriteIndexHint) = 0;
virtual float getLetterPosXLeft(cocos2d::Sprite* sp) const = 0;
virtual float getLetterPosXRight(cocos2d::Sprite* sp) const = 0;
virtual cocos2d::Sprite *getLetter(int ID) = 0;
// font related stuff
virtual int getCommonLineHeight() const = 0;

View File

@ -54,22 +54,23 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
int skip = 0;
Array* children = theLabel->getChildrenLetters();
int strLen = theLabel->getStringLenght();
std::vector<LetterInfo> *leterInfo = theLabel->getLettersInfo();
int tIndex = 0;
for (int j = 0; j < children->count(); j++)
for (int j = 0; j < strLen; j++)
{
Sprite* characterSprite;
LetterInfo* info = &leterInfo->at(j+skip);
unsigned int justSkipped = 0;
while (!(characterSprite = theLabel->getSpriteChild(j + skip + justSkipped)))
while (info->def.validDefinition == false)
{
justSkipped++;
info = &leterInfo->at( j+skip+justSkipped );
}
skip += justSkipped;
if (!characterSprite->isVisible())
continue;
tIndex = j + skip;
if (i >= stringLength)
break;
@ -78,7 +79,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
if (!isStartOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( characterSprite );
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
@ -110,7 +111,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
if (!startOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( characterSprite );
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!startOfLine)
@ -133,7 +134,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
}
// Out of bounds.
if (theLabel->getLetterPosXRight( characterSprite ) - startOfLine > theLabel->getMaxLineWidth())
if (theLabel->getLetterPosXRight( tIndex ) - startOfLine > theLabel->getMaxLineWidth())
{
if (!theLabel->breakLineWithoutSpace())
{
@ -171,7 +172,7 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
if (!startOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( characterSprite );
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!startOfLine)
@ -222,6 +223,7 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel)
int lineNumber = 0;
int strLen = cc_wcslen(theLabel->getUTF8String());
vector<unsigned short> lastLine;
std::vector<LetterInfo> *leterInfo = theLabel->getLettersInfo();
for (int ctr = 0; ctr <= strLen; ++ctr)
{
unsigned short int currentChar = theLabel->getCharAtStringPosition(ctr);
@ -240,11 +242,12 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel)
int index = i + lineLength - 1 + lineNumber;
if (index < 0) continue;
Sprite* lastChar = theLabel->getSpriteChild(index);
if (lastChar == nullptr)
if(currentChar == 0)
continue;
lineWidth = lastChar->getPosition().x + lastChar->getContentSize().width / 2.0f;
LetterInfo* info = &leterInfo->at( index );
if(info->def.validDefinition == false)
continue;
lineWidth = info->position.x + info->contentSize.width /2.0f;
float shift = 0;
switch (theLabel->getTextAlignment())
@ -266,10 +269,11 @@ bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel)
index = i + j + lineNumber;
if (index < 0) continue;
Sprite* characterSprite = theLabel->getSpriteChild(index);
if (characterSprite)
characterSprite->setPosition( characterSprite->getPosition() + Point(shift, 0.0f));
info = &leterInfo->at( index );
if(info)
{
info->position = info->position + Point(shift, 0.0f);
}
}
}
@ -336,15 +340,8 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel)
{
nextFontPositionX = 0;
nextFontPositionY -= commonLineHeight;
continue;
}
// get the sprite to this letter
Sprite *letterSprite = theLabel->getSpriteForChar(c, i);
if (!letterSprite)
{
log("WARNING: can't find letter definition in font file for letter: %c", c);
theLabel->recordPlaceholderInfo(i);
continue;
}
@ -355,8 +352,11 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel)
Point fontPos = Point((float)nextFontPositionX + charXOffset + charRect.size.width * 0.5f + kerningAmount,
(float)nextFontPositionY + yOffset - charRect.size.height * 0.5f);
// set the sprite position
letterSprite->setPosition(CC_POINT_PIXELS_TO_POINTS(fontPos));
if( theLabel->recordLetterInfo(CC_POINT_PIXELS_TO_POINTS(fontPos),c,i) == false)
{
log("WARNING: can't find letter definition in font file for letter: %c", c);
continue;
}
// update kerning
nextFontPositionX += charAdvance + kerningAmount;

View File

@ -48,14 +48,6 @@ NS_CC_BEGIN
// Layer
Layer::Layer()
: _touchEnabled(false)
, _accelerometerEnabled(false)
, _keyboardEnabled(false)
, _touchMode(Touch::DispatchMode::ALL_AT_ONCE)
, _swallowsTouches(true)
, _touchListener(nullptr)
, _keyboardListener(nullptr)
, _accelerationListener(nullptr)
{
_ignoreAnchorPointForPosition = true;
setAnchorPoint(Point(0.5f, 0.5f));
@ -74,8 +66,6 @@ bool Layer::init()
Director * pDirector;
CC_BREAK_IF(!(pDirector = Director::getInstance()));
this->setContentSize(pDirector->getWinSize());
setTouchEnabled(false);
setAccelerometerEnabled(false);
// success
bRet = true;
} while(0);
@ -97,386 +87,6 @@ Layer *Layer::create()
}
}
/// Touch and Accelerometer related
void Layer::addTouchListener()
{
if (_touchListener != nullptr)
return;
auto dispatcher = EventDispatcher::getInstance();
if( _touchMode == Touch::DispatchMode::ALL_AT_ONCE )
{
// Register Touch Event
auto listener = EventListenerTouch::create(Touch::DispatchMode::ALL_AT_ONCE);
listener->onTouchesBegan = CC_CALLBACK_2(Layer::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(Layer::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(Layer::onTouchesEnded, this);
listener->onTouchesCancelled = CC_CALLBACK_2(Layer::onTouchesCancelled, this);
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_touchListener = listener;
}
else
{
// Register Touch Event
auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE);
listener->setSwallowTouches(_swallowsTouches);
listener->onTouchBegan = CC_CALLBACK_2(Layer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(Layer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(Layer::onTouchEnded, this);
listener->onTouchCancelled = CC_CALLBACK_2(Layer::onTouchCancelled, this);
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_touchListener = listener;
}
}
int Layer::executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch)
{
if (kScriptTypeNone != _scriptType)
{
TouchScriptData data(eventType, this, touch);
ScriptEvent event(kTouchEvent, &data);
return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
//can not reach it
return 0;
}
int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType, const std::vector<Touch*>& touches)
{
if (kScriptTypeNone != _scriptType)
{
TouchesScriptData data(eventType, this, touches);
ScriptEvent event(kTouchesEvent, &data);
return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
return 0;
}
/// isTouchEnabled getter
bool Layer::isTouchEnabled() const
{
return _touchEnabled;
}
/// isTouchEnabled setter
void Layer::setTouchEnabled(bool enabled)
{
if (_touchEnabled != enabled)
{
_touchEnabled = enabled;
if (_running)
{
if (enabled)
{
this->addTouchListener();
}
else
{
EventDispatcher::getInstance()->removeEventListener(_touchListener);
_touchListener = nullptr;
}
}
}
}
void Layer::setTouchMode(Touch::DispatchMode mode)
{
if(_touchMode != mode)
{
_touchMode = mode;
if( _touchEnabled)
{
setTouchEnabled(false);
setTouchEnabled(true);
}
}
}
void Layer::setSwallowsTouches(bool swallowsTouches)
{
if (_swallowsTouches != swallowsTouches)
{
_swallowsTouches = swallowsTouches;
if( _touchEnabled)
{
setTouchEnabled(false);
setTouchEnabled(true);
}
}
}
Touch::DispatchMode Layer::getTouchMode() const
{
return _touchMode;
}
bool Layer::isSwallowsTouches() const
{
return _swallowsTouches;
}
/// isAccelerometerEnabled getter
bool Layer::isAccelerometerEnabled() const
{
return _accelerometerEnabled;
}
/// isAccelerometerEnabled setter
void Layer::setAccelerometerEnabled(bool enabled)
{
if (enabled != _accelerometerEnabled)
{
_accelerometerEnabled = enabled;
Device::setAccelerometerEnabled(enabled);
if (_running)
{
auto dispatcher = EventDispatcher::getInstance();
dispatcher->removeEventListener(_accelerationListener);
_accelerationListener = nullptr;
if (enabled)
{
_accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this));
dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);
}
}
}
}
void Layer::setAccelerometerInterval(double interval) {
if (_accelerometerEnabled)
{
if (_running)
{
Device::setAccelerometerInterval(interval);
}
}
}
void Layer::onAcceleration(Acceleration* pAccelerationValue, Event* event)
{
CC_UNUSED_PARAM(pAccelerationValue);
if(kScriptTypeNone != _scriptType)
{
BasicScriptData data(this,(void*)pAccelerationValue);
ScriptEvent event(kAccelerometerEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
}
void Layer::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
{
CC_UNUSED_PARAM(keyCode);
CC_UNUSED_PARAM(event);
}
void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
{
CC_UNUSED_PARAM(event);
if(kScriptTypeNone != _scriptType)
{
KeypadScriptData data(keyCode, this);
ScriptEvent event(kKeypadEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
}
/// isKeyboardEnabled getter
bool Layer::isKeyboardEnabled() const
{
return _keyboardEnabled;
}
/// isKeyboardEnabled setter
void Layer::setKeyboardEnabled(bool enabled)
{
if (enabled != _keyboardEnabled)
{
_keyboardEnabled = enabled;
auto dispatcher = EventDispatcher::getInstance();
dispatcher->removeEventListener(_keyboardListener);
_keyboardListener = nullptr;
if (enabled)
{
auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(Layer::onKeyPressed, this);
listener->onKeyReleased = CC_CALLBACK_2(Layer::onKeyReleased, this);
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_keyboardListener = listener;
}
}
}
/// Callbacks
void Layer::onEnter()
{
// register 'parent' nodes first
// since events are propagated in reverse order
if (_touchEnabled)
{
this->addTouchListener();
}
// then iterate over all the children
Node::onEnter();
// add this layer to concern the Accelerometer Sensor
if (_accelerometerEnabled)
{
auto dispatcher = EventDispatcher::getInstance();
dispatcher->removeEventListener(_accelerationListener);
_accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this));
dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);
}
}
void Layer::onExit()
{
auto dispatcher = EventDispatcher::getInstance();
dispatcher->removeEventListener(_touchListener);
_touchListener = nullptr;
// remove this layer from the delegates who concern Accelerometer Sensor
dispatcher->removeEventListener(_accelerationListener);
_accelerationListener = nullptr;
// remove this layer from the delegates who concern the keypad msg
dispatcher->removeEventListener(_keyboardListener);
_keyboardListener = nullptr;
Node::onExit();
}
void Layer::onEnterTransitionDidFinish()
{
if (_accelerometerEnabled)
{
auto dispatcher = EventDispatcher::getInstance();
dispatcher->removeEventListener(_accelerationListener);
_accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this));
dispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);
}
Node::onEnterTransitionDidFinish();
}
bool Layer::onTouchBegan(Touch *pTouch, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
return executeScriptTouchHandler(EventTouch::EventCode::BEGAN, pTouch) == 0 ? false : true;
}
CC_UNUSED_PARAM(pTouch);
CC_UNUSED_PARAM(pEvent);
CCASSERT(false, "Layer#ccTouchBegan override me");
return true;
}
void Layer::onTouchMoved(Touch *pTouch, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchHandler(EventTouch::EventCode::MOVED, pTouch);
return;
}
CC_UNUSED_PARAM(pTouch);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchEnded(Touch *pTouch, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchHandler(EventTouch::EventCode::ENDED, pTouch);
return;
}
CC_UNUSED_PARAM(pTouch);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchCancelled(Touch *pTouch, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchHandler(EventTouch::EventCode::CANCELLED, pTouch);
return;
}
CC_UNUSED_PARAM(pTouch);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchesBegan(const std::vector<Touch*>& pTouches, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchesHandler(EventTouch::EventCode::BEGAN, pTouches);
return;
}
CC_UNUSED_PARAM(pTouches);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchesMoved(const std::vector<Touch*>& pTouches, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchesHandler(EventTouch::EventCode::MOVED, pTouches);
return;
}
CC_UNUSED_PARAM(pTouches);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchesEnded(const std::vector<Touch*>& pTouches, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchesHandler(EventTouch::EventCode::ENDED, pTouches);
return;
}
CC_UNUSED_PARAM(pTouches);
CC_UNUSED_PARAM(pEvent);
}
void Layer::onTouchesCancelled(const std::vector<Touch*>& pTouches, Event *pEvent)
{
if (kScriptTypeNone != _scriptType)
{
executeScriptTouchesHandler(EventTouch::EventCode::CANCELLED, pTouches);
return;
}
CC_UNUSED_PARAM(pTouches);
CC_UNUSED_PARAM(pEvent);
}
#ifdef CC_USE_PHYSICS
void Layer::addChild(Node* child)
{
@ -1015,7 +625,14 @@ LayerMultiplex::LayerMultiplex()
}
LayerMultiplex::~LayerMultiplex()
{
CC_SAFE_RELEASE(_layers);
if (_layers)
{
for (auto& item : *_layers)
{
static_cast<Layer*>(item)->cleanup();
}
_layers->release();
}
}
LayerMultiplex * LayerMultiplex::create(Layer * layer, ...)

View File

@ -46,10 +46,6 @@ NS_CC_BEGIN
class TouchScriptHandlerEntry;
class EventListenerTouch;
class EventListenerKeyboard;
class EventListenerAcceleration;
//
// Layer
//
@ -86,23 +82,10 @@ public:
CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesEnded(Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesCancelled(Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
// default implements are used to call script callback if exist
virtual bool onTouchBegan(Touch *touch, Event *event);
virtual void onTouchMoved(Touch *touch, Event *event);
virtual void onTouchEnded(Touch *touch, Event *event);
virtual void onTouchCancelled(Touch *touch, Event *event);
// // default implements are used to call script callback if exist
virtual void onTouchesBegan(const std::vector<Touch*>& touches, Event *event);
virtual void onTouchesMoved(const std::vector<Touch*>& touches, Event *event);
virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event *event);
virtual void onTouchesCancelled(const std::vector<Touch*>&touches, Event *event);
/** @deprecated Please override onAcceleration */
CC_DEPRECATED_ATTRIBUTE virtual void didAccelerate(Acceleration* accelerationValue) final {};
virtual void onAcceleration(Acceleration* acc, Event* event);
/** If isTouchEnabled, this method is called onEnter. Override it to change the
way Layer receives touch events.
( Default: TouchDispatcher::sharedDispatcher()->addStandardDelegate(this,0); )
@ -115,36 +98,6 @@ public:
*/
CC_DEPRECATED_ATTRIBUTE virtual void registerWithTouchDispatcher() final {};
/** whether or not it will receive Touch events.
You can enable / disable touch events with this property.
Only the touches of this node will be affected. This "method" is not propagated to it's children.
@since v0.8.1
*/
virtual bool isTouchEnabled() const;
virtual void setTouchEnabled(bool value);
virtual void setTouchMode(Touch::DispatchMode mode);
virtual Touch::DispatchMode getTouchMode() const;
/** swallowsTouches of the touch events. Default is true */
virtual void setSwallowsTouches(bool swallowsTouches);
virtual bool isSwallowsTouches() const;
/** whether or not it will receive Accelerometer events
You can enable / disable accelerometer events with this property.
@since v0.8.1
*/
virtual bool isAccelerometerEnabled() const;
virtual void setAccelerometerEnabled(bool value);
virtual void setAccelerometerInterval(double interval);
/** whether or not it will receive keyboard or keypad events
You can enable / disable accelerometer events with this property.
it's new in cocos2d-x
*/
virtual bool isKeyboardEnabled() const;
virtual void setKeyboardEnabled(bool value);
/** Please use onKeyPressed instead. */
virtual void keyPressed(int keyCode) final {};
@ -152,11 +105,6 @@ public:
/** Please use onKeyReleased instead. */
virtual void keyReleased(int keyCode) final {};
virtual void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event);
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);
CC_DEPRECATED_ATTRIBUTE virtual bool isKeypadEnabled() const final { return isKeyboardEnabled(); };
CC_DEPRECATED_ATTRIBUTE virtual void setKeypadEnabled(bool value) { setKeyboardEnabled(value); };
/** @deprecated Please override onKeyReleased and check the keycode of KeyboardEvent::KeyCode::Menu(KEY_BACKSPACE) instead. */
CC_DEPRECATED_ATTRIBUTE virtual void keyBackClicked() final {};
@ -164,43 +112,12 @@ public:
//
// Overrides
//
/**
* @js NA
* @lua NA
*/
virtual void onEnter() override;
/**
* @js NA
* @lua NA
*/
virtual void onExit() override;
/**
* @js NA
* @lua NA
*/
virtual void onEnterTransitionDidFinish() override;
#ifdef CC_USE_PHYSICS
virtual void addChild(Node* child) override;
virtual void addChild(Node* child, int zOrder) override;
virtual void addChild(Node* child, int zOrder, int tag) override;
#endif // CC_USE_PHYSICS
protected:
void addTouchListener();
bool _touchEnabled;
bool _accelerometerEnabled;
bool _keyboardEnabled;
EventListenerTouch* _touchListener;
EventListenerKeyboard* _keyboardListener;
EventListenerAcceleration* _accelerationListener;
private:
Touch::DispatchMode _touchMode;
bool _swallowsTouches;
int executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch);
int executeScriptTouchesHandler(EventTouch::EventCode eventType, const std::vector<Touch*>& touches);
};
#ifdef __apple__

View File

@ -127,9 +127,6 @@ bool Menu::initWithArray(Array* pArrayOfItems)
{
if (Layer::init())
{
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
setTouchEnabled(true);
_enabled = true;
// menu in the center of the screen
Size s = Director::getInstance()->getWinSize();
@ -152,7 +149,6 @@ bool Menu::initWithArray(Array* pArrayOfItems)
}
}
// [self alignItemsVertically];
_selectedItem = NULL;
_state = Menu::State::WAITING;
@ -160,6 +156,17 @@ bool Menu::initWithArray(Array* pArrayOfItems)
setCascadeColorEnabled(true);
setCascadeOpacityEnabled(true);
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(true);
touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
return true;
}
return false;
@ -187,9 +194,6 @@ void Menu::addChild(Node * child, int zOrder, int tag)
void Menu::onEnter()
{
Layer::onEnter();
setTouchEnabled(true);
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
}
void Menu::onExit()
@ -253,22 +257,26 @@ bool Menu::onTouchBegan(Touch* touch, Event* event)
void Menu::onTouchEnded(Touch* touch, Event* event)
{
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchEnded] -- invalid state");
this->retain();
if (_selectedItem)
{
_selectedItem->unselected();
_selectedItem->activate();
}
_state = Menu::State::WAITING;
this->release();
}
void Menu::onTouchCancelled(Touch* touch, Event* event)
{
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchCancelled] -- invalid state");
this->retain();
if (_selectedItem)
{
_selectedItem->unselected();
}
_state = Menu::State::WAITING;
this->release();
}
void Menu::onTouchMoved(Touch* touch, Event* event)

View File

@ -112,6 +112,11 @@ public:
virtual bool isEnabled() const { return _enabled; }
virtual void setEnabled(bool value) { _enabled = value; };
virtual bool onTouchBegan(Touch* touch, Event* event);
virtual void onTouchEnded(Touch* touch, Event* event);
virtual void onTouchCancelled(Touch* touch, Event* event);
virtual void onTouchMoved(Touch* touch, Event* event);
// overrides
virtual void removeChild(Node* child, bool cleanup) override;
@ -119,11 +124,6 @@ public:
virtual void addChild(Node * child, int zOrder) override;
virtual void addChild(Node * child, int zOrder, int tag) override;
virtual bool onTouchBegan(Touch* touch, Event* event) override;
virtual void onTouchEnded(Touch* touch, Event* event) override;
virtual void onTouchCancelled(Touch* touch, Event* event) override;
virtual void onTouchMoved(Touch* touch, Event* event) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void setOpacityModifyRGB(bool bValue) override {CC_UNUSED_PARAM(bValue);}

View File

@ -410,6 +410,15 @@ MenuItemFont * MenuItemFont::create(const char *value)
return pRet;
}
MenuItemFont::MenuItemFont()
: _fontSize(0), _fontName("")
{}
MenuItemFont::~MenuItemFont()
{
CCLOGINFO("In the destructor of MenuItemFont (%p).", this);
}
// XXX: deprecated
bool MenuItemFont::initWithString(const char *value, Object* target, SEL_MenuHandler selector)
{
@ -925,7 +934,14 @@ void MenuItemToggle::addSubItem(MenuItem *item)
MenuItemToggle::~MenuItemToggle()
{
CC_SAFE_RELEASE(_subItems);
if (_subItems)
{
for (auto& item : *_subItems)
{
static_cast<MenuItem*>(item)->cleanup();
}
_subItems->release();
}
}
void MenuItemToggle::setSelectedIndex(unsigned int index)

View File

@ -241,12 +241,12 @@ public:
/**
* @js ctor
*/
MenuItemFont() : _fontSize(0), _fontName(""){}
MenuItemFont();
/**
* @js NA
* @lua NA
*/
virtual ~MenuItemFont(){}
virtual ~MenuItemFont();
/** initializes a menu item from a string with a target/selector */
CC_DEPRECATED_ATTRIBUTE bool initWithString(const char *value, Object* target, SEL_MenuHandler selector);

View File

@ -89,7 +89,6 @@ bool nodeComparisonLess(Object* p1, Object* p2)
// XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
static int s_globalOrderOfArrival = 1;
int Node::_globalEventPriorityIndex = 0;
Node::Node(void)
: _rotationX(0.0f)
@ -130,8 +129,6 @@ Node::Node(void)
, _isTransitionFinished(false)
, _updateScriptHandler(0)
, _componentContainer(NULL)
, _eventPriority(0)
, _oldEventPriority(0)
#ifdef CC_USE_PHYSICS
, _physicsBody(nullptr)
#endif
@ -142,6 +139,8 @@ Node::Node(void)
_actionManager->retain();
_scheduler = director->getScheduler();
_scheduler->retain();
_eventDispatcher = director->getEventDispatcher();
_eventDispatcher->retain();
ScriptEngineProtocol* pEngine = ScriptEngineManager::getInstance()->getScriptEngine();
_scriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone;
@ -158,6 +157,10 @@ Node::~Node()
CC_SAFE_RELEASE(_actionManager);
CC_SAFE_RELEASE(_scheduler);
_eventDispatcher->cleanTarget(this);
CC_SAFE_RELEASE(_eventDispatcher);
// attributes
CC_SAFE_RELEASE(_camera);
@ -185,8 +188,6 @@ Node::~Node()
CC_SAFE_DELETE(_componentContainer);
removeAllEventListeners();
#ifdef CC_USE_PHYSICS
CC_SAFE_RELEASE(_physicsBody);
#endif
@ -240,6 +241,8 @@ void Node::setZOrder(int z)
{
_parent->reorderChild(this, z);
}
_eventDispatcher->setDirtyForNode(this);
}
/// vertexZ getter
@ -859,7 +862,6 @@ void Node::visit()
}
// self draw
this->draw();
updateEventPriorityIndex();
for( ; i < _children->count(); i++ )
{
@ -871,7 +873,6 @@ void Node::visit()
else
{
this->draw();
updateEventPriorityIndex();
}
// reset for next frame
@ -934,7 +935,7 @@ void Node::onEnter()
arrayMakeObjectsPerformSelector(_children, onEnter, Node*);
this->resumeSchedulerAndActions();
this->resume();
_running = true;
@ -976,7 +977,7 @@ void Node::onExitTransitionDidStart()
void Node::onExit()
{
this->pauseSchedulerAndActions();
this->pause();
_running = false;
if (_scriptType != kScriptTypeNone)
@ -988,8 +989,17 @@ void Node::onExit()
}
arrayMakeObjectsPerformSelector(_children, onExit, Node*);
}
removeAllEventListeners();
void Node::setEventDispatcher(EventDispatcher* dispatcher)
{
if (dispatcher != _eventDispatcher)
{
_eventDispatcher->cleanTarget(this);
CC_SAFE_RETAIN(dispatcher);
CC_SAFE_RELEASE(_eventDispatcher);
_eventDispatcher = dispatcher;
}
}
void Node::setActionManager(ActionManager* actionManager)
@ -1117,16 +1127,28 @@ void Node::unscheduleAllSelectors()
_scheduler->unscheduleAllForTarget(this);
}
void Node::resumeSchedulerAndActions()
void Node::resume()
{
_scheduler->resumeTarget(this);
_actionManager->resumeTarget(this);
_eventDispatcher->resumeTarget(this);
}
void Node::pause()
{
_scheduler->pauseTarget(this);
_actionManager->pauseTarget(this);
_eventDispatcher->pauseTarget(this);
}
void Node::resumeSchedulerAndActions()
{
resume();
}
void Node::pauseSchedulerAndActions()
{
_scheduler->pauseTarget(this);
_actionManager->pauseTarget(this);
pause();
}
// override me
@ -1342,43 +1364,6 @@ void Node::removeAllComponents()
_componentContainer->removeAll();
}
void Node::resetEventPriorityIndex()
{
_globalEventPriorityIndex = 0;
}
void Node::associateEventListener(EventListener* listener)
{
_eventlisteners.insert(listener);
}
void Node::dissociateEventListener(EventListener* listener)
{
_eventlisteners.erase(listener);
}
void Node::removeAllEventListeners()
{
auto dispatcher = EventDispatcher::getInstance();
auto eventListenersCopy = _eventlisteners;
for (auto& listener : eventListenersCopy)
{
dispatcher->removeEventListener(listener);
}
}
void Node::setDirtyForAllEventListeners()
{
auto dispatcher = EventDispatcher::getInstance();
for (auto& listener : _eventlisteners)
{
dispatcher->setDirtyForEventType(listener->_type, true);
}
}
#ifdef CC_USE_PHYSICS
void Node::setPhysicsBody(PhysicsBody* body)
{

View File

@ -995,6 +995,9 @@ public:
/** @deprecated Use getBoundingBox instead */
CC_DEPRECATED_ATTRIBUTE inline virtual Rect boundingBox() const { return getBoundingBox(); }
virtual void setEventDispatcher(EventDispatcher* dispatcher);
virtual EventDispatcher* getEventDispatcher() const { return _eventDispatcher; };
/// @{
/// @name Actions
@ -1193,15 +1196,26 @@ public:
void unscheduleAllSelectors(void);
/**
* Resumes all scheduled selectors and actions.
* Resumes all scheduled selectors, actions and event listeners.
* This method is called internally by onEnter
*/
void resumeSchedulerAndActions(void);
void resume(void);
/**
* Pauses all scheduled selectors and actions.
* Pauses all scheduled selectors, actions and event listeners..
* This method is called internally by onExit
*/
void pauseSchedulerAndActions(void);
void pause(void);
/**
* Resumes all scheduled selectors, actions and event listeners.
* This method is called internally by onEnter
*/
CC_DEPRECATED_ATTRIBUTE void resumeSchedulerAndActions(void);
/**
* Pauses all scheduled selectors, actions and event listeners..
* This method is called internally by onExit
*/
CC_DEPRECATED_ATTRIBUTE void pauseSchedulerAndActions(void);
/*
* Update method will be called automatically every frame if "scheduleUpdate" is called, and the node is "live"
@ -1398,37 +1412,8 @@ public:
#endif
private:
friend class Director;
friend class EventDispatcher;
int getEventPriority() const { return _eventPriority; };
void associateEventListener(EventListener* listener);
void dissociateEventListener(EventListener* listener);
static void resetEventPriorityIndex();
std::set<EventListener*> _eventlisteners;
protected:
/// Upates event priority for this node.
inline void updateEventPriorityIndex() {
_oldEventPriority = _eventPriority;
_eventPriority = ++_globalEventPriorityIndex;
if (_oldEventPriority != _eventPriority)
{
setDirtyForAllEventListeners();
}
};
/// Removes all event listeners that associated with this node.
void removeAllEventListeners();
/// Sets dirty for event listener.
void setDirtyForAllEventListeners();
/// lazy allocs
void childrenAlloc(void);
@ -1490,6 +1475,8 @@ protected:
ActionManager *_actionManager; ///< a pointer to ActionManager singleton, which is used to handle all the actions
EventDispatcher* _eventDispatcher; ///< event dispatcher used to dispatch all kinds of events
bool _running; ///< is running
bool _visible; ///< is this node visible
@ -1506,10 +1493,6 @@ protected:
ComponentContainer *_componentContainer; ///< Dictionary of components
int _eventPriority; ///< The scene graph based priority of event listener.
int _oldEventPriority; ///< The old scene graph based priority of event listener.
static int _globalEventPriorityIndex; ///< The index of global event priority.
#ifdef CC_USE_PHYSICS
PhysicsBody* _physicsBody; ///< the physicsBody the node have
#endif

View File

@ -144,7 +144,6 @@ void ParticleBatchNode::visit()
transform();
draw();
updateEventPriorityIndex();
if ( _grid && _grid->isActive())
{

View File

@ -465,7 +465,6 @@ void RenderTexture::visit()
transform();
_sprite->visit();
draw();
updateEventPriorityIndex();
if (_grid && _grid->isActive())
{

View File

@ -211,6 +211,7 @@ enum ScriptEventType
kControlEvent,
kCommonEvent,
kTableViewEvent,//Now it's only used in LuaBinding
kAssetsManagerEvent,//Now it's only used in Lua Binding
};
struct BasicScriptData

View File

@ -158,7 +158,6 @@ void SpriteBatchNode::visit(void)
transform();
draw();
updateEventPriorityIndex();
if (_grid && _grid->isActive())
{

View File

@ -160,9 +160,7 @@ void TransitionScene::onEnter()
Scene::onEnter();
// disable events while transitions
// Director::getInstance()->getTouchDispatcher()->setDispatchEvents(false);
EventDispatcher::getInstance()->setEnabled(false);
_eventDispatcher->setEnabled(false);
// outScene should not receive the onEnter callback
// only the onExitTransitionDidStart
@ -177,9 +175,7 @@ void TransitionScene::onExit()
Scene::onExit();
// enable events while transitions
// Director::getInstance()->getTouchDispatcher()->setDispatchEvents(true);
EventDispatcher::getInstance()->setEnabled(true);
_eventDispatcher->setEnabled(true);
_outScene->onExit();
// _inScene should not receive the onEnter callback

View File

@ -36,6 +36,8 @@ CCEventDispatcher.cpp \
CCEventListener.cpp \
CCEventKeyboard.cpp \
CCEventListenerKeyboard.cpp \
CCEventMouse.cpp \
CCEventListenerMouse.cpp \
CCTouch.cpp \
CCEventTouch.cpp \
CCEventListenerTouch.cpp \

View File

@ -226,6 +226,8 @@ THE SOFTWARE.
#include "CCEventTouch.h"
#include "CCEventListenerKeyboard.h"
#include "CCEventKeyboard.h"
#include "CCEventListenerMouse.h"
#include "CCEventMouse.h"
#include "CCEventAcceleration.h"
#include "CCEventListenerAcceleration.h"
#include "CCEventCustom.h"

View File

@ -243,7 +243,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClCompile Include="CCEventListenerAcceleration.cpp" />
<ClCompile Include="CCEventListenerCustom.cpp" />
<ClCompile Include="CCEventListenerKeyboard.cpp" />
<ClCompile Include="CCEventListenerMouse.cpp" />
<ClCompile Include="CCEventListenerTouch.cpp" />
<ClCompile Include="CCEventMouse.cpp" />
<ClCompile Include="CCEventTouch.cpp" />
<ClCompile Include="CCFont.cpp" />
<ClCompile Include="CCFontAtlas.cpp" />
@ -414,7 +416,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClInclude Include="CCEventListenerAcceleration.h" />
<ClInclude Include="CCEventListenerCustom.h" />
<ClInclude Include="CCEventListenerKeyboard.h" />
<ClInclude Include="CCEventListenerMouse.h" />
<ClInclude Include="CCEventListenerTouch.h" />
<ClInclude Include="CCEventMouse.h" />
<ClInclude Include="CCEventTouch.h" />
<ClInclude Include="CCEventType.h" />
<ClInclude Include="CCFont.h" />

View File

@ -572,6 +572,12 @@
<ClCompile Include="ccUtils.cpp">
<Filter>support</Filter>
</ClCompile>
<ClCompile Include="CCEventListenerMouse.cpp">
<Filter>event_dispatcher</Filter>
</ClCompile>
<ClCompile Include="CCEventMouse.cpp">
<Filter>event_dispatcher</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\physics\CCPhysicsBody.h">
@ -1152,5 +1158,11 @@
<ClInclude Include="..\base\CCString.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="CCEventListenerMouse.h">
<Filter>event_dispatcher</Filter>
</ClInclude>
<ClInclude Include="CCEventMouse.h">
<Filter>event_dispatcher</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -247,7 +247,8 @@ void EGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float y
}
touchEvent._eventCode = EventTouch::EventCode::BEGAN;
EventDispatcher::getInstance()->dispatchEvent(&touchEvent);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&touchEvent);
}
void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[])
@ -294,7 +295,8 @@ void EGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys
}
touchEvent._eventCode = EventTouch::EventCode::MOVED;
EventDispatcher::getInstance()->dispatchEvent(&touchEvent);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&touchEvent);
}
void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[])
@ -347,7 +349,8 @@ void EGLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode
}
touchEvent._eventCode = eventCode;
EventDispatcher::getInstance()->dispatchEvent(&touchEvent);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&touchEvent);
for (auto& touch : touchEvent._touches)
{

View File

@ -81,7 +81,7 @@ public:
{
JniMethodInfo methodInfo;
if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmapShadowStroke",
"(Ljava/lang/String;Ljava/lang/String;IFFFIIIZFFFFZFFFF)V"))
"(Ljava/lang/String;Ljava/lang/String;IFFFIIIZFFFFZFFFF)Z"))
{
CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__);
return false;
@ -109,8 +109,12 @@ public:
jstring jstrText = methodInfo.env->NewStringUTF(text);
jstring jstrFont = methodInfo.env->NewStringUTF(fullPathOrFontName.c_str());
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrText,
jstrFont, (int)fontSize, textTintR, textTintG, textTintB, eAlignMask, nWidth, nHeight, shadow, shadowDeltaX, -shadowDeltaY, shadowBlur, shadowOpacity, stroke, strokeColorR, strokeColorG, strokeColorB, strokeSize);
if(!methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrText,
jstrFont, (int)fontSize, textTintR, textTintG, textTintB, eAlignMask, nWidth, nHeight, shadow, shadowDeltaX, -shadowDeltaY, shadowBlur, shadowOpacity, stroke, strokeColorR, strokeColorG, strokeColorB, strokeSize))
{
return false;
}
methodInfo.env->DeleteLocalRef(jstrText);
methodInfo.env->DeleteLocalRef(jstrFont);

View File

@ -58,7 +58,7 @@ public class Cocos2dxBitmap {
// Fields
// ===========================================================
private static Context sContext;
private static Context _context;
// ===========================================================
// Constructors
@ -68,8 +68,8 @@ public class Cocos2dxBitmap {
// Getter & Setter
// ===========================================================
public static void setContext(final Context pContext) {
Cocos2dxBitmap.sContext = pContext;
public static void setContext(final Context context) {
Cocos2dxBitmap._context = context;
}
// ===========================================================
@ -80,8 +80,8 @@ public class Cocos2dxBitmap {
// Methods
// ===========================================================
private static native void nativeInitBitmapDC(final int pWidth,
final int pHeight, final byte[] pPixels);
private static native void nativeInitBitmapDC(final int width,
final int height, final byte[] pixels);
/**
* @param pWidth
@ -89,36 +89,49 @@ public class Cocos2dxBitmap {
* @param pHeight
* the height to draw, it can be 0
*/
public static void createTextBitmap(String pString, final String pFontName,
final int pFontSize, final int pAlignment, final int pWidth,
final int pHeight) {
public static void createTextBitmap(String string, final String fontName,
final int fontSize, final int alignment, final int width,
final int height) {
//
createTextBitmapShadowStroke( pString, pFontName, pFontSize, 1.0f, 1.0f, 1.0f, // text font and color
pAlignment, pWidth, pHeight, // alignment and size
createTextBitmapShadowStroke( string, fontName, fontSize, 1.0f, 1.0f, 1.0f, // text font and color
alignment, width, height, // alignment and size
false, 0.0f, 0.0f, 0.0f, 0.0f, // no shadow
false, 1.0f, 1.0f, 1.0f, 1.0f); // no stroke
}
public static void createTextBitmapShadowStroke(String pString, final String pFontName, final int pFontSize,
public static boolean createTextBitmapShadowStroke(String string, final String fontName, final int fontSize,
final float fontTintR, final float fontTintG, final float fontTintB,
final int pAlignment, final int pWidth, final int pHeight, final boolean shadow,
final int alignment, final int width, final int height, final boolean shadow,
final float shadowDX, final float shadowDY, final float shadowBlur, final float shadowOpacity, final boolean stroke,
final float strokeR, final float strokeG, final float strokeB, final float strokeSize) {
final int horizontalAlignment = pAlignment & 0x0F;
final int verticalAlignment = (pAlignment >> 4) & 0x0F;
final int horizontalAlignment = alignment & 0x0F;
final int verticalAlignment = (alignment >> 4) & 0x0F;
string = Cocos2dxBitmap.refactorString(string);
final Paint paint = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment);
/**
* if the first word width less than designed width,It means no words to show
*/
if(0 != width)
{
final int firstWordWidth = (int) FloatMath.ceil(paint.measureText(string, 0,1));
if ( firstWordWidth > width)
{
Log.w("createTextBitmapShadowStroke warning:","the input width is less than the width of the pString's first word\n");
return false;
}
}
pString = Cocos2dxBitmap.refactorString(pString);
final Paint paint = Cocos2dxBitmap.newPaint(pFontName, pFontSize, horizontalAlignment);
// set the paint color
paint.setARGB(255, (int)(255.0 * fontTintR), (int)(255.0 * fontTintG), (int)(255.0 * fontTintB));
final TextProperty textProperty = Cocos2dxBitmap.computeTextProperty(pString, pWidth, pHeight, paint);
final int bitmapTotalHeight = (pHeight == 0 ? textProperty.mTotalHeight: pHeight);
final TextProperty textProperty = Cocos2dxBitmap.computeTextProperty(string, width, height, paint);
final int bitmapTotalHeight = (height == 0 ? textProperty.mTotalHeight: height);
// padding needed when using shadows (not used otherwise)
float bitmapPaddingX = 0.0f;
@ -145,6 +158,13 @@ public class Cocos2dxBitmap {
}
}
if (0 == textProperty.mMaxWidth || 0 == bitmapTotalHeight)
{
Log.w("createTextBitmapShadowStroke warning:","textProperty MaxWidth is 0 or bitMapTotalHeight is 0\n");
return false;
}
final Bitmap bitmap = Bitmap.createBitmap(textProperty.mMaxWidth + (int)bitmapPaddingX,
bitmapTotalHeight + (int)bitmapPaddingY, Bitmap.Config.ARGB_8888);
@ -154,7 +174,7 @@ public class Cocos2dxBitmap {
final FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
int x = 0;
int y = Cocos2dxBitmap.computeY(fontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment);
int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines = textProperty.mLines;
@ -169,13 +189,13 @@ public class Cocos2dxBitmap {
// draw again with stroke on if needed
if ( stroke ) {
final Paint paintStroke = Cocos2dxBitmap.newPaint(pFontName, pFontSize, horizontalAlignment);
final Paint paintStroke = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment);
paintStroke.setStyle(Paint.Style.STROKE);
paintStroke.setStrokeWidth(strokeSize * 0.5f);
paintStroke.setARGB(255, (int) (strokeR * 255), (int) (strokeG * 255), (int) (strokeB * 255));
x = 0;
y = Cocos2dxBitmap.computeY(fontMetricsInt, pHeight, textProperty.mTotalHeight, verticalAlignment);
y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines2 = textProperty.mLines;
for (final String line : lines2) {
@ -189,33 +209,35 @@ public class Cocos2dxBitmap {
}
Cocos2dxBitmap.initNativeObject(bitmap);
return true;
}
private static Paint newPaint(final String pFontName, final int pFontSize,
final int pHorizontalAlignment) {
private static Paint newPaint(final String fontName, final int fontSize,
final int horizontalAlignment) {
final Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(pFontSize);
paint.setTextSize(fontSize);
paint.setAntiAlias(true);
/* Set type face for paint, now it support .ttf file. */
if (pFontName.endsWith(".ttf")) {
if (fontName.endsWith(".ttf")) {
try {
final Typeface typeFace = Cocos2dxTypefaces.get(
Cocos2dxBitmap.sContext, pFontName);
Cocos2dxBitmap._context, fontName);
paint.setTypeface(typeFace);
} catch (final Exception e) {
Log.e("Cocos2dxBitmap", "error to create ttf type face: "
+ pFontName);
+ fontName);
/* The file may not find, use system font. */
paint.setTypeface(Typeface.create(pFontName, Typeface.NORMAL));
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
} else {
paint.setTypeface(Typeface.create(pFontName, Typeface.NORMAL));
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
switch (pHorizontalAlignment) {
switch (horizontalAlignment) {
case HORIZONTALALIGN_CENTER:
paint.setTextAlign(Align.CENTER);
break;
@ -231,22 +253,22 @@ public class Cocos2dxBitmap {
return paint;
}
private static TextProperty computeTextProperty(final String pString,
final int pWidth, final int pHeight, final Paint pPaint) {
final FontMetricsInt fm = pPaint.getFontMetricsInt();
private static TextProperty computeTextProperty(final String string,
final int width, final int height, final Paint paint) {
final FontMetricsInt fm = paint.getFontMetricsInt();
final int h = (int) Math.ceil(fm.bottom - fm.top);
int maxContentWidth = 0;
final String[] lines = Cocos2dxBitmap.splitString(pString, pWidth,
pHeight, pPaint);
final String[] lines = Cocos2dxBitmap.splitString(string, width,
height, paint);
if (pWidth != 0) {
maxContentWidth = pWidth;
if (width != 0) {
maxContentWidth = width;
} else {
/* Compute the max width. */
int temp = 0;
for (final String line : lines) {
temp = (int) FloatMath.ceil(pPaint.measureText(line, 0,
temp = (int) FloatMath.ceil(paint.measureText(line, 0,
line.length()));
if (temp > maxContentWidth) {
maxContentWidth = temp;
@ -257,16 +279,16 @@ public class Cocos2dxBitmap {
return new TextProperty(maxContentWidth, h, lines);
}
private static int computeX(final String pText, final int pMaxWidth,
final int pHorizontalAlignment) {
private static int computeX(final String text, final int maxWidth,
final int horizontalAlignment) {
int ret = 0;
switch (pHorizontalAlignment) {
switch (horizontalAlignment) {
case HORIZONTALALIGN_CENTER:
ret = pMaxWidth / 2;
ret = maxWidth / 2;
break;
case HORIZONTALALIGN_RIGHT:
ret = pMaxWidth;
ret = maxWidth;
break;
case HORIZONTALALIGN_LEFT:
default:
@ -276,22 +298,22 @@ public class Cocos2dxBitmap {
return ret;
}
private static int computeY(final FontMetricsInt pFontMetricsInt,
final int pConstrainHeight, final int pTotalHeight,
final int pVerticalAlignment) {
int y = -pFontMetricsInt.top;
private static int computeY(final FontMetricsInt fontMetricsInt,
final int constrainHeight, final int totalHeight,
final int verticalAlignment) {
int y = -fontMetricsInt.top;
if (pConstrainHeight > pTotalHeight) {
switch (pVerticalAlignment) {
if (constrainHeight > totalHeight) {
switch (verticalAlignment) {
case VERTICALALIGN_TOP:
y = -pFontMetricsInt.top;
y = -fontMetricsInt.top;
break;
case VERTICALALIGN_CENTER:
y = -pFontMetricsInt.top + (pConstrainHeight - pTotalHeight)
y = -fontMetricsInt.top + (constrainHeight - totalHeight)
/ 2;
break;
case VERTICALALIGN_BOTTOM:
y = -pFontMetricsInt.top + (pConstrainHeight - pTotalHeight);
y = -fontMetricsInt.top + (constrainHeight - totalHeight);
break;
default:
break;
@ -305,26 +327,26 @@ public class Cocos2dxBitmap {
* If maxWidth or maxHeight is not 0, split the string to fix the maxWidth
* and maxHeight.
*/
private static String[] splitString(final String pString,
final int pMaxWidth, final int pMaxHeight, final Paint pPaint) {
final String[] lines = pString.split("\\n");
private static String[] splitString(final String string,
final int maxWidth, final int maxHeight, final Paint paint) {
final String[] lines = string.split("\\n");
String[] ret = null;
final FontMetricsInt fm = pPaint.getFontMetricsInt();
final FontMetricsInt fm = paint.getFontMetricsInt();
final int heightPerLine = (int) Math.ceil(fm.bottom - fm.top);
final int maxLines = pMaxHeight / heightPerLine;
final int maxLines = maxHeight / heightPerLine;
if (pMaxWidth != 0) {
if (maxWidth != 0) {
final LinkedList<String> strList = new LinkedList<String>();
for (final String line : lines) {
/*
* The width of line is exceed maxWidth, should divide it into
* two or more lines.
*/
final int lineWidth = (int) FloatMath.ceil(pPaint
final int lineWidth = (int) FloatMath.ceil(paint
.measureText(line));
if (lineWidth > pMaxWidth) {
if (lineWidth > maxWidth) {
strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidth(
line, pMaxWidth, pPaint));
line, maxWidth, paint));
} else {
strList.add(line);
}
@ -344,7 +366,7 @@ public class Cocos2dxBitmap {
ret = new String[strList.size()];
strList.toArray(ret);
} else if (pMaxHeight != 0 && lines.length > maxLines) {
} else if (maxHeight != 0 && lines.length > maxLines) {
/* Remove exceeding lines. */
final LinkedList<String> strList = new LinkedList<String>();
for (int i = 0; i < maxLines; i++) {
@ -360,37 +382,37 @@ public class Cocos2dxBitmap {
}
private static LinkedList<String> divideStringWithMaxWidth(
final String pString, final int pMaxWidth, final Paint pPaint) {
final int charLength = pString.length();
final String string, final int maxWidth, final Paint paint) {
final int charLength = string.length();
int start = 0;
int tempWidth = 0;
final LinkedList<String> strList = new LinkedList<String>();
/* Break a String into String[] by the width & should wrap the word. */
for (int i = 1; i <= charLength; ++i) {
tempWidth = (int) FloatMath.ceil(pPaint.measureText(pString, start,
tempWidth = (int) FloatMath.ceil(paint.measureText(string, start,
i));
if (tempWidth >= pMaxWidth) {
final int lastIndexOfSpace = pString.substring(0, i)
if (tempWidth >= maxWidth) {
final int lastIndexOfSpace = string.substring(0, i)
.lastIndexOf(" ");
if (lastIndexOfSpace != -1 && lastIndexOfSpace > start) {
/* Should wrap the word. */
strList.add(pString.substring(start, lastIndexOfSpace));
strList.add(string.substring(start, lastIndexOfSpace));
i = lastIndexOfSpace + 1; // skip space
} else {
/* Should not exceed the width. */
if (tempWidth > pMaxWidth) {
strList.add(pString.substring(start, i - 1));
if (tempWidth > maxWidth) {
strList.add(string.substring(start, i - 1));
/* Compute from previous char. */
--i;
} else {
strList.add(pString.substring(start, i));
strList.add(string.substring(start, i));
}
}
/* Remove spaces at the beginning of a new line. */
while (i < charLength && pString.charAt(i) == ' ') {
while (i < charLength && string.charAt(i) == ' ') {
++i;
}
@ -400,15 +422,15 @@ public class Cocos2dxBitmap {
/* Add the last chars. */
if (start < charLength) {
strList.add(pString.substring(start));
strList.add(string.substring(start));
}
return strList;
}
private static String refactorString(final String pString) {
private static String refactorString(final String string) {
/* Avoid error when content is "". */
if (pString.compareTo("") == 0) {
if (string.compareTo("") == 0) {
return " ";
}
@ -416,7 +438,7 @@ public class Cocos2dxBitmap {
* If the font of "\n" is "" or "\n", insert " " in front of it. For
* example: "\nabc" -> " \nabc" "\nabc\n\n" -> " \nabc\n \n".
*/
final StringBuilder strBuilder = new StringBuilder(pString);
final StringBuilder strBuilder = new StringBuilder(string);
int start = 0;
int index = strBuilder.indexOf("\n");
while (index != -1) {
@ -437,23 +459,23 @@ public class Cocos2dxBitmap {
return strBuilder.toString();
}
private static void initNativeObject(final Bitmap pBitmap) {
final byte[] pixels = Cocos2dxBitmap.getPixels(pBitmap);
private static void initNativeObject(final Bitmap bitmap) {
final byte[] pixels = Cocos2dxBitmap.getPixels(bitmap);
if (pixels == null) {
return;
}
Cocos2dxBitmap.nativeInitBitmapDC(pBitmap.getWidth(),
pBitmap.getHeight(), pixels);
Cocos2dxBitmap.nativeInitBitmapDC(bitmap.getWidth(),
bitmap.getHeight(), pixels);
}
private static byte[] getPixels(final Bitmap pBitmap) {
if (pBitmap != null) {
final byte[] pixels = new byte[pBitmap.getWidth()
* pBitmap.getHeight() * 4];
private static byte[] getPixels(final Bitmap bitmap) {
if (bitmap != null) {
final byte[] pixels = new byte[bitmap.getWidth()
* bitmap.getHeight() * 4];
final ByteBuffer buf = ByteBuffer.wrap(pixels);
buf.order(ByteOrder.nativeOrder());
pBitmap.copyPixelsToBuffer(buf);
bitmap.copyPixelsToBuffer(buf);
return pixels;
}
@ -484,9 +506,9 @@ public class Cocos2dxBitmap {
return incr_text_size;
}
private static String getStringWithEllipsis(String pString, float width,
private static String getStringWithEllipsis(String string, float width,
float fontSize) {
if (TextUtils.isEmpty(pString)) {
if (TextUtils.isEmpty(string)) {
return "";
}
@ -494,7 +516,7 @@ public class Cocos2dxBitmap {
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(fontSize);
return TextUtils.ellipsize(pString, paint, width,
return TextUtils.ellipsize(string, paint, width,
TextUtils.TruncateAt.END).toString();
}
@ -510,12 +532,12 @@ public class Cocos2dxBitmap {
private final int mHeightPerLine;
private final String[] mLines;
TextProperty(final int pMaxWidth, final int pHeightPerLine,
final String[] pLines) {
this.mMaxWidth = pMaxWidth;
this.mHeightPerLine = pHeightPerLine;
this.mTotalHeight = pHeightPerLine * pLines.length;
this.mLines = pLines;
TextProperty(final int maxWidth, final int heightPerLine,
final String[] lines) {
this.mMaxWidth = maxWidth;
this.mHeightPerLine = heightPerLine;
this.mTotalHeight = heightPerLine * lines.length;
this.mLines = lines;
}
}
}

View File

@ -213,6 +213,7 @@ namespace cocos2d {
jmethodID methodID = pEnv->GetMethodID(classID, methodName, paramCode);
if (! methodID) {
LOGD("Failed to find method id of %s", methodName);
pEnv->ExceptionClear();
return false;
}
@ -247,6 +248,7 @@ namespace cocos2d {
jmethodID methodID = pEnv->GetMethodID(classID, methodName, paramCode);
if (! methodID) {
LOGD("Failed to find method id of %s", methodName);
pEnv->ExceptionClear();
return false;
}

View File

@ -422,18 +422,20 @@ static int32_t handle_key_input(AInputEvent *event)
{
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP)
{
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
switch (AKeyEvent_getKeyCode(event))
{
case AKEYCODE_BACK:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE, false);
cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event);
dispatcher->dispatchEvent(&event);
}
return 1;
case AKEYCODE_MENU:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_MENU, false);
cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event);
dispatcher->dispatchEvent(&event);
}
return 1;
default:
@ -629,8 +631,8 @@ void android_main(struct android_app* state) {
acc.z = event.acceleration.z/10;
acc.timestamp = 0;
cocos2d::EventAcceleration accEvent(acc);
cocos2d::EventDispatcher::getInstance()->dispatchEvent(&accEvent);
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&accEvent);
} else {
// ACONFIGURATION_ORIENTATION_LAND
// swap x and y parameters
@ -640,8 +642,8 @@ void android_main(struct android_app* state) {
acc.z = event.acceleration.z/10;
acc.timestamp = 0;
cocos2d::EventAcceleration accEvent(acc);
cocos2d::EventDispatcher::getInstance()->dispatchEvent(&accEvent);
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&accEvent);
}
}
}

View File

@ -2,7 +2,7 @@
#include "ccTypes.h"
#include "CCEventDispatcher.h"
#include "CCEventAcceleration.h"
#include "CCDirector.h"
#import <UIKit/UIKit.h>
// Accelerometer
@ -100,7 +100,8 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
}
cocos2d::EventAcceleration event(*_acceleration);
cocos2d::EventDispatcher::getInstance()->dispatchEvent(&event);
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&event);
}
@end

View File

@ -13,6 +13,7 @@
#include "CCIMEDispatcher.h"
#include "CCEventDispatcher.h"
#include "CCEventKeyboard.h"
#include "CCEventMouse.h"
#include <unistd.h>
NS_CC_BEGIN
@ -159,6 +160,7 @@ public:
static void OnGLFWError(int errorID, const char* errorDesc);
static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify);
static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y);
static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y);
static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character);
static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y);
@ -198,6 +200,21 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in
}
}
}
if(GLFW_PRESS == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
else if(GLFW_RELEASE == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_UP);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
}
void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
@ -218,12 +235,30 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x,
eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY);
}
}
EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE);
//Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y)
{
EGLView* eglView = EGLView::getInstance();
if(nullptr == eglView) return;
EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL);
//Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here
event.setScrollData((float)x, -(float)y);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action);
EventDispatcher::getInstance()->dispatchEvent(&event);
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character)
@ -282,6 +317,7 @@ bool EGLView::init(const char* viewName, float width, float height, float frameZ
glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack);
glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack);
glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback);
glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback);
glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback);
glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback);

View File

@ -25,7 +25,7 @@
#import "CCDirectorCaller.h"
#import "CCDirector.h"
#import "EAGLView.h"
#import "CCEventDispatcher.h"
#import "CCEventDispatcherMac.h"
#include "CCAutoreleasePool.h"
static id s_sharedDirectorCaller;

View File

@ -28,6 +28,7 @@
#include "CCTouch.h"
#include "CCEventDispatcher.h"
#include "CCEventKeyboard.h"
#include "CCEventMouse.h"
#include "CCIMEDispatcher.h"
NS_CC_BEGIN
@ -175,6 +176,7 @@ public:
static void OnGLFWError(int errorID, const char* errorDesc);
static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify);
static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y);
static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y);
static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character);
static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y);
@ -214,14 +216,31 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in
}
}
}
if(GLFW_PRESS == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN);
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
else if(GLFW_RELEASE == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_UP);
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
}
void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
{
s_mouseX = (float)x;
s_mouseY = (float)y;
EGLView* eglView = EGLView::getInstance();
if(nullptr == eglView) return;
s_mouseX = (float)x;
s_mouseY = (float)y;
s_mouseX /= eglView->getFrameZoomFactor();
s_mouseY /= eglView->getFrameZoomFactor();
@ -234,12 +253,30 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x,
eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY);
}
}
EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE);
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y)
{
EGLView* eglView = EGLView::getInstance();
if(nullptr == eglView) return;
EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL);
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
event.setScrollData((float)x, -(float)y);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action);
EventDispatcher::getInstance()->dispatchEvent(&event);
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character)
@ -300,6 +337,7 @@ bool EGLView::init(const char *viewName, float width, float height, float frameZ
glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack);
glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack);
glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback);
glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback);
glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback);
glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback);

View File

@ -27,12 +27,11 @@
// But in case they are included, it won't be compiled.
#import <Availability.h>
#import "CCEventDispatcher.h"
#import "CCEventDispatcherMac.h"
#import "ccConfig.h"
#include "utlist.h"
#include "CCDirector.h"
#include "platform/mac/CCEventDispatcher.h"
//NS_CC_BEGIN;
static CCEventDispatcher *sharedDispatcher = nil;

View File

@ -37,7 +37,7 @@ THE SOFTWARE.
#import "CCTouch.h"
#import "CCIMEDispatcher.h"
#import "CCWindow.h"
#import "CCEventDispatcher.h"
#import "CCEventDispatcherMac.h"
#import "CCEGLView.h"

View File

@ -31,7 +31,7 @@ THE SOFTWARE.
#include "CCTouch.h"
#include "CCEventDispatcher.h"
#include "CCEventKeyboard.h"
#include "CCEventMouse.h"
NS_CC_BEGIN
@ -277,6 +277,7 @@ public:
static void OnGLFWError(int errorID, const char* errorDesc);
static void OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify);
static void OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y);
static void OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y);
static void OnGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void OnGLFWCharCallback(GLFWwindow* window, unsigned int character);
static void OnGLFWWindowPosCallback(GLFWwindow* windows, int x, int y);
@ -316,6 +317,21 @@ void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, in
}
}
}
if(GLFW_PRESS == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
else if(GLFW_RELEASE == action)
{
EventMouse event(EventMouse::MouseEventType::MOUSE_UP);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
event.setMouseButton(button);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
}
void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
@ -336,12 +352,30 @@ void EGLViewEventHandler::OnGLFWMouseMoveCallBack(GLFWwindow* window, double x,
eglView->handleTouchesMove(1, &id, &s_mouseX, &s_mouseY);
}
}
EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE);
//Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWMouseScrollCallback(GLFWwindow* window, double x, double y)
{
EGLView* eglView = EGLView::getInstance();
if(nullptr == eglView) return;
EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL);
//Because OpenGL use upper left as origin point, we need to revert the mouse y coordinate here
event.setScrollData((float)x, -(float)y);
event.setCursorPosition(s_mouseX, eglView->getViewPortRect().size.height - s_mouseY);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action);
EventDispatcher::getInstance()->dispatchEvent(&event);
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action || GLFW_REPEAT == action);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&event);
}
void EGLViewEventHandler::OnGLFWCharCallback(GLFWwindow *window, unsigned int character)
@ -405,8 +439,10 @@ bool EGLView::init(const char* viewName, float width, float height, float frameZ
glfwGetFramebufferSize(_mainWindow, &_frameBufferSize[0], &_frameBufferSize[1]);
glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack);
glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack);
glfwSetScrollCallback(_mainWindow, EGLViewEventHandler::OnGLFWMouseScrollCallback);
glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback);
glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback);
glfwSetWindowPosCallback(_mainWindow, EGLViewEventHandler::OnGLFWWindowPosCallback);
// check OpenGL version at first
const GLubyte* glVersion = glGetString(GL_VERSION);

View File

@ -14,9 +14,9 @@ namespace cocosbuilder {
void LayerLoader::onHandlePropTypeCheck(Node * pNode, Node * pParent, const char * pPropertyName, bool pCheck, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_TOUCH_ENABLED) == 0) {
((Layer *)pNode)->setTouchEnabled(pCheck);
// FIXME: ((Layer *)pNode)->setTouchEnabled(pCheck);
} else if(strcmp(pPropertyName, PROPERTY_ACCELEROMETER_ENABLED) == 0) {
((Layer *)pNode)->setAccelerometerEnabled(pCheck);
// FIXME: ((Layer *)pNode)->setAccelerometerEnabled(pCheck);
} else if(strcmp(pPropertyName, PROPERTY_MOUSE_ENABLED) == 0) {
// TODO XXX
CCLOG("The property '%s' is not supported!", PROPERTY_MOUSE_ENABLED);

View File

@ -18,13 +18,17 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -624,7 +624,6 @@ void Armature::visit()
transform();
sortAllChildren();
draw();
updateEventPriorityIndex();
// reset for next frame
_orderOfArrival = 0;

View File

@ -81,7 +81,6 @@ void BatchNode::visit()
transform();
sortAllChildren();
draw();
updateEventPriorityIndex();
// reset for next frame
_orderOfArrival = 0;

View File

@ -43,7 +43,7 @@ InputDelegate::InputDelegate(void)
InputDelegate::~InputDelegate(void)
{
auto dispatcher = EventDispatcher::getInstance();
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->removeEventListener(_touchListener);
dispatcher->removeEventListener(_keyboardListener);
dispatcher->removeEventListener(_accelerometerListener);
@ -107,23 +107,24 @@ void InputDelegate::setTouchEnabled(bool enabled)
{
if (_touchEnabled != enabled)
{
auto dispatcher = Director::getInstance()->getEventDispatcher();
_touchEnabled = enabled;
if (enabled)
{
if( _touchMode == Touch::DispatchMode::ALL_AT_ONCE ) {
// Register Touch Event
auto listener = EventListenerTouch::create(Touch::DispatchMode::ALL_AT_ONCE);
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(InputDelegate::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(InputDelegate::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(InputDelegate::onTouchesEnded, this);
listener->onTouchesCancelled = CC_CALLBACK_2(InputDelegate::onTouchesCancelled, this);
EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, _touchPriority);
dispatcher->addEventListenerWithFixedPriority(listener, _touchPriority);
_touchListener = listener;
} else {
// Register Touch Event
auto listener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE);
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(InputDelegate::onTouchBegan, this);
@ -131,13 +132,13 @@ void InputDelegate::setTouchEnabled(bool enabled)
listener->onTouchEnded = CC_CALLBACK_2(InputDelegate::onTouchEnded, this);
listener->onTouchCancelled = CC_CALLBACK_2(InputDelegate::onTouchCancelled, this);
EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, _touchPriority);
dispatcher->addEventListenerWithFixedPriority(listener, _touchPriority);
_touchListener = listener;
}
}
else
{
EventDispatcher::getInstance()->removeEventListener(_touchListener);
dispatcher->removeEventListener(_touchListener);
}
}
}
@ -191,7 +192,7 @@ void InputDelegate::setAccelerometerEnabled(bool enabled)
{
_accelerometerEnabled = enabled;
auto dispatcher = EventDispatcher::getInstance();
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->removeEventListener(_accelerometerListener);
_accelerometerListener = nullptr;
@ -215,7 +216,8 @@ void InputDelegate::setKeypadEnabled(bool enabled)
{
_keypadEnabled = enabled;
EventDispatcher::getInstance()->removeEventListener(_keyboardListener);
auto dispatcher = Director::getInstance()->getEventDispatcher();
dispatcher->removeEventListener(_keyboardListener);
if (enabled)
{
@ -223,7 +225,7 @@ void InputDelegate::setKeypadEnabled(bool enabled)
listener->onKeyPressed = CC_CALLBACK_2(InputDelegate::onKeyPressed, this);
listener->onKeyReleased = CC_CALLBACK_2(InputDelegate::onKeyReleased, this);
EventDispatcher::getInstance()->addEventListenerWithFixedPriority(listener, -1);
dispatcher->addEventListenerWithFixedPriority(listener, -1);
_keyboardListener = listener;
}
}

View File

@ -106,13 +106,17 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -65,13 +65,17 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -74,15 +74,21 @@ UILayer* UILayer::create(void)
void UILayer::onEnter()
{
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
setTouchEnabled(true);
CCLayer::onEnter();
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(UILayer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(UILayer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(UILayer::onTouchEnded, this);
listener->onTouchCancelled = CC_CALLBACK_2(UILayer::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
void UILayer::onExit()
{
setTouchEnabled(false);
CCLayer::onExit();
}

View File

@ -67,13 +67,17 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -123,7 +123,10 @@ public:
/** Get the request data pointer back */
inline char* getRequestData()
{
return &(_requestData.front());
if(_requestData.size() != 0)
return &(_requestData.front());
return nullptr;
}
/** Get the size of request data back */
inline int getRequestDataSize()

View File

@ -24,6 +24,7 @@
#include "CCPhysicsBody.h"
#ifdef CC_USE_PHYSICS
#include <climits>
#include <algorithm>
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)

View File

@ -43,7 +43,7 @@ class PhysicsJoint;
class PhysicsBodyInfo;
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT = {1.0f, 1.0f, 1.0f};
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(1.0f, 1.0f, 1.0f);
/**
* A body affect by physics.

View File

@ -70,16 +70,21 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
{
do
{
CC_BREAK_IF(a == nullptr || b == nullptr);
CC_BREAK_IF(!(_info = new PhysicsJointInfo(this)));
_bodyA = a;
_bodyA->retain();
_bodyA->_joints.push_back(this);
_bodyB = b;
_bodyB->retain();
_bodyB->_joints.push_back(this);
if (a != nullptr)
{
_bodyA = a;
_bodyA->retain();
_bodyA->_joints.push_back(this);
}
if (b != nullptr)
{
_bodyB = b;
_bodyB->retain();
_bodyB->_joints.push_back(this);
}
return true;
} while (false);

View File

@ -44,14 +44,20 @@ typedef struct PhysicsMaterial
float restitution;
float friction;
static PhysicsMaterial make(float density, float restitution, float friction)
{
PhysicsMaterial var = {density, restitution, friction};
return var;
}
PhysicsMaterial()
: density(0.0f)
, restitution(0.0f)
, friction(0.0f)
{}
PhysicsMaterial(float density, float restitution, float friction)
: density(density)
, restitution(restitution)
, friction(friction)
{}
}PhysicsMaterial;
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT = {0.0f, 1.0f, 1.0f};
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT(0.0f, 1.0f, 1.0f);
/**
* @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it.

View File

@ -88,6 +88,7 @@ public:
static void collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, PhysicsWorld *world);
static void rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect n, RayCastCallbackInfo *info);
static void rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info);
static void nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr);
public:
static bool continues;
@ -166,6 +167,15 @@ void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallba
info->data);
}
void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr)
{
auto it = PhysicsShapeInfo::map.find(shape);
CC_ASSERT(it != PhysicsShapeInfo::map.end());
arr->addObject(it->second->shape);
}
bool PhysicsWorld::init()
{
_info = new PhysicsWorldInfo();
@ -561,9 +571,30 @@ void PhysicsWorld::rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void
}
}
Array* getShapesAtPoint(Point point)
Array* PhysicsWorld::getShapesAtPoint(Point point)
{
Array* arr = Array::create();
cpSpaceNearestPointQuery(this->_info->space,
PhysicsHelper::point2cpv(point),
0,
CP_ALL_LAYERS,
CP_NO_GROUP,
(cpSpaceNearestPointQueryFunc)PhysicsWorldCallback::nearestPointQueryFunc,
arr);
return arr;
}
PhysicsShape* PhysicsWorld::getShapeAtPoint(Point point)
{
cpShape* shape = cpSpaceNearestPointQueryNearest(this->_info->space,
PhysicsHelper::point2cpv(point),
0,
CP_ALL_LAYERS,
CP_NO_GROUP,
nullptr);
return shape == nullptr ? nullptr : PhysicsShapeInfo::map.find(shape)->second->shape;
}
Array* PhysicsWorld::getAllBody() const

View File

@ -98,6 +98,7 @@ public:
void rayCast(PhysicsRayCastCallback& callback, Point point1, Point point2, void* data);
void rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data);
Array* getShapesAtPoint(Point point);
PhysicsShape* getShapeAtPoint(Point point);
Array* getAllBody() const;
/** Register a listener to receive contact callbacks*/

@ -1 +1 @@
Subproject commit 893da8ccfb4ed7fa754c483a90dc4e5248c36e03
Subproject commit f399ed22077b04a757a1b5613acf20bfdf7796b7

View File

@ -8,65 +8,34 @@ LOCAL_MODULE_FILENAME := libcocos2dxjsb
LOCAL_SRC_FILES := ScriptingCore.cpp \
cocos2d_specifics.cpp \
jsb_cocos2dx_extension_manual.cpp \
js_manual_conversions.cpp \
cocosjs_manual_conversions.cpp \
js_bindings_chipmunk_manual.cpp \
js_bindings_chipmunk_functions.cpp \
js_bindings_chipmunk_auto_classes.cpp \
js_bindings_chipmunk_registration.cpp \
js_bindings_system_functions.cpp \
js_bindings_system_registration.cpp \
js_bindings_ccbreader.cpp \
js_bindings_core.cpp \
js_bindings_opengl.cpp \
jsb_opengl_functions.cpp \
jsb_opengl_manual.cpp \
jsb_opengl_registration.cpp \
../../auto-generated/js-bindings/jsb_cocos2dx_auto.cpp \
../../auto-generated/js-bindings/jsb_cocos2dx_extension_auto.cpp \
XMLHTTPRequest.cpp \
jsb_websocket.cpp
../../auto-generated/js-bindings/jsb_cocos2dx_auto.cpp
LOCAL_CFLAGS := -DCOCOS2D_JAVASCRIPT
LOCAL_EXPORT_CFLAGS := -DCOCOS2D_JAVASCRIPT
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/../../../CocosDenshion/include \
$(LOCAL_PATH)/../../../audio/include \
$(LOCAL_PATH)/../../../storage \
$(LOCAL_PATH)/../../auto-generated/js-bindings \
$(LOCAL_PATH)/../../../../extensions \
$(LOCAL_PATH)/../../../editor-support/cocostudio \
$(LOCAL_PATH)/../../../editor-support/cocosbuilder
$(LOCAL_PATH)/../../../../extensions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/../../auto-generated/js-bindings
$(LOCAL_PATH)/../../auto-generated/js-bindings \
$(LOCAL_PATH)/../../../audio/include
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += spidermonkey_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static
LOCAL_WHOLE_STATIC_LIBRARIES += spine_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_localstorage_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static
LOCAL_WHOLE_STATIC_LIBRARIES += websockets_static
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module,spidermonkey/prebuilt/android)
$(call import-module,extensions)
$(call import-module,2d)
$(call import-module,extensions)
$(call import-module,editor-support/cocosbuilder)
$(call import-module,editor-support/spine)
$(call import-module,network)
$(call import-module,chipmunk)
$(call import-module,storage/local-storage)
$(call import-module,editor-support/cocostudio)
$(call import-module,websockets/prebuilt/android)

View File

@ -54,9 +54,9 @@
#define BYTE_CODE_FILE_EXT ".jsc"
static string inData;
static string outData;
static vector<string> g_queue;
static std::string inData;
static std::string outData;
static std::vector<std::string> g_queue;
static std::mutex g_qMutex;
static std::mutex g_rwMutex;
static int clientSocket = -1;
@ -79,7 +79,6 @@ static std::map<int,int> ports_sockets;
// name ~> globals
static std::map<std::string, js::RootedObject*> globals;
static void ReportException(JSContext *cx)
{
if (JS_IsExceptionPending(cx)) {
@ -176,6 +175,8 @@ void ScriptingCore::executeJSFunctionWithThisObj(jsval thisObj,
{
if (callback != JSVAL_VOID || thisObj != JSVAL_VOID)
{
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
// Very important: The last parameter 'retVal' passed to 'JS_CallFunctionValue' should not be a NULL pointer.
// If it's a NULL pointer, crash will be triggered in 'JS_CallFunctionValue'. To find out the reason of this crash is very difficult.
// So we have to check the availability of 'retVal'.
@ -300,13 +301,13 @@ JSBool JSB_core_restartVM(JSContext *cx, uint32_t argc, jsval *vp)
void registerDefaultClasses(JSContext* cx, JSObject* global) {
// first, try to get the ns
jsval nsval;
JS::RootedValue nsval(cx);
JSObject *ns;
JS_GetProperty(cx, global, "cc", &nsval);
if (nsval == JSVAL_VOID) {
ns = JS_NewObject(cx, NULL, NULL, NULL);
nsval = OBJECT_TO_JSVAL(ns);
JS_SetProperty(cx, global, "cc", &nsval);
JS_SetProperty(cx, global, "cc", nsval);
} else {
JS_ValueToObject(cx, nsval, &ns);
}
@ -315,8 +316,9 @@ void registerDefaultClasses(JSContext* cx, JSObject* global) {
// Javascript controller (__jsc__)
//
JSObject *jsc = JS_NewObject(cx, NULL, NULL, NULL);
jsval jscVal = OBJECT_TO_JSVAL(jsc);
JS_SetProperty(cx, global, "__jsc__", &jscVal);
JS::RootedValue jscVal(cx);
jscVal = OBJECT_TO_JSVAL(jsc);
JS_SetProperty(cx, global, "__jsc__", jscVal);
JS_DefineFunction(cx, jsc, "garbageCollect", ScriptingCore::forceGC, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE );
JS_DefineFunction(cx, jsc, "dumpRoot", ScriptingCore::dumpRoot, 0, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE );
@ -451,6 +453,11 @@ void ScriptingCore::createGlobalContext() {
this->_cx = NULL;
this->_rt = NULL;
}
// Start the engine. Added in SpiderMonkey v25
if (!JS_Init())
return;
// Removed from Spidermonkey 19.
//JS_SetCStringsAreUTF8();
this->_rt = JS_NewRuntime(8L * 1024L * 1024L, JS_USE_HELPER_THREADS);
@ -461,13 +468,15 @@ void ScriptingCore::createGlobalContext() {
JS_SetNativeStackQuota(_rt, JSB_MAX_STACK_QUOTA);
this->_cx = JS_NewContext(_rt, 8192);
JS_SetOptions(this->_cx, JSOPTION_TYPE_INFERENCE);
JS_SetVersion(this->_cx, JSVERSION_LATEST);
// JS_SetVersion(this->_cx, JSVERSION_LATEST);
// Only disable METHODJIT on iOS.
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT);
JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT_ALWAYS);
// JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT);
// JS_SetOptions(this->_cx, JS_GetOptions(this->_cx) & ~JSOPTION_METHODJIT_ALWAYS);
#endif
JS_SetErrorReporter(this->_cx, ScriptingCore::reportError);
@ -476,6 +485,9 @@ void ScriptingCore::createGlobalContext() {
#endif
this->_global = NewGlobalObject(_cx);
JSAutoCompartment ac(_cx, _global);
js::SetDefaultObjectForContext(_cx, _global);
for (std::vector<sc_register_sth>::iterator it = registrationList.begin(); it != registrationList.end(); it++) {
sc_register_sth callback = *it;
callback(this->_cx, this->_global);
@ -500,17 +512,18 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c
cocos2d::FileUtils *futil = cocos2d::FileUtils::getInstance();
std::string fullPath = futil->fullPathForFilename(path);
if (global == NULL) {
global = _global;
}
if (cx == NULL) {
cx = _cx;
}
JSScript *script = NULL;
JSAutoCompartment ac(cx, global);
js::RootedScript script(cx);
js::RootedObject obj(cx, global);
JS::CompileOptions options(cx);
options.setUTF8(true).setFileAndLine(fullPath.c_str(), 1);
// a) check jsc file first
std::string byteCodePath = RemoveFileExt(std::string(path)) + BYTE_CODE_FILE_EXT;
@ -529,6 +542,10 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c
/* Clear any pending exception from previous failed decoding. */
ReportException(cx);
std::string fullPath = futil->fullPathForFilename(path);
JS::CompileOptions options(cx);
options.setUTF8(true).setFileAndLine(fullPath.c_str(), 1);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
String* content = String::createWithContentsOfFile(path);
if (content) {
@ -659,7 +676,7 @@ JSBool ScriptingCore::executeScript(JSContext *cx, uint32_t argc, jsval *vp)
return JS_FALSE;
}
} else {
JSObject* glob = JS_GetGlobalForScopeChain(cx);
JSObject* glob = JS::CurrentGlobalOrNull(cx);
res = ScriptingCore::getInstance()->runScript(path, glob);
}
return res;
@ -925,8 +942,8 @@ JSBool ScriptingCore::executeFunctionWithOwner(jsval owner, const char *name, ui
{
JSBool bRet = JS_FALSE;
JSBool hasAction;
jsval temp_retval;
JSContext* cx = this->_cx;
JS::RootedValue temp_retval(cx);
JSObject* obj = JSVAL_TO_OBJECT(owner);
do
@ -1061,6 +1078,8 @@ int ScriptingCore::executeCustomTouchesEvent(EventTouch::EventCode eventType,
int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
Touch *pTouch, JSObject *obj)
{
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
jsval retval;
std::string funcName;
getTouchFuncName(eventType, funcName);
@ -1081,6 +1100,7 @@ int ScriptingCore::executeCustomTouchEvent(EventTouch::EventCode eventType,
Touch *pTouch, JSObject *obj,
jsval &retval)
{
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
std::string funcName;
getTouchFuncName(eventType, funcName);
@ -1213,7 +1233,8 @@ JSBool jsval_to_std_string(JSContext *cx, jsval v, std::string* ret) {
JSBool jsval_to_ccpoint(JSContext *cx, jsval v, Point* ret) {
JSObject *tmp;
jsval jsx, jsy;
JS::RootedValue jsx(cx);
JS::RootedValue jsy(cx);
double x, y;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1231,7 +1252,11 @@ JSBool jsval_to_ccpoint(JSContext *cx, jsval v, Point* ret) {
JSBool jsval_to_ccacceleration(JSContext* cx,jsval v, Acceleration* ret) {
JSObject *tmp;
jsval jsx, jsy, jsz, jstimestamp;
JS::RootedValue jsx(cx);
JS::RootedValue jsy(cx);
JS::RootedValue jsz(cx);
JS::RootedValue jstimestamp(cx);
double x, y, timestamp, z;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1292,7 +1317,11 @@ JSBool jsvals_variadic_to_ccarray( JSContext *cx, jsval *vp, int argc, Array** r
JSBool jsval_to_ccrect(JSContext *cx, jsval v, Rect* ret) {
JSObject *tmp;
jsval jsx, jsy, jswidth, jsheight;
JS::RootedValue jsx(cx);
JS::RootedValue jsy(cx);
JS::RootedValue jswidth(cx);
JS::RootedValue jsheight(cx);
double x, y, width, height;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1316,7 +1345,8 @@ JSBool jsval_to_ccrect(JSContext *cx, jsval v, Rect* ret) {
JSBool jsval_to_ccsize(JSContext *cx, jsval v, Size* ret) {
JSObject *tmp;
jsval jsw, jsh;
JS::RootedValue jsw(cx);
JS::RootedValue jsh(cx);
double w, h;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1333,7 +1363,11 @@ JSBool jsval_to_ccsize(JSContext *cx, jsval v, Size* ret) {
JSBool jsval_to_cccolor4b(JSContext *cx, jsval v, Color4B* ret) {
JSObject *tmp;
jsval jsr, jsg, jsb, jsa;
JS::RootedValue jsr(cx);
JS::RootedValue jsg(cx);
JS::RootedValue jsb(cx);
JS::RootedValue jsa(cx);
double r, g, b, a;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1357,7 +1391,10 @@ JSBool jsval_to_cccolor4b(JSContext *cx, jsval v, Color4B* ret) {
JSBool jsval_to_cccolor4f(JSContext *cx, jsval v, Color4F* ret) {
JSObject *tmp;
jsval jsr, jsg, jsb, jsa;
JS::RootedValue jsr(cx);
JS::RootedValue jsg(cx);
JS::RootedValue jsb(cx);
JS::RootedValue jsa(cx);
double r, g, b, a;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1380,7 +1417,9 @@ JSBool jsval_to_cccolor4f(JSContext *cx, jsval v, Color4F* ret) {
JSBool jsval_to_cccolor3b(JSContext *cx, jsval v, Color3B* ret) {
JSObject *tmp;
jsval jsr, jsg, jsb;
JS::RootedValue jsr(cx);
JS::RootedValue jsg(cx);
JS::RootedValue jsb(cx);
double r, g, b;
JSBool ok = v.isObject() &&
JS_ValueToObject(cx, v, &tmp) &&
@ -1554,7 +1593,7 @@ jsval ccdictionary_to_jsval(JSContext* cx, Dictionary* dict)
DictElement* pElement = NULL;
CCDICT_FOREACH(dict, pElement)
{
jsval dictElement;
JS::RootedValue dictElement(cx);
Object* obj = pElement->getObject();
//First, check whether object is associated with js object.
js_proxy_t* jsproxy = js_get_or_create_proxy<cocos2d::Object>(cx, obj);
@ -1591,7 +1630,7 @@ jsval ccdictionary_to_jsval(JSContext* cx, Dictionary* dict)
const char* key = pElement->getStrKey();
if (key && strlen(key) > 0)
{
JS_SetProperty(cx, jsRet, key, &dictElement);
JS_SetProperty(cx, jsRet, key, dictElement);
}
}
return OBJECT_TO_JSVAL(jsRet);
@ -1635,7 +1674,7 @@ JSBool jsval_to_ccdictionary(JSContext* cx, jsval v, Dictionary** ret) {
dict = Dictionary::create();
}
jsval value;
JS::RootedValue value(cx);
JS_GetPropertyById(cx, tmp, idp, &value);
if (value.isObject())
{
@ -1699,7 +1738,12 @@ JSBool jsval_to_ccdictionary(JSContext* cx, jsval v, Dictionary** ret) {
JSBool jsval_to_ccaffinetransform(JSContext* cx, jsval v, AffineTransform* ret)
{
JSObject *tmp;
jsval jsa, jsb, jsc, jsd, jstx, jsty;
JS::RootedValue jsa(cx);
JS::RootedValue jsb(cx);
JS::RootedValue jsc(cx);
JS::RootedValue jsd(cx);
JS::RootedValue jstx(cx);
JS::RootedValue jsty(cx);
double a, b, c, d, tx, ty;
JSBool ok = JS_ValueToObject(cx, v, &tmp) &&
JS_GetProperty(cx, tmp, "a", &jsa) &&
@ -1752,6 +1796,8 @@ jsval c_string_to_jsval(JSContext* cx, const char* v, size_t length /* = -1 */)
return JSVAL_NULL;
}
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
if (0 == length)
{
auto emptyStr = JS_NewStringCopyZ(cx, "");
@ -1925,8 +1971,8 @@ void SimpleRunLoop::update(float dt)
while (size > 0)
{
g_qMutex.lock();
vector<string>::iterator first = g_queue.begin();
string str = *first;
auto first = g_queue.begin();
std::string str = *first;
g_queue.erase(first);
size = g_queue.size();
g_qMutex.unlock();
@ -1935,7 +1981,7 @@ void SimpleRunLoop::update(float dt)
}
}
void ScriptingCore::debugProcessInput(string str)
void ScriptingCore::debugProcessInput(const std::string& str)
{
JSAutoCompartment ac(_cx, _debugGlobal);
@ -1955,8 +2001,8 @@ static bool NS_ProcessNextEvent()
while (size > 0)
{
g_qMutex.lock();
vector<string>::iterator first = g_queue.begin();
string str = *first;
auto first = g_queue.begin();
std::string str = *first;
g_queue.erase(first);
size = g_queue.size();
g_qMutex.unlock();
@ -2021,7 +2067,7 @@ static void _clientSocketWriteAndClearString(std::string& s)
s.clear();
}
static void processInput(string data) {
static void processInput(const std::string& data) {
std::lock_guard<std::mutex> lk(g_qMutex);
g_queue.push_back(data);
}
@ -2048,7 +2094,7 @@ static void serverEntryPoint(void)
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
stringstream portstr;
std::stringstream portstr;
portstr << JSB_DEBUGGER_PORT;
int err = 0;
@ -2145,11 +2191,12 @@ JSBool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp)
void ScriptingCore::enableDebugger()
{
JS_SetDebugMode(_cx, JS_TRUE);
if (_debugGlobal == NULL)
{
JSAutoCompartment ac0(_cx, _global);
JS_SetDebugMode(_cx, JS_TRUE);
_debugGlobal = NewGlobalObject(_cx, true);
JS_WrapObject(_cx, &_debugGlobal);
JSAutoCompartment ac(_cx, _debugGlobal);
@ -2182,7 +2229,10 @@ void ScriptingCore::enableDebugger()
JSObject* NewGlobalObject(JSContext* cx, bool debug)
{
JSObject* glob = JS_NewGlobalObject(cx, &global_class, NULL);
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
JS::RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL, JS::DontFireOnNewGlobalHook, options));
if (!glob) {
return NULL;
}
@ -2196,6 +2246,8 @@ JSObject* NewGlobalObject(JSContext* cx, bool debug)
if (!ok)
return NULL;
JS_FireOnNewGlobalObject(cx, glob);
return glob;
}
@ -2251,7 +2303,7 @@ void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy)
static Color3B getColorFromJSObject(JSContext *cx, JSObject *colorObject)
{
jsval jsr;
JS::RootedValue jsr(cx);
Color3B out;
JS_GetProperty(cx, colorObject, "r", &jsr);
double fontR = 0.0;
@ -2275,7 +2327,7 @@ static Color3B getColorFromJSObject(JSContext *cx, JSObject *colorObject)
Size getSizeFromJSObject(JSContext *cx, JSObject *sizeObject)
{
jsval jsr;
JS::RootedValue jsr(cx);
Size out;
JS_GetProperty(cx, sizeObject, "width", &jsr);
double width = 0.0;
@ -2316,7 +2368,7 @@ JSBool jsval_to_FontDefinition( JSContext *cx, jsval vp, FontDefinition *out )
out->_fontFillColor = Color3B::WHITE;
// font name
jsval jsr;
JS::RootedValue jsr(cx);
JS_GetProperty(cx, jsobj, "fontName", &jsr);
JS_ValueToString(cx, jsr);
JSStringWrapper wrapper(jsr);

View File

@ -21,7 +21,6 @@
void js_log(const char *format, ...);
using namespace cocos2d;
using namespace std;
typedef void (*sc_register_sth)(JSContext* cx, JSObject* global);
@ -189,7 +188,7 @@ public:
/**
* enable the debug environment
*/
void debugProcessInput(string str);
void debugProcessInput(const std::string& str);
void enableDebugger();
JSObject* getDebugGlobal() { return _debugGlobal; }
JSObject* getGlobalObject() { return _global; }
@ -230,7 +229,7 @@ JSBool jsval_to_FontDefinition( JSContext *cx, jsval vp, FontDefinition* ret );
jsval int32_to_jsval( JSContext *cx, int32_t l);
jsval uint32_to_jsval( JSContext *cx, uint32_t number );
jsval long_long_to_jsval(JSContext* cx, long long v);
jsval std_string_to_jsval(JSContext* cx, const string& v);
jsval std_string_to_jsval(JSContext* cx, const std::string& v);
jsval c_string_to_jsval(JSContext* cx, const char* v, size_t length = -1);
jsval ccpoint_to_jsval(JSContext* cx, const Point& v);
jsval ccrect_to_jsval(JSContext* cx, const Rect& v);

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