Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into develop_new_fix

This commit is contained in:
samuele3hu 2014-03-04 10:27:25 +08:00
commit 987afe2272
349 changed files with 2951 additions and 13782 deletions

View File

@ -770,6 +770,12 @@ Developers:
seemk
Fixed crash if invoking Director::end() on WINDOWS.
odedsh
Fixed a bug that loading custom fonts from ttf file fails on windows.
Wilhansen
Fixed a bug that spine::Skeleton would not be updated after re-adding to scene.
Retired Core Developers:
WenSheng Yang

View File

@ -3,6 +3,8 @@ cocos2d-x-3.0rc0 Feb.?? 2014
[NEW] Action: RotateBy supports 3D rotations
[NEW] Bindings: Using python to automatically generate script bindings
[NEW] Bindings: Added JS bindings support for Linux
[NEW] ccConfig.h: removed support for CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
[NEW] Console: Added command: 'autotest run|main|next|back|restart'.
[NEW] Console: Added 'resolution', 'projection' commands. Improved API
[NEW] Console: Added more commands: director resume|pause|stopanimation|startanimation.
[NEW] Console: Added command: 'touch tap|swipe' to simulating touch events.
@ -13,9 +15,13 @@ cocos2d-x-3.0rc0 Feb.?? 2014
Node: set/get VertexZ() -> set/get PositionZ()
Node: setRotationX() -> setRotationSkewX()
Node: setRotationY() -> setRotationSkewY()
Node: visit() and draw() new arguments: Renderer, parentTransform, and whether or not the parentTransform has changed since the last frame
[NEW] Language: Added Dutch support.
[NEW] Sprite: Added auto-culling support
[NEW] Sprite: Added auto-culling support. Performance increased in about 100% when many sprites are outside the screen
[FIX] EditBox's position would not be updated if its parent's position changed.
[FIX] spine::Skeleton would not be updated after being re-added to scene.
[FIX] Loading custom fonts from ttf file fails on windows.
[FIX] FadeIn and FadeOut behaviours is incorrect if it doesn't start from an edge value( 0 or 255).
[FIX] Renderer: Expand textureID bit from 18bits to 32bits. Resolves probably crash on Linux / Android.
[FIX] Potential crash by switching repeatly between HttpClientTest, WebSocketTest, SocketIOTest.
@ -45,6 +51,8 @@ cocos2d-x-3.0rc0 Feb.?? 2014
[FIX] EGLView improvements: renamed to GLView, no longer a singleton, easier to customize
[FIX] Removes samples except testcpp|testjavascript|testlua. Moves sample games to `cocos2d/samples` repo.
[FIX] cc.BuilderReader.load( path, null, parentSize ); was not allowed.
[FIX] Node: setAdditionalTransform receives a pointer and not a const reference
cocos2d-x-3.0beta2 Jan.24 2014
[All]

View File

@ -1 +1 @@
3e5af93e674100c3fcff441051ba5d9d6f3be7bb
8fad051dc33d390c01df304fee2a78e22785136f

View File

@ -122,7 +122,7 @@ void ActionCamera::updateTransform()
// But that operation needs to be done after all the 'updates'.
// So the Director should emit an 'director_after_update' event.
// And this object should listen to it
_target->setAdditionalTransform(mv);
_target->setAdditionalTransform(&mv);
}
//

View File

@ -35,7 +35,6 @@ THE SOFTWARE.
#include "CCDirector.h"
#include "TransformUtils.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCQuadCommand.h"
// external
#include "kazmath/GL/matrix.h"
@ -110,8 +109,7 @@ bool AtlasNode::initWithTexture(Texture2D* texture, int tileWidth, int tileHeigh
_quadsToDraw = itemsToRender;
// shader stuff
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_U_COLOR));
_uniformColor = glGetUniformLocation( getShaderProgram()->getProgram(), "u_color");
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
return true;
}
@ -138,30 +136,18 @@ void AtlasNode::updateAtlasValues()
}
// AtlasNode - draw
void AtlasNode::draw(void)
void AtlasNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
// CC_NODE_DRAW_SETUP();
//
// GL::blendFunc( _blendFunc.src, _blendFunc.dst );
//
// GLfloat colors[4] = {_displayedColor.r / 255.0f, _displayedColor.g / 255.0f, _displayedColor.b / 255.0f, _displayedOpacity / 255.0f};
// getShaderProgram()->setUniformLocationWith4fv(_uniformColor, colors, 1);
//
// _textureAtlas->drawNumberOfQuads(_quadsToDraw, 0);
auto shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP);
_quadCommand.init(
_globalZOrder,
_textureAtlas->getTexture()->getName(),
shader,
_shaderProgram,
_blendFunc,
_textureAtlas->getQuads(),
_quadsToDraw,
_modelViewTransform);
transform);
Director::getInstance()->getRenderer()->addCommand(&_quadCommand);
renderer->addCommand(&_quadCommand);
}

View File

@ -69,7 +69,7 @@ public:
// Overrides
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual Texture2D* getTexture() const override;
virtual void setTexture(Texture2D *texture) override;
virtual bool isOpacityModifyRGB() const override;

View File

@ -199,17 +199,24 @@ void ClippingNode::drawFullScreenQuadClearStencil()
kmGLPopMatrix();
}
void ClippingNode::visit()
void ClippingNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if(!_visible)
return;
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
transform();
kmGLLoadMatrix(&_modelViewTransform);
//Add group command
Renderer* renderer = Director::getInstance()->getRenderer();
_groupCommand.init(_globalZOrder);
renderer->addCommand(&_groupCommand);
@ -236,7 +243,7 @@ void ClippingNode::visit()
#endif
}
_stencil->visit();
_stencil->visit(renderer, _modelViewTransform, dirty);
_afterDrawStencilCmd.init(_globalZOrder);
_afterDrawStencilCmd.func = CC_CALLBACK_0(ClippingNode::onAfterDrawStencil, this);
@ -253,19 +260,19 @@ void ClippingNode::visit()
auto node = _children.at(i);
if ( node && node->getLocalZOrder() < 0 )
node->visit();
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
// self draw
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit();
(*it)->visit(renderer, _modelViewTransform, dirty);
}
else
{
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
}
_afterVisitCmd.init(_globalZOrder);

View File

@ -95,7 +95,7 @@ public:
* @lua NA
*/
virtual void onExit() override;
virtual void visit() override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
protected:
ClippingNode();

View File

@ -140,9 +140,7 @@ bool Director::init(void)
_scheduler = new Scheduler();
// action manager
_actionManager = new ActionManager();
_scheduler->scheduleUpdate([this](float dt){
this->_actionManager->update(dt);
}, _actionManager, Scheduler::PRIORITY_SYSTEM, false);
_scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);
_eventDispatcher = new EventDispatcher();
_eventAfterDraw = new EventCustom(EVENT_AFTER_DRAW);
@ -275,17 +273,21 @@ void Director::drawScene()
kmGLPushMatrix();
// global identity matrix is needed... come on kazmath!
kmMat4 identity;
kmMat4Identity(&identity);
// draw the scene
if (_runningScene)
{
_runningScene->visit();
_runningScene->visit(_renderer, identity, false);
_eventDispatcher->dispatchEvent(_eventAfterVisit);
}
// draw the notifications node
if (_notificationNode)
{
_notificationNode->visit();
_notificationNode->visit(_renderer, identity, false);
}
if (_displayStats)
@ -870,9 +872,13 @@ void Director::showStats()
prevVerts = currentVerts;
}
_drawnVerticesLabel->visit();
_drawnBatchesLabel->visit();
_FPSLabel->visit();
// global identity matrix is needed... come on kazmath!
kmMat4 identity;
kmMat4Identity(&identity);
_drawnVerticesLabel->visit(_renderer, identity, false);
_drawnBatchesLabel->visit(_renderer, identity, false);
_FPSLabel->visit(_renderer, identity, false);
}
}

View File

@ -239,11 +239,11 @@ void DrawNode::render()
CHECK_GL_ERROR_DEBUG();
}
void DrawNode::draw()
void DrawNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
}
void DrawNode::onDraw()

View File

@ -92,7 +92,7 @@ public:
void onDraw();
// Overrides
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
DrawNode();

View File

@ -33,6 +33,7 @@
#include "CCNode.h"
#include "CCDirector.h"
#include "CCEventType.h"
#include <algorithm>
@ -184,10 +185,18 @@ EventDispatcher::EventDispatcher()
, _nodePriorityIndex(0)
{
_toAddedListeners.reserve(50);
// fixed #4129: Mark the following listener IDs for internal use.
// Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
_internalCustomListenerIDs.insert(EVENT_COME_TO_FOREGROUND);
_internalCustomListenerIDs.insert(EVENT_COME_TO_BACKGROUND);
}
EventDispatcher::~EventDispatcher()
{
// Clear internal custom listener IDs from set,
// so removeAllEventListeners would clean internal custom listeners.
_internalCustomListenerIDs.clear();
removeAllEventListeners();
}
@ -258,9 +267,9 @@ void EventDispatcher::visitTarget(Node* node, bool isRootNode)
}
}
void EventDispatcher::pauseTarget(Node* node)
void EventDispatcher::pauseEventListenersForTarget(Node* target, bool recursive/* = false */)
{
auto listenerIter = _nodeListenersMap.find(node);
auto listenerIter = _nodeListenersMap.find(target);
if (listenerIter != _nodeListenersMap.end())
{
auto listeners = listenerIter->second;
@ -269,11 +278,20 @@ void EventDispatcher::pauseTarget(Node* node)
l->setPaused(true);
}
}
if (recursive)
{
const auto& children = target->getChildren();
for (const auto& child : children)
{
pauseEventListenersForTarget(child, true);
}
}
}
void EventDispatcher::resumeTarget(Node* node)
void EventDispatcher::resumeEventListenersForTarget(Node* target, bool recursive/* = false */)
{
auto listenerIter = _nodeListenersMap.find(node);
auto listenerIter = _nodeListenersMap.find(target);
if (listenerIter != _nodeListenersMap.end())
{
auto listeners = listenerIter->second;
@ -282,12 +300,21 @@ void EventDispatcher::resumeTarget(Node* node)
l->setPaused(false);
}
}
setDirtyForNode(node);
setDirtyForNode(target);
if (recursive)
{
const auto& children = target->getChildren();
for (const auto& child : children)
{
resumeEventListenersForTarget(child, true);
}
}
}
void EventDispatcher::cleanTarget(Node* node)
void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive/* = false */)
{
auto listenerIter = _nodeListenersMap.find(node);
auto listenerIter = _nodeListenersMap.find(target);
if (listenerIter != _nodeListenersMap.end())
{
auto listeners = listenerIter->second;
@ -297,6 +324,15 @@ void EventDispatcher::cleanTarget(Node* node)
removeEventListener(l);
}
}
if (recursive)
{
const auto& children = target->getChildren();
for (const auto& child : children)
{
removeEventListenersForTarget(child, true);
}
}
}
void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener)
@ -355,12 +391,12 @@ void EventDispatcher::forceAddEventListener(EventListener* listener)
{
EventListenerVector* listeners = nullptr;
EventListener::ListenerID listenerID = listener->getListenerID();
auto itr = _listeners.find(listenerID);
if (itr == _listeners.end())
auto itr = _listenerMap.find(listenerID);
if (itr == _listenerMap.end())
{
listeners = new EventListenerVector();
_listeners.insert(std::make_pair(listenerID, listeners));
_listenerMap.insert(std::make_pair(listenerID, listeners));
}
else
{
@ -380,7 +416,7 @@ void EventDispatcher::forceAddEventListener(EventListener* listener)
if (node->isRunning())
{
resumeTarget(node);
resumeEventListenersForTarget(node);
}
}
else
@ -421,7 +457,7 @@ void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener,
addEventListener(listener);
}
EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, std::function<void(EventCustom*)> callback)
EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback)
{
EventListenerCustom *listener = EventListenerCustom::create(eventName, callback);
addEventListenerWithFixedPriority(listener, 1);
@ -434,7 +470,7 @@ void EventDispatcher::removeEventListener(EventListener* listener)
return;
bool isFound = false;
auto removeListenerInVector = [&](std::vector<EventListener*>* listeners){
if (listeners == nullptr)
return;
@ -463,23 +499,32 @@ void EventDispatcher::removeEventListener(EventListener* listener)
}
};
for (auto iter = _listeners.begin(); iter != _listeners.end();)
for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
{
auto listeners = iter->second;
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
removeListenerInVector(sceneGraphPriorityListeners);
if (!isFound)
if (isFound)
{
// fixed #4160: Dirty flag need to be updated after listeners were removed.
setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
}
else
{
removeListenerInVector(fixedPriorityListeners);
if (isFound)
{
setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
}
}
if (iter->second->empty())
{
_priorityDirtyFlagMap.erase(listener->getListenerID());
auto list = iter->second;
iter = _listeners.erase(iter);
iter = _listenerMap.erase(iter);
CC_SAFE_DELETE(list);
}
else
@ -514,7 +559,7 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority)
if (listener == nullptr)
return;
for (auto iter = _listeners.begin(); iter != _listeners.end(); ++iter)
for (auto iter = _listenerMap.begin(); iter != _listenerMap.end(); ++iter)
{
auto fixedPriorityListeners = iter->second->getFixedPriorityListeners();
if (fixedPriorityListeners)
@ -535,7 +580,7 @@ void EventDispatcher::setPriority(EventListener* listener, int fixedPriority)
}
}
void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, std::function<bool(EventListener*)> onEvent)
void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent)
{
bool shouldStopPropagation = false;
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
@ -545,14 +590,18 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, s
// priority < 0
if (fixedPriorityListeners)
{
bool isEmpty = fixedPriorityListeners->empty();
for (; !isEmpty && i < listeners->getGt0Index(); ++i)
CCASSERT(listeners->getGt0Index() <= fixedPriorityListeners->size(), "Out of range exception!");
if (!fixedPriorityListeners->empty())
{
auto l = fixedPriorityListeners->at(i);
if (!l->isPaused() && l->isRegistered() && onEvent(l))
for (; i < listeners->getGt0Index(); ++i)
{
shouldStopPropagation = true;
break;
auto l = fixedPriorityListeners->at(i);
if (!l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
@ -613,8 +662,8 @@ void EventDispatcher::dispatchEvent(Event* event)
sortEventListeners(listenerID);
auto iter = _listeners.find(listenerID);
if (iter != _listeners.end())
auto iter = _listenerMap.find(listenerID);
if (iter != _listenerMap.end())
{
auto listeners = iter->second;
@ -652,7 +701,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event)
bool isNeedsMutableSet = (oneByOneListeners && allAtOnceListeners);
std::vector<Touch*> originalTouches = event->getTouches();
const std::vector<Touch*>& originalTouches = event->getTouches();
std::vector<Touch*> mutableTouches(originalTouches.size());
std::copy(originalTouches.begin(), originalTouches.end(), mutableTouches.begin());
@ -835,8 +884,8 @@ void EventDispatcher::updateListeners(Event* event)
{
auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID)
{
auto listenersIter = _listeners.find(listenerID);
if (listenersIter == _listeners.end())
auto listenersIter = _listenerMap.find(listenerID);
if (listenersIter == _listenerMap.end())
return;
auto listeners = listenersIter->second;
@ -891,7 +940,7 @@ void EventDispatcher::updateListeners(Event* event)
{
_priorityDirtyFlagMap.erase(listenersIter->first);
delete listenersIter->second;
_listeners.erase(listenersIter);
_listenerMap.erase(listenersIter);
}
};
@ -1027,8 +1076,8 @@ void EventDispatcher::sortEventListenersOfFixedPriority(const EventListener::Lis
EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const EventListener::ListenerID& listenerID)
{
auto iter = _listeners.find(listenerID);
if (iter != _listeners.end())
auto iter = _listenerMap.find(listenerID);
if (iter != _listenerMap.end())
{
return iter->second;
}
@ -1038,8 +1087,8 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const EventL
void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)
{
auto listenerItemIter = _listeners.find(listenerID);
if (listenerItemIter != _listeners.end())
auto listenerItemIter = _listenerMap.find(listenerID);
if (listenerItemIter != _listenerMap.end())
{
auto listeners = listenerItemIter->second;
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
@ -1073,12 +1122,15 @@ void EventDispatcher::removeEventListenersForListenerID(const EventListener::Lis
removeAllListenersInVector(sceneGraphPriorityListeners);
removeAllListenersInVector(fixedPriorityListeners);
// Remove the dirty flag according the 'listenerID'.
// No need to check whether the dispatcher is dispatching event.
_priorityDirtyFlagMap.erase(listenerID);
if (!_inDispatch)
{
listeners->clear();
delete listeners;
_listeners.erase(listenerItemIter);
_priorityDirtyFlagMap.erase(listenerID);
_listenerMap.erase(listenerItemIter);
}
}
@ -1096,7 +1148,7 @@ void EventDispatcher::removeEventListenersForListenerID(const EventListener::Lis
}
}
void EventDispatcher::removeEventListeners(EventListener::Type listenerType)
void EventDispatcher::removeEventListenersForType(EventListener::Type listenerType)
{
if (listenerType == EventListener::Type::TOUCH_ONE_BY_ONE)
{
@ -1131,11 +1183,19 @@ void EventDispatcher::removeCustomEventListeners(const std::string& customEventN
void EventDispatcher::removeAllEventListeners()
{
std::vector<EventListener::ListenerID> types(_listeners.size());
for (const auto& e : _listeners)
bool cleanMap = true;
std::vector<EventListener::ListenerID> types(_listenerMap.size());
for (const auto& e : _listenerMap)
{
types.push_back(e.first);
if (_internalCustomListenerIDs.find(e.first) != _internalCustomListenerIDs.end())
{
cleanMap = false;
}
else
{
types.push_back(e.first);
}
}
for (const auto& type : types)
@ -1143,9 +1203,9 @@ void EventDispatcher::removeAllEventListeners()
removeEventListenersForListenerID(type);
}
if (!_inDispatch)
if (!_inDispatch && cleanMap)
{
_listeners.clear();
_listenerMap.clear();
}
}

View File

@ -56,6 +56,8 @@ dispatched.
class EventDispatcher : public Ref
{
public:
// Adds event listener
/** 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.
@ -76,22 +78,41 @@ public:
It will use a fixed priority of 1.
@return the generated event. Needed in order to remove the event from the dispather
*/
EventListenerCustom* addCustomEventListener(const std::string &eventName, std::function<void(EventCustom*)> callback);
EventListenerCustom* addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback);
/////////////////////////////////////////////
// Removes event listener
/** Remove a listener
* @param listener The specified event listener which needs to be removed.
*/
void removeEventListener(EventListener* listener);
/** Removes all listeners with the same event listener type */
void removeEventListeners(EventListener::Type listenerType);
void removeEventListenersForType(EventListener::Type listenerType);
/** Removes all listeners which are associated with the specified target. */
void removeEventListenersForTarget(Node* target, bool recursive = false);
/** Removes all custom listeners with the same event name */
void removeCustomEventListeners(const std::string& customEventName);
/** Removes all listeners */
void removeAllEventListeners();
/////////////////////////////////////////////
// Pauses / Resumes event listener
/** Pauses all listeners which are associated the specified target. */
void pauseEventListenersForTarget(Node* target, bool recursive = false);
/** Resumes all listeners which are associated the specified target. */
void resumeEventListenersForTarget(Node* target, bool recursive = false);
/////////////////////////////////////////////
/** Sets listener's priority with fixed value. */
void setPriority(EventListener* listener, int fixedPriority);
@ -101,6 +122,8 @@ public:
/** Checks whether dispatching events is enabled */
bool isEnabled() const;
/////////////////////////////////////////////
/** Dispatches the event
* Also removes all EventListeners marked for deletion from the
* event dispatcher list.
@ -108,8 +131,10 @@ public:
void dispatchEvent(Event* event);
/** Dispatches a Custom Event with a event name an optional user data */
void dispatchCustomEvent(const std::string &eventName, void *optionalUserData);
void dispatchCustomEvent(const std::string &eventName, void *optionalUserData = nullptr);
/////////////////////////////////////////////
/** Constructor of EventDispatcher */
EventDispatcher();
/** Destructor of EventDispatcher */
@ -121,15 +146,6 @@ protected:
/** 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.
*/
@ -202,7 +218,7 @@ protected:
void dissociateNodeAndEventListener(Node* node, EventListener* listener);
/** Dispatches event to listeners with a specified listener type */
void dispatchEventToListeners(EventListenerVector* listeners, std::function<bool(EventListener*)> onEvent);
void dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent);
/// Priority dirty flag
enum class DirtyFlag
@ -220,7 +236,7 @@ protected:
void visitTarget(Node* node, bool isRootNode);
/** Listeners map */
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listeners;
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
/** The map of dirty flag */
std::unordered_map<EventListener::ListenerID, DirtyFlag> _priorityDirtyFlagMap;
@ -247,6 +263,8 @@ protected:
bool _isEnabled;
int _nodePriorityIndex;
std::set<std::string> _internalCustomListenerIDs;
};

View File

@ -48,8 +48,8 @@ public:
EventTouch();
EventCode getEventCode() { return _eventCode; };
std::vector<Touch*> getTouches() { return _touches; };
inline EventCode getEventCode() const { return _eventCode; };
inline const std::vector<Touch*>& getTouches() const { return _touches; };
#if TOUCH_PERF_DEBUG
void setEventCode(EventCode eventCode) { _eventCode = eventCode; };

View File

@ -679,24 +679,32 @@ void Label::onDraw()
CC_PROFILER_STOP("Label - draw");
}
void Label::draw()
void Label::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
}
void Label::visit()
void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (! _visible)
{
return;
}
kmGLPushMatrix();
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
transform();
draw();
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();

View File

@ -128,8 +128,8 @@ public:
void addChild(Node * child, int zOrder=0, int tag=0) override;
virtual std::string getDescription() const override;
virtual void visit() override;
virtual void draw(void) override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onDraw();
virtual FontAtlas* getFontAtlas() const {return _fontAtlas;}

View File

@ -581,11 +581,11 @@ void LayerColor::updateColor()
}
}
void LayerColor::draw()
void LayerColor::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(LayerColor::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
for(int i = 0; i < 4; ++i)
{

View File

@ -37,7 +37,6 @@ THE SOFTWARE.
#include "CCEventKeyboard.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCQuadCommand.h"
NS_CC_BEGIN
@ -266,7 +265,7 @@ public:
//
// Overrides
//
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onDraw();
virtual void setContentSize(const Size & var) override;

View File

@ -328,7 +328,7 @@ void MotionStreak::reset()
void MotionStreak::onDraw()
{
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(_cachedMV);
getShaderProgram()->setUniformsForBuiltins(_modelViewTransform);
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
@ -352,16 +352,16 @@ void MotionStreak::onDraw()
#endif // EMSCRIPTEN
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)_nuPoints*2);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _nuPoints*2);
}
void MotionStreak::draw()
void MotionStreak::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if(_nuPoints <= 1)
return;
kmGLGetMatrix(KM_GL_MODELVIEW,&_cachedMV);
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(MotionStreak::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
}

View File

@ -78,7 +78,7 @@ public:
* @js NA
* @lua NA
*/
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
/**
* @js NA
* @lua NA
@ -102,19 +102,9 @@ public:
virtual bool isOpacityModifyRGB() const override;
protected:
kmMat4 _cachedMV;
//renderer callback
void onDraw();
protected:
/**
* @js ctor
*/
MotionStreak();
/**
* @js NA
* @lua NA
*/
virtual ~MotionStreak();
/** initializes a motion streak with fade in seconds, minimum segments, stroke's width, color and texture filename */

View File

@ -92,6 +92,7 @@ Node::Node(void)
, _useAdditionalTransform(false)
, _transformDirty(true)
, _inverseDirty(true)
, _transformUpdated(true)
// children (lazy allocs)
// lazy alloc
, _localZOrder(0)
@ -156,7 +157,7 @@ Node::~Node()
CC_SAFE_RELEASE(_actionManager);
CC_SAFE_RELEASE(_scheduler);
_eventDispatcher->cleanTarget(this);
_eventDispatcher->removeEventListenersForTarget(this);
CC_SAFE_RELEASE(_eventDispatcher);
// attributes
@ -193,7 +194,7 @@ void Node::setSkewX(float skewX)
return;
_skewX = skewX;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
float Node::getSkewY() const
@ -207,7 +208,7 @@ void Node::setSkewY(float skewY)
return;
_skewY = skewY;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -255,8 +256,8 @@ void Node::setRotation(float rotation)
return;
_rotationZ_X = _rotationZ_Y = rotation;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsBody)
{
@ -277,7 +278,7 @@ void Node::setRotation3D(const Vertex3F& rotation)
_rotationZ_X == rotation.z)
return;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
_rotationX = rotation.x;
_rotationY = rotation.y;
@ -307,7 +308,7 @@ void Node::setRotationSkewX(float rotationX)
return;
_rotationZ_X = rotationX;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
float Node::getRotationSkewY() const
@ -321,7 +322,7 @@ void Node::setRotationSkewY(float rotationY)
return;
_rotationZ_Y = rotationY;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
/// scale getter
@ -336,9 +337,9 @@ void Node::setScale(float scale)
{
if (_scaleX == scale)
return;
_scaleX = _scaleY = scale;
_transformDirty = _inverseDirty = true;
_scaleX = _scaleY = _scaleZ = scale;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
/// scaleX getter
@ -355,7 +356,7 @@ void Node::setScale(float scaleX,float scaleY)
_scaleX = scaleX;
_scaleY = scaleY;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
/// scaleX setter
@ -365,7 +366,7 @@ void Node::setScaleX(float scaleX)
return;
_scaleX = scaleX;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
/// scaleY getter
@ -381,7 +382,7 @@ void Node::setScaleZ(float scaleZ)
return;
_scaleZ = scaleZ;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
/// scaleY getter
@ -397,7 +398,7 @@ void Node::setScaleY(float scaleY)
return;
_scaleY = scaleY;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -414,12 +415,14 @@ void Node::setPosition(const Point& position)
return;
_position = position;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setPosition(position);
Node* parent = getParent();
Point pos = parent != nullptr ? parent->convertToWorldSpace(getPosition()) : getPosition();
_physicsBody->setPosition(pos);
}
#endif
}
@ -480,7 +483,7 @@ void Node::setPositionZ(float positionZ)
if (_positionZ == positionZ)
return;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
_positionZ = positionZ;
@ -489,21 +492,6 @@ void Node::setPositionZ(float positionZ)
setGlobalZOrder(positionZ);
}
void Node::setNormalizedPosition(const cocos2d::Point &position)
{
_normalizedPosition = position;
Size s = Director::getInstance()->getVisibleSize();
Point p;
p.x = s.width * position.x;
p.y = s.height * position.y;
setPosition(p);
}
const Point& Node::getNormalizedPosition() const
{
return _normalizedPosition;
}
ssize_t Node::getChildrenCount() const
{
return _children.size();
@ -534,11 +522,19 @@ const Point& Node::getAnchorPoint() const
void Node::setAnchorPoint(const Point& point)
{
#if CC_USE_PHYSICS
if (_physicsBody != nullptr && !point.equals(Point::ANCHOR_MIDDLE))
{
CCLOG("Node warning: This node has a physics body, the anchor must be in the middle, you cann't change this to other value.");
return;
}
#endif
if( ! point.equals(_anchorPoint))
{
_anchorPoint = point;
_anchorPointInPoints = Point(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y );
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
}
@ -555,7 +551,7 @@ void Node::setContentSize(const Size & size)
_contentSize = size;
_anchorPointInPoints = Point(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y );
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
}
@ -582,7 +578,7 @@ void Node::ignoreAnchorPointForPosition(bool newValue)
if (newValue != _ignoreAnchorPointForPosition)
{
_ignoreAnchorPointForPosition = newValue;
_transformDirty = _inverseDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
}
@ -719,6 +715,11 @@ void Node::addChild(Node *child, int zOrder, int tag)
this->insertChild(child, zOrder);
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->setPosition(this->convertToWorldSpace(child->getPosition()));
}
for (Node* node = this->getParent(); node != nullptr; node = node->getParent())
{
if (dynamic_cast<Scene*>(node) != nullptr)
@ -899,26 +900,44 @@ void Node::sortAllChildren()
}
}
void Node::draw()
{
auto renderer = Director::getInstance()->getRenderer();
draw(renderer, _modelViewTransform, true);
}
void Node::draw()
{
//CCASSERT(0);
// override me
// Only use- this function to draw your stuff.
// DON'T draw your stuff outside this method
}
void Node::draw(Renderer* renderer, const kmMat4 &transform, bool transformUpdated)
{
}
void Node::visit()
{
auto renderer = Director::getInstance()->getRenderer();
kmMat4 parentTransform;
kmGLGetMatrix(KM_GL_MODELVIEW, &parentTransform);
visit(renderer, parentTransform, true);
}
void Node::visit(Renderer* renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
kmGLPushMatrix();
this->transform();
bool dirty = _transformUpdated || parentTransformUpdated;
if(dirty)
_modelViewTransform = this->transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
int i = 0;
if(!_children.empty())
@ -930,19 +949,19 @@ void Node::visit()
auto node = _children.at(i);
if ( node && node->_localZOrder < 0 )
node->visit();
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
// self draw
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit();
(*it)->visit(renderer, _modelViewTransform, dirty);
}
else
{
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
}
// reset for next frame
@ -951,23 +970,12 @@ void Node::visit()
kmGLPopMatrix();
}
void Node::transformAncestors()
kmMat4 Node::transform(const kmMat4& parentTransform)
{
if( _parent != nullptr )
{
_parent->transformAncestors();
_parent->transform();
}
}
kmMat4 ret = this->getNodeToParentTransform();
kmMat4Multiply(&ret, &parentTransform, &ret);
void Node::transform()
{
kmMat4 transfrom4x4 = this->getNodeToParentTransform();
kmGLMultMatrix( &transfrom4x4 );
// saves the MV matrix
kmGLGetMatrix(KM_GL_MODELVIEW, &_modelViewTransform);
return ret;
}
void Node::onEnter()
@ -1050,7 +1058,7 @@ void Node::setEventDispatcher(EventDispatcher* dispatcher)
{
if (dispatcher != _eventDispatcher)
{
_eventDispatcher->cleanTarget(this);
_eventDispatcher->removeEventListenersForTarget(this);
CC_SAFE_RETAIN(dispatcher);
CC_SAFE_RELEASE(_eventDispatcher);
_eventDispatcher = dispatcher;
@ -1115,7 +1123,7 @@ void Node::setScheduler(Scheduler* scheduler)
bool Node::isScheduled(SEL_SCHEDULE selector)
{
return _scheduler->isScheduled(this, schedule_selector_to_key(selector));
return _scheduler->isScheduled(selector, this);
}
void Node::scheduleUpdate()
@ -1125,9 +1133,7 @@ void Node::scheduleUpdate()
void Node::scheduleUpdateWithPriority(int priority)
{
_scheduler->scheduleUpdate([this](float dt){
this->update(dt);
}, this, priority, !_running);
_scheduler->scheduleUpdate(this, priority, !_running);
}
void Node::scheduleUpdateWithPriorityLua(int nHandler, int priority)
@ -1137,9 +1143,8 @@ void Node::scheduleUpdateWithPriorityLua(int nHandler, int priority)
#if CC_ENABLE_SCRIPT_BINDING
_updateScriptHandler = nHandler;
#endif
_scheduler->scheduleUpdate([this](float dt){
this->update(dt);
}, this, priority, !_running);
_scheduler->scheduleUpdate(this, priority, !_running);
}
void Node::unscheduleUpdate()
@ -1170,9 +1175,7 @@ void Node::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat,
CCASSERT( selector, "Argument must be non-nil");
CCASSERT( interval >=0, "Argument must be positive");
_scheduler->schedule([=](float dt){
(this->*selector)(dt);
}, this, schedule_selector_to_key(selector), interval , repeat, delay, !_running);
_scheduler->schedule(selector, this, interval , repeat, delay, !_running);
}
void Node::scheduleOnce(SEL_SCHEDULE selector, float delay)
@ -1186,7 +1189,7 @@ void Node::unschedule(SEL_SCHEDULE selector)
if (selector == nullptr)
return;
_scheduler->unschedule(this, schedule_selector_to_key(selector));
_scheduler->unschedule(selector, this);
}
void Node::unscheduleAllSelectors()
@ -1198,14 +1201,14 @@ void Node::resume()
{
_scheduler->resumeTarget(this);
_actionManager->resumeTarget(this);
_eventDispatcher->resumeTarget(this);
_eventDispatcher->resumeEventListenersForTarget(this);
}
void Node::pause()
{
_scheduler->pauseTarget(this);
_actionManager->pauseTarget(this);
_eventDispatcher->pauseTarget(this);
_eventDispatcher->pauseEventListenersForTarget(this);
}
void Node::resumeSchedulerAndActions()
@ -1348,20 +1351,25 @@ void Node::setNodeToParentTransform(const kmMat4& transform)
{
_transform = transform;
_transformDirty = false;
_transformUpdated = true;
}
void Node::setAdditionalTransform(const AffineTransform& additionalTransform)
{
CGAffineToGL(additionalTransform, _additionalTransform.mat);
_transformDirty = true;
_useAdditionalTransform = true;
kmMat4 tmp;
CGAffineToGL(additionalTransform, tmp.mat);
setAdditionalTransform(&tmp);
}
void Node::setAdditionalTransform(const kmMat4& additionalTransform)
void Node::setAdditionalTransform(kmMat4* additionalTransform)
{
_additionalTransform = additionalTransform;
_transformDirty = true;
_useAdditionalTransform = true;
if(additionalTransform == nullptr) {
_useAdditionalTransform = false;
} else {
_additionalTransform = *additionalTransform;
_useAdditionalTransform = true;
}
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -1511,6 +1519,14 @@ void Node::setPhysicsBody(PhysicsBody* body)
{
body->_node = this;
body->retain();
// physics rotation based on body position, but node rotation based on node anthor point
// it cann't support both of them, so I clear the anthor point to default.
if (!getAnchorPoint().equals(Point::ANCHOR_MIDDLE))
{
CCLOG("Node warning: setPhysicsBody sets anchor point to Point::ANCHOR_MIDDLE.");
setAnchorPoint(Point::ANCHOR_MIDDLE);
}
}
if (_physicsBody != nullptr)
@ -1529,7 +1545,9 @@ void Node::setPhysicsBody(PhysicsBody* body)
_physicsBody = body;
if (body != nullptr)
{
_physicsBody->setPosition(getPosition());
Node* parent = getParent();
Point pos = parent != nullptr ? parent->convertToWorldSpace(getPosition()) : getPosition();
_physicsBody->setPosition(pos);
_physicsBody->setRotation(getRotation());
}
}

View File

@ -54,6 +54,7 @@ class Component;
class ComponentContainer;
class EventDispatcher;
class Scene;
class Renderer;
#if CC_USE_PHYSICS
class PhysicsBody;
#endif
@ -386,15 +387,6 @@ public:
virtual float getPositionZ() const;
CC_DEPRECATED_ATTRIBUTE virtual float getVertexZ() const { return getPositionZ(); }
/** Sets the position using normalized coordinates.
- (0,0) means bottom,left corner
- (1,1) means top,right corner
- (0.5,0.5) means center
*/
virtual void setNormalizedPosition(const Point& position);
/** returns the normalized position */
const Point& getNormalizedPosition() const;
/**
* Changes the X skew angle of the node in degrees.
*
@ -449,6 +441,7 @@ public:
* The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
* But you can use values higher than (1,1) and lower than (0,0) too.
* The default anchorPoint is (0.5,0.5), so it starts in the center of the node.
* @note If node has a physics body, the anchor must be in the middle, you cann't change this to other value.
*
* @param anchorPoint The anchor point of node.
*/
@ -990,12 +983,15 @@ public:
* AND YOU SHOULD NOT DISABLE THEM AFTER DRAWING YOUR NODE
* But if you enable any other GL state, you should disable it after drawing your node.
*/
virtual void draw();
virtual void draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated);
virtual void draw() final;
/**
* Visits this node's children and draw them recursively.
*/
virtual void visit();
virtual void visit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated);
virtual void visit() final;
/** Returns the Scene that contains the Node.
It returns `nullptr` if the node doesn't belong to any Scene.
@ -1249,16 +1245,6 @@ public:
/// @{
/// @name Transformations
/**
* Performs OpenGL view-matrix transformation based on position, scale, rotation and other attributes.
*/
void transform();
/**
* Performs OpenGL view-matrix transformation of it's ancestors.
* Generally the ancestors are already transformed, but in certain cases (eg: attaching a FBO)
* It's necessary to transform the ancestors again.
*/
void transformAncestors();
/**
* Calls children's updateTransform() method recursively.
*
@ -1309,7 +1295,7 @@ public:
virtual AffineTransform getWorldToNodeAffineTransform() const;
/** @deprecated Use worldToNodeTransform() instead */
/** @deprecated Use getWorldToNodeTransform() instead */
CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeAffineTransform(); }
/// @} end of Transformations
@ -1353,55 +1339,13 @@ public:
/**
* Sets an additional transform matrix to the node.
*
* In order to remove it, set the Identity Matrix to the additional transform.
* In order to remove it, call it again with the argument `nullptr`
*
* @note The additional transform will be concatenated at the end of getNodeToParentTransform.
* It could be used to simulate `parent-child` relationship between two nodes (e.g. one is in BatchNode, another isn't).
@code
// create a batchNode
SpriteBatchNode* batch= SpriteBatchNode::create("Icon-114.png");
this->addChild(batch);
// create two sprites, spriteA will be added to batchNode, they are using different textures.
Sprite* spriteA = Sprite::createWithTexture(batch->getTexture());
Sprite* spriteB = Sprite::create("Icon-72.png");
batch->addChild(spriteA);
// We can't make spriteB as spriteA's child since they use different textures. So just add it to layer.
// But we want to simulate `parent-child` relationship for these two node.
this->addChild(spriteB);
//position
spriteA->setPosition(Point(200, 200));
// Gets the spriteA's transform.
auto t = spriteA->getNodeToParentTransform();
// Sets the additional transform to spriteB, spriteB's postion will based on its pseudo parent i.e. spriteA.
spriteB->setAdditionalTransform(t);
//scale
spriteA->setScale(2);
// Gets the spriteA's transform.
t = spriteA->getNodeToParentTransform();
// Sets the additional transform to spriteB, spriteB's scale will based on its pseudo parent i.e. spriteA.
spriteB->setAdditionalTransform(t);
//rotation
spriteA->setRotation(20);
// Gets the spriteA's transform.
t = spriteA->getNodeToParentTransform();
// Sets the additional transform to spriteB, spriteB's rotation will based on its pseudo parent i.e. spriteA.
spriteB->setAdditionalTransform(t);
@endcode
*/
void setAdditionalTransform(kmMat4* additionalTransform);
void setAdditionalTransform(const AffineTransform& additionalTransform);
void setAdditionalTransform(const kmMat4& additionalTransform);
/// @} end of Coordinate Converters
@ -1432,6 +1376,7 @@ public:
#if CC_USE_PHYSICS
/**
* set the PhysicsBody that let the sprite effect with physics
* @note This method will set anchor point to Point::ANCHOR_MIDDLE if body not null, and you cann't change anchor point if node has a physics body.
*/
void setPhysicsBody(PhysicsBody* body);
@ -1477,7 +1422,9 @@ protected:
/// Convert cocos2d coordinates to UI windows coordinate.
Point convertToWindowSpace(const Point& nodePoint) const;
kmMat4 transform(const kmMat4 &parentTransform);
virtual void updateCascadeOpacity();
virtual void disableCascadeOpacity();
virtual void updateCascadeColor();
@ -1497,37 +1444,36 @@ protected:
Point _position; ///< position of the node
float _positionZ; ///< OpenGL real Z position
Point _normalizedPosition; ///< position in normalized coordinates
float _skewX; ///< skew angle on x-axis
float _skewY; ///< skew angle on y-axis
Point _anchorPointInPoints; ///< anchor point in points
Point _anchorPoint; ///< anchor point normalized (NOT in points)
Point _anchorPointInPoints; ///< anchor point in points
Point _anchorPoint; ///< anchor point normalized (NOT in points)
Size _contentSize; ///< untransformed size of the node
Size _contentSize; ///< untransformed size of the node
kmMat4 _modelViewTransform; ///< ModelView transform of the Node.
// "cache" variables are allowed to be mutable
mutable kmMat4 _transform; ///< transform
mutable bool _transformDirty; ///< transform dirty flag
mutable kmMat4 _inverse; ///< inverse transform
mutable bool _inverseDirty; ///< inverse transform dirty flag
mutable kmMat4 _additionalTransform; ///< transform
mutable kmMat4 _transform; ///< transform
mutable kmMat4 _inverse; ///< inverse transform
bool _useAdditionalTransform; ///< The flag to check whether the additional transform is dirty
mutable bool _transformDirty; ///< transform dirty flag
mutable bool _inverseDirty; ///< inverse transform dirty flag
bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame
int _localZOrder; ///< Local order (relative to its siblings) used to sort the node
float _globalZOrder; ///< Global order used to sort the node
int _localZOrder; ///< Local order (relative to its siblings) used to sort the node
float _globalZOrder; ///< Global order used to sort the node
Vector<Node*> _children; ///< array of children nodes
Vector<Node*> _children; ///< array of children nodes
Node *_parent; ///< weak reference to parent node
int _tag; ///< a tag. Can be any number you assigned just to identify this node
int _tag; ///< a tag. Can be any number you assigned just to identify this node
void *_userData; ///< A user assingned void pointer, Can be point to any cpp object
Ref *_userObject; ///< A user assigned Object
void *_userData; ///< A user assingned void pointer, Can be point to any cpp object
Ref *_userObject; ///< A user assigned Object
GLProgram *_shaderProgram; ///< OpenGL shader
@ -1539,9 +1485,9 @@ protected:
EventDispatcher* _eventDispatcher; ///< event dispatcher used to dispatch all kinds of events
bool _running; ///< is running
bool _running; ///< is running
bool _visible; ///< is this node visible
bool _visible; ///< is this node visible
bool _ignoreAnchorPointForPosition; ///< true if the Anchor Point will be (0,0) when you position the Node, false otherwise.
///< Used by Layer and Scene.

View File

@ -82,7 +82,7 @@ void NodeGrid::onGridEndDraw()
}
}
void NodeGrid::visit()
void NodeGrid::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
@ -90,13 +90,21 @@ void NodeGrid::visit()
return;
}
Renderer* renderer = Director::getInstance()->getRenderer();
_groupCommand.init(_globalZOrder);
renderer->addCommand(&_groupCommand);
renderer->pushGroup(_groupCommand.getRenderQueueID());
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = this->transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
Director::Projection beforeProjectionType;
if(_nodeGrid && _nodeGrid->isActive())
{
@ -108,11 +116,10 @@ void NodeGrid::visit()
_gridBeginCommand.func = CC_CALLBACK_0(NodeGrid::onGridBeginDraw, this);
renderer->addCommand(&_gridBeginCommand);
this->transform();
if(_gridTarget)
{
_gridTarget->visit();
_gridTarget->visit(renderer, _modelViewTransform, dirty);
}
int i = 0;
@ -126,20 +133,20 @@ void NodeGrid::visit()
auto node = _children.at(i);
if ( node && node->getLocalZOrder() < 0 )
node->visit();
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
// self draw,currently we have nothing to draw on NodeGrid, so there is no need to add render command
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) {
(*it)->visit();
(*it)->visit(renderer, _modelViewTransform, dirty);
}
}
else
{
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
}
// reset for next frame

View File

@ -55,7 +55,7 @@ public:
void setTarget(Node *target);
// overrides
virtual void visit() override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
protected:
NodeGrid();

View File

@ -145,7 +145,7 @@ The positions are updated at visit because:
- using a timer is not guaranteed that it will called after all the positions were updated
- overriding "draw" will only precise if the children have a z > 0
*/
void ParallaxNode::visit()
void ParallaxNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// Point pos = position_;
// Point pos = [self convertToWorldSpace:Point::ZERO];
@ -161,7 +161,7 @@ void ParallaxNode::visit()
}
_lastPosition = pos;
}
Node::visit();
Node::visit(renderer, parentTransform, parentTransformUpdated);
}
NS_CC_END

View File

@ -67,7 +67,7 @@ public:
virtual void addChild(Node * child, int zOrder, int tag) override;
virtual void removeChild(Node* child, bool cleanup) override;
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
virtual void visit(void) override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
protected:
/** Adds a child to the container with a z-order, a parallax ratio and a position offset

View File

@ -120,7 +120,7 @@ bool ParticleBatchNode::initWithFile(const std::string& fileImage, int capacity)
// override visit.
// Don't call visit on it's children
void ParticleBatchNode::visit()
void ParticleBatchNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// CAREFUL:
// This visit is almost identical to Node#visit
@ -134,11 +134,18 @@ void ParticleBatchNode::visit()
return;
}
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
transform();
draw();
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();
}
@ -373,7 +380,7 @@ void ParticleBatchNode::removeAllChildrenWithCleanup(bool doCleanup)
_textureAtlas->removeAllQuads();
}
void ParticleBatchNode::draw(void)
void ParticleBatchNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
CC_PROFILER_START("CCParticleBatchNode - draw");
@ -388,7 +395,7 @@ void ParticleBatchNode::draw(void)
_blendFunc,
_textureAtlas,
_modelViewTransform);
Director::getInstance()->getRenderer()->addCommand(&_batchCommand);
renderer->addCommand(&_batchCommand);
CC_PROFILER_STOP("CCParticleBatchNode - draw");
}

View File

@ -97,13 +97,13 @@ public:
inline void setTextureAtlas(TextureAtlas* atlas) { _textureAtlas = atlas; };
// Overrides
void visit();
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
using Node::addChild;
virtual void addChild(Node * child, int zOrder, int tag) override;
virtual void removeChild(Node* child, bool cleanup) override;
virtual void reorderChild(Node * child, int zOrder) override;
virtual void draw(void) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual Texture2D* getTexture(void) const override;
virtual void setTexture(Texture2D *texture) override;
/**

View File

@ -72,7 +72,7 @@ bool ParticleSystemQuad::initWithTotalParticles(int numberOfParticles)
setupVBO();
}
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
#if CC_ENABLE_CACHE_TEXTURE_DATA
// Need to listen the event only when not use batchnode, because it will use VBO
@ -358,103 +358,15 @@ void ParticleSystemQuad::postStep()
}
// overriding draw method
//void ParticleSystemQuad::draw()
//{
// CCASSERT(!_batchNode,"draw should not be called when added to a particleBatchNode");
//
// CC_NODE_DRAW_SETUP();
//
// GL::bindTexture2D( _texture->getName() );
// GL::blendFunc( _blendFunc.src, _blendFunc.dst );
//
// CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad");
//
// if (Configuration::getInstance()->supportsShareableVAO())
// {
// //
// // Using VBO and VAO
// //
// GL::bindVAO(_VAOname);
//
//#if CC_REBIND_INDICES_BUFFER
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
//#endif
//
// glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0);
//
//#if CC_REBIND_INDICES_BUFFER
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//#endif
// }
// else
// {
// //
// // Using VBO without VAO
// //
//
// #define kQuadSize sizeof(_quads[0].bl)
//
// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
//
// glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
// // vertices
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, vertices));
// // colors
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, colors));
// // tex coords
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, texCoords));
//
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
//
// glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0);
//
// glBindBuffer(GL_ARRAY_BUFFER, 0);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// }
//
// CC_INCREMENT_GL_DRAWS(1);
// CHECK_GL_ERROR_DEBUG();
//}
void ParticleSystemQuad::draw()
void ParticleSystemQuad::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad");
//quad command
if(_particleIdx > 0)
{
// //transform vertices
// std::vector<V3F_C4B_T2F_Quad> drawQuads(_particleIdx);
// memcpy(&drawQuads[0], _quads, sizeof(V3F_C4B_T2F_Quad) * _particleIdx);
// AffineTransform worldTM = getNodeToWorldTransform();
// for(int index = 0; index <_particleIdx; ++index)
// {
// V3F_C4B_T2F_Quad* quad = _quads + index;
//
// Point pt(0,0);
// pt = PointApplyAffineTransform( Point(quad->bl.vertices.x, quad->bl.vertices.y), worldTM);
// drawQuads[index].bl.vertices.x = pt.x;
// drawQuads[index].bl.vertices.y = pt.y;
//
// pt = PointApplyAffineTransform( Point(quad->br.vertices.x, quad->br.vertices.y), worldTM);
// drawQuads[index].br.vertices.x = pt.x;
// drawQuads[index].br.vertices.y = pt.y;
//
// pt = PointApplyAffineTransform( Point(quad->tl.vertices.x, quad->tl.vertices.y), worldTM);
// drawQuads[index].tl.vertices.x = pt.x;
// drawQuads[index].tl.vertices.y = pt.y;
//
// pt = PointApplyAffineTransform( Point(quad->tr.vertices.x, quad->tr.vertices.y), worldTM);
// drawQuads[index].tr.vertices.x = pt.x;
// drawQuads[index].tr.vertices.y = pt.y;
//
// }
auto shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP);
_quadCommand.init(_globalZOrder, _texture->getName(), shader, _blendFunc, _quads, _particleIdx, _modelViewTransform);
Director::getInstance()->getRenderer()->addCommand(&_quadCommand);
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, _quads, _particleIdx, transform);
renderer->addCommand(&_quadCommand);
}
}
void ParticleSystemQuad::setTotalParticles(int tp)

View File

@ -104,7 +104,7 @@ public:
* @js NA
* @lua NA
*/
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
/**
* @js NA
@ -151,15 +151,12 @@ protected:
bool allocMemory();
V3F_C4B_T2F_Quad *_quads; // quads to be rendered
GLushort *_indices; // indices
GLuint _VAOname;
GLuint _buffersVBO[2]; //0: vertex 1: indices
GLushort *_indices; // indices
GLuint _VAOname;
GLuint _buffersVBO[2]; //0: vertex 1: indices
QuadCommand _quadCommand; // quad command
kmMat4 _transformMatrix;
QuadCommand _quadCommand; // quad command
private:
CC_DISALLOW_COPY_AND_ASSIGN(ParticleSystemQuad);
};

View File

@ -532,7 +532,8 @@ void ProgressTimer::onDraw()
if(_type == Type::RADIAL)
{
glDrawArrays(GL_TRIANGLE_FAN, 0, _vertexDataCount);
}
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_vertexDataCount);
}
else if (_type == Type::BAR)
{
if (!_reverseDirection)
@ -550,14 +551,14 @@ void ProgressTimer::onDraw()
}
}
void ProgressTimer::draw()
void ProgressTimer::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if( ! _vertexData || ! _sprite)
return;
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(ProgressTimer::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
}

View File

@ -111,7 +111,7 @@ public:
inline Point getBarChangeRate() const { return _barChangeRate; }
// Overrides
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void setAnchorPoint(const Point& anchorPoint) override;
virtual void setColor(const Color3B &color) override;
virtual const Color3B& getColor() const override;

View File

@ -361,7 +361,7 @@ void RenderTexture::clearStencil(int stencilValue)
glClearStencil(stencilClearValue);
}
void RenderTexture::visit()
void RenderTexture::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// override visit.
// Don't call visit on its children
@ -370,11 +370,19 @@ void RenderTexture::visit()
return;
}
kmGLPushMatrix();
transform();
_sprite->visit();
draw();
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
_sprite->visit(renderer, _modelViewTransform, dirty);
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();
@ -610,7 +618,7 @@ void RenderTexture::onClearDepth()
glClearDepth(depthClearValue);
}
void RenderTexture::draw()
void RenderTexture::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if (_autoDraw)
{
@ -620,7 +628,7 @@ void RenderTexture::draw()
//clear screen
_clearCommand.init(_globalZOrder);
_clearCommand.func = CC_CALLBACK_0(RenderTexture::onClear, this);
Director::getInstance()->getRenderer()->addCommand(&_clearCommand);
renderer->addCommand(&_clearCommand);
//! make sure all children are drawn
sortAllChildren();
@ -628,7 +636,7 @@ void RenderTexture::draw()
for(const auto &child: _children)
{
if (child != _sprite)
child->visit();
child->visit(renderer, transform, transformUpdated);
}
//End will pop the current render group

View File

@ -154,8 +154,8 @@ public:
};
// Overrides
virtual void visit() override;
virtual void draw() override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
public:
// XXX should be procted.

View File

@ -33,28 +33,16 @@ THE SOFTWARE.
#include "CCArray.h"
#include "CCScriptSupport.h"
using namespace std;
NS_CC_BEGIN
long schedule_selector_to_key(SEL_SCHEDULE selector)
{
static union{
SEL_SCHEDULE func;
long key;
};
func = selector;
return key;
}
// data structures
// A list double-linked list used for "updates with priority"
typedef struct _listEntry
{
struct _listEntry *prev, *next;
void *target;
ccSchedulerFunc callback;
void *target;
int priority;
bool paused;
bool markedForDeletion; // selector will no longer be called and entry will be removed at end of the next tick
@ -84,65 +72,24 @@ typedef struct _hashSelectorEntry
// implementation Timer
Timer::Timer()
: _target(nullptr)
, _elapsed(-1)
: _elapsed(-1)
, _runForever(false)
, _useDelay(false)
, _timesExecuted(0)
, _repeat(0)
, _delay(0.0f)
, _interval(0.0f)
, _callback(nullptr)
, _key(0)
#if CC_ENABLE_SCRIPT_BINDING
, _scriptHandler(0)
#endif
{
}
Timer* Timer::create(const ccSchedulerFunc& callback, void *target, long key, float seconds/* = 0 */)
void Timer::setupTimerWithInterval(float seconds, unsigned int repeat, float delay)
{
Timer *timer = new Timer();
timer->initWithTarget(callback, target, key, seconds, kRepeatForever, 0.0f);
timer->autorelease();
return timer;
}
#if CC_ENABLE_SCRIPT_BINDING
Timer* Timer::createWithScriptHandler(int handler, float seconds)
{
Timer *timer = new Timer();
timer->initWithScriptHandler(handler, seconds);
timer->autorelease();
return timer;
}
bool Timer::initWithScriptHandler(int handler, float seconds)
{
_scriptHandler = handler;
_elapsed = -1;
_interval = seconds;
return true;
}
#endif
bool Timer::initWithTarget(const ccSchedulerFunc& callback, void *target, long key, float seconds, unsigned int repeat, float delay)
{
_target = target;
_callback = callback;
_key = key;
_elapsed = -1;
_interval = seconds;
_delay = delay;
_useDelay = (delay > 0.0f) ? true : false;
_repeat = repeat;
_runForever = (repeat == kRepeatForever) ? true : false;
return true;
_elapsed = -1;
_interval = seconds;
_delay = delay;
_useDelay = (_delay > 0.0f) ? true : false;
_repeat = repeat;
_runForever = (_repeat == kRepeatForever) ? true : false;
}
void Timer::update(float dt)
@ -159,18 +106,8 @@ void Timer::update(float dt)
_elapsed += dt;
if (_elapsed >= _interval)
{
if (_target && _key != 0 && _callback)
{
_callback(_elapsed);
}
#if CC_ENABLE_SCRIPT_BINDING
if (0 != _scriptHandler)
{
SchedulerScriptData data(_scriptHandler,_elapsed);
ScriptEvent event(kScheduleEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
#endif
trigger();
_elapsed = 0;
}
}
@ -181,19 +118,8 @@ void Timer::update(float dt)
{
if( _elapsed >= _delay )
{
if (_target && _key != 0 && _callback)
{
_callback(_elapsed);
}
#if CC_ENABLE_SCRIPT_BINDING
if (0 != _scriptHandler)
{
SchedulerScriptData data(_scriptHandler,_elapsed);
ScriptEvent event(kScheduleEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
#endif
trigger();
_elapsed = _elapsed - _delay;
_timesExecuted += 1;
_useDelay = false;
@ -203,19 +129,7 @@ void Timer::update(float dt)
{
if (_elapsed >= _interval)
{
if (_target && _key != 0 && _callback)
{
_callback(_elapsed);
}
#if CC_ENABLE_SCRIPT_BINDING
if (0 != _scriptHandler)
{
SchedulerScriptData data(_scriptHandler,_elapsed);
ScriptEvent event(kScheduleEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
#endif
trigger();
_elapsed = 0;
_timesExecuted += 1;
@ -225,12 +139,106 @@ void Timer::update(float dt)
if (!_runForever && _timesExecuted > _repeat)
{ //unschedule timer
Director::getInstance()->getScheduler()->unschedule(_target, _key);
cancel();
}
}
}
}
// TimerTargetSelector
TimerTargetSelector::TimerTargetSelector()
: _target(nullptr)
, _selector(nullptr)
{
}
bool TimerTargetSelector::initWithSelector(SEL_SCHEDULE selector, Ref* target, float seconds, unsigned int repeat, float delay)
{
_target = target;
_selector = selector;
setupTimerWithInterval(seconds, repeat, delay);
return true;
}
void TimerTargetSelector::trigger()
{
if (_target && _selector)
{
(_target->*_selector)(_elapsed);
}
}
void TimerTargetSelector::cancel()
{
Director::getInstance()->getScheduler()->unschedule(_selector, _target);
}
// TimerTargetCallback
TimerTargetCallback::TimerTargetCallback()
: _target(nullptr)
, _callback(nullptr)
{
}
bool TimerTargetCallback::initWithCallback(const ccSchedulerFunc& callback, void *target, const std::string& key, float seconds, unsigned int repeat, float delay)
{
_target = target;
_callback = callback;
_key = key;
setupTimerWithInterval(seconds, repeat, delay);
return true;
}
void TimerTargetCallback::trigger()
{
if (_callback)
{
_callback(_elapsed);
}
}
void TimerTargetCallback::cancel()
{
Director::getInstance()->getScheduler()->unschedule(_key, _target);
}
#if CC_ENABLE_SCRIPT_BINDING
// TimerScriptHandler
bool TimerScriptHandler::initWithScriptHandler(int handler, float seconds)
{
_scriptHandler = handler;
_elapsed = -1;
_interval = seconds;
return true;
}
void TimerScriptHandler::trigger()
{
if (0 != _scriptHandler)
{
SchedulerScriptData data(_scriptHandler,_elapsed);
ScriptEvent event(kScheduleEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
}
void TimerScriptHandler::cancel()
{
if (0 != _scriptHandler)
{
ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptHandler(_scriptHandler);
_scriptHandler = 0;
}
}
#endif
// implementation of Scheduler
// Priority level reserved for system services.
@ -269,15 +277,15 @@ void Scheduler::removeHashElement(_hashSelectorEntry *element)
free(element);
}
void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, long key, float interval, bool paused)
void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, float interval, bool paused, const std::string& key)
{
this->schedule(callback, target, key, interval, kRepeatForever, 0.0f, paused);
this->schedule(callback, target, interval, kRepeatForever, 0.0f, paused, key);
}
void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, long key, float interval, unsigned int repeat, float delay, bool paused)
void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, float interval, unsigned int repeat, float delay, bool paused, const std::string& key)
{
CCASSERT(target, "Argument target must be non-nullptr");
CCASSERT(key != 0, "key should not be empty!");
CCASSERT(!key.empty(), "key should not be empty!");
tHashTimerEntry *element = nullptr;
HASH_FIND_PTR(_hashForTimers, &target, element);
@ -305,7 +313,7 @@ void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, long key
{
for (int i = 0; i < element->timers->num; ++i)
{
Timer *timer = (Timer*)element->timers->arr[i];
TimerTargetCallback *timer = static_cast<TimerTargetCallback*>(element->timers->arr[i]);
if (key == timer->getKey())
{
@ -317,16 +325,16 @@ void Scheduler::schedule(const ccSchedulerFunc& callback, void *target, long key
ccArrayEnsureExtraCapacity(element->timers, 1);
}
Timer *timer = new Timer();
timer->initWithTarget(callback, target, key, interval, repeat, delay);
TimerTargetCallback *timer = new TimerTargetCallback();
timer->initWithCallback(callback, target, key, interval, repeat, delay);
ccArrayAppendObject(element->timers, timer);
timer->release();
}
void Scheduler::unschedule(void *target, long key)
void Scheduler::unschedule(const std::string &key, void *target)
{
// explicity handle nil arguments when removing an object
if (target == nullptr || key == 0)
if (target == nullptr || key.empty())
{
return;
}
@ -341,7 +349,7 @@ void Scheduler::unschedule(void *target, long key)
{
for (int i = 0; i < element->timers->num; ++i)
{
Timer *timer = static_cast<Timer*>(element->timers->arr[i]);
TimerTargetCallback *timer = static_cast<TimerTargetCallback*>(element->timers->arr[i]);
if (key == timer->getKey())
{
@ -453,7 +461,7 @@ void Scheduler::appendIn(_listEntry **list, const ccSchedulerFunc& callback, voi
HASH_ADD_PTR(_hashForUpdates, target, hashElement);
}
void Scheduler::scheduleUpdate(const ccSchedulerFunc& callback, void *target, int priority, bool paused)
void Scheduler::schedulePerFrame(const ccSchedulerFunc& callback, void *target, int priority, bool paused)
{
tHashUpdateEntry *hashElement = nullptr;
HASH_FIND_PTR(_hashForUpdates, &target, hashElement);
@ -485,9 +493,9 @@ void Scheduler::scheduleUpdate(const ccSchedulerFunc& callback, void *target, in
}
}
bool Scheduler::isScheduled(void *target, long key)
bool Scheduler::isScheduled(const std::string& key, void *target)
{
CCASSERT(key != 0, "Argument key must be empty");
CCASSERT(!key.empty(), "Argument key must not be empty");
CCASSERT(target, "Argument target must be non-nullptr");
tHashTimerEntry *element = nullptr;
@ -501,11 +509,12 @@ bool Scheduler::isScheduled(void *target, long key)
if (element->timers == nullptr)
{
return false;
}else
}
else
{
for (int i = 0; i < element->timers->num; ++i)
{
Timer *timer = (Timer*)element->timers->arr[i];
TimerTargetCallback *timer = static_cast<TimerTargetCallback*>(element->timers->arr[i]);
if (key == timer->getKey())
{
@ -536,7 +545,7 @@ void Scheduler::removeUpdateFromHash(struct _listEntry *entry)
}
}
void Scheduler::unscheduleUpdate(void* target)
void Scheduler::unscheduleUpdate(void *target)
{
if (target == nullptr)
{
@ -959,38 +968,146 @@ void Scheduler::update(float dt)
}
}
//OLD METHODS:
void Scheduler::scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused)
void Scheduler::schedule(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused)
{
target->retain();
this->schedule([=](float dt){
(target->*selector)(dt);
}, target, schedule_selector_to_key(selector), interval , repeat, delay, paused);
CCASSERT(target, "Argument target must be non-nullptr");
tHashTimerEntry *element = nullptr;
HASH_FIND_PTR(_hashForTimers, &target, element);
if (! element)
{
element = (tHashTimerEntry *)calloc(sizeof(*element), 1);
element->target = target;
HASH_ADD_PTR(_hashForTimers, target, element);
// Is this the 1st element ? Then set the pause level to all the selectors of this target
element->paused = paused;
}
else
{
CCASSERT(element->paused == paused, "");
}
if (element->timers == nullptr)
{
element->timers = ccArrayNew(10);
}
else
{
for (int i = 0; i < element->timers->num; ++i)
{
TimerTargetSelector *timer = static_cast<TimerTargetSelector*>(element->timers->arr[i]);
if (selector == timer->getSelector())
{
CCLOG("CCScheduler#scheduleSelector. Selector already scheduled. Updating interval from: %.4f to %.4f", timer->getInterval(), interval);
timer->setInterval(interval);
return;
}
}
ccArrayEnsureExtraCapacity(element->timers, 1);
}
TimerTargetSelector *timer = new TimerTargetSelector();
timer->initWithSelector(selector, target, interval, repeat, delay);
ccArrayAppendObject(element->timers, timer);
timer->release();
}
void Scheduler::scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, bool paused)
void Scheduler::schedule(SEL_SCHEDULE selector, Ref *target, float interval, bool paused)
{
target->retain();
this->schedule([=](float dt){
(target->*selector)(dt);
}, target, schedule_selector_to_key(selector), interval, paused);
this->schedule(selector, target, interval, kRepeatForever, 0.0f, paused);
}
bool Scheduler::isScheduledForTarget(SEL_SCHEDULE selector, Ref *target)
bool Scheduler::isScheduled(SEL_SCHEDULE selector, Ref *target)
{
return this->isScheduled(target, schedule_selector_to_key(selector));
CCASSERT(selector, "Argument selector must be non-nullptr");
CCASSERT(target, "Argument target must be non-nullptr");
tHashTimerEntry *element = nullptr;
HASH_FIND_PTR(_hashForTimers, &target, element);
if (!element)
{
return false;
}
if (element->timers == nullptr)
{
return false;
}
else
{
for (int i = 0; i < element->timers->num; ++i)
{
TimerTargetSelector *timer = static_cast<TimerTargetSelector*>(element->timers->arr[i]);
if (selector == timer->getSelector())
{
return true;
}
}
return false;
}
return false; // should never get here
}
void Scheduler::unscheduleSelector(SEL_SCHEDULE selector, Ref *target)
void Scheduler::unschedule(SEL_SCHEDULE selector, Ref *target)
{
this->unschedule(target, schedule_selector_to_key(selector));
target->release();
// explicity handle nil arguments when removing an object
if (target == nullptr || selector == nullptr)
{
return;
}
//CCASSERT(target);
//CCASSERT(selector);
tHashTimerEntry *element = nullptr;
HASH_FIND_PTR(_hashForTimers, &target, element);
if (element)
{
for (int i = 0; i < element->timers->num; ++i)
{
TimerTargetSelector *timer = static_cast<TimerTargetSelector*>(element->timers->arr[i]);
if (selector == timer->getSelector())
{
if (timer == element->currentTimer && (! element->currentTimerSalvaged))
{
element->currentTimer->retain();
element->currentTimerSalvaged = true;
}
ccArrayRemoveObjectAtIndex(element->timers, i, true);
// update timerIndex in case we are in tick:, looping over the actions
if (element->timerIndex >= i)
{
element->timerIndex--;
}
if (element->timers->num == 0)
{
if (_currentTarget == element)
{
_currentTargetSalvaged = true;
}
else
{
removeHashElement(element);
}
}
return;
}
}
}
}
void Scheduler::unscheduleUpdateForTarget(Ref *target)
{
this->unscheduleUpdate(target);
target->release();
};
NS_CC_END

View File

@ -43,8 +43,6 @@ NS_CC_BEGIN
* @{
*/
long schedule_selector_to_key(SEL_SCHEDULE selector);
typedef std::function<void(float)> ccSchedulerFunc;
//
// Timer
@ -53,46 +51,24 @@ typedef std::function<void(float)> ccSchedulerFunc;
//
class CC_DLL Timer : public Ref
{
protected:
Timer();
public:
/** Allocates a timer with a target, a selector and an interval in seconds. */
static Timer* create(const ccSchedulerFunc& callback, void *target, long key, float seconds = 0.0f);
#if CC_ENABLE_SCRIPT_BINDING
/** Allocates a timer with a script callback function and an interval in seconds.
* @js NA
* @lua NA
*/
static Timer* createWithScriptHandler(int handler, float seconds);
/** Initializes a timer with a script callback function and an interval in seconds. */
bool initWithScriptHandler(int handler, float seconds);
#endif
Timer(void);
/** Initializes a timer with a target, a selector and an interval in seconds, repeat in number of times to repeat, delay in seconds. */
bool initWithTarget(const ccSchedulerFunc& callback, void *target, long key, float seconds, unsigned int repeat, float delay);
/** get interval in seconds */
inline float getInterval() const { return _interval; };
/** set interval in seconds */
inline void setInterval(float interval) { _interval = interval; };
/**
* @js NA
* @lua NA
*/
inline const ccSchedulerFunc& getCallback() const { return _callback; };
inline long getKey() const { return _key; };
void setupTimerWithInterval(float seconds, unsigned int repeat, float delay);
virtual void trigger() = 0;
virtual void cancel() = 0;
/** triggers the timer */
void update(float dt);
#if CC_ENABLE_SCRIPT_BINDING
inline int getScriptHandler() const { return _scriptHandler; };
#endif
protected:
void *_target;
float _elapsed;
bool _runForever;
bool _useDelay;
@ -100,13 +76,69 @@ protected:
unsigned int _repeat; //0 = once, 1 is 2 x executed
float _delay;
float _interval;
ccSchedulerFunc _callback;
long _key;
#if CC_ENABLE_SCRIPT_BINDING
int _scriptHandler;
#endif
};
class CC_DLL TimerTargetSelector : public Timer
{
public:
TimerTargetSelector();
/** Initializes a timer with a target, a selector and an interval in seconds, repeat in number of times to repeat, delay in seconds. */
bool initWithSelector(SEL_SCHEDULE selector, Ref* target, float seconds, unsigned int repeat, float delay);
inline SEL_SCHEDULE getSelector() const { return _selector; };
virtual void trigger() override;
virtual void cancel() override;
protected:
Ref* _target;
SEL_SCHEDULE _selector;
};
class CC_DLL TimerTargetCallback : public Timer
{
public:
TimerTargetCallback();
/** Initializes a timer with a target, a lambda and an interval in seconds, repeat in number of times to repeat, delay in seconds. */
bool initWithCallback(const ccSchedulerFunc& callback, void *target, const std::string& key, float seconds, unsigned int repeat, float delay);
/**
* @js NA
* @lua NA
*/
inline const ccSchedulerFunc& getCallback() const { return _callback; };
inline const std::string& getKey() const { return _key; };
virtual void trigger() override;
virtual void cancel() override;
protected:
void* _target;
ccSchedulerFunc _callback;
std::string _key;
};
#if CC_ENABLE_SCRIPT_BINDING
class CC_DLL TimerScriptHandler : public Timer
{
public:
bool initWithScriptHandler(int handler, float seconds);
inline int getScriptHandler() const { return _scriptHandler; };
virtual void trigger() override;
virtual void cancel() override;
private:
int _scriptHandler;
};
#endif
//
// Scheduler
//
@ -119,7 +151,7 @@ class SchedulerScriptHandlerEntry;
#endif
/** @brief Scheduler is responsible for triggering the scheduled callbacks.
You should not use NSTimer. Instead use this class.
You should not use system timer for your game logic. Instead, use this class.
There are 2 different types of callbacks (selectors):
@ -145,7 +177,7 @@ public:
* @js NA
* @lua NA
*/
~Scheduler(void);
virtual ~Scheduler();
inline float getTimeScale() { return _timeScale; }
/** Modifies the time of all scheduled callbacks.
@ -164,115 +196,126 @@ public:
*/
void update(float dt);
/////////////////////////////////////
// schedule
/** The scheduled method will be called every 'interval' seconds.
If paused is true, then it won't be called until it is resumed.
If 'interval' is 0, it will be called every frame, but if so, it's recommended to use 'scheduleUpdateForTarget:' instead.
If 'interval' is 0, it will be called every frame, but if so, it's recommended to use 'scheduleUpdate' instead.
If the 'callback' is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
repeat let the action be repeated repeat + 1 times, use kRepeatForever to let the action run continuously
delay is the amount of time the action will wait before it'll start
@param key The key to identify the callback
@since v3.0
*/
void schedule(const ccSchedulerFunc& callback, void *target, float interval, unsigned int repeat, float delay, bool paused, const std::string& key);
/** Calls scheduleCallback with kRepeatForever and a 0 delay
@since v3.0
*/
void schedule(const ccSchedulerFunc& callback, void *target, float interval, bool paused, const std::string& key);
/** The scheduled method will be called every 'interval' seconds.
If paused is true, then it won't be called until it is resumed.
If 'interval' is 0, it will be called every frame, but if so, it's recommended to use 'scheduleUpdate' instead.
If the selector is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
repeat let the action be repeated repeat + 1 times, use kRepeatForever to let the action run continuously
delay is the amount of time the action will wait before it'll start
@since v3.0
@since v3.0, repeat and delay added in v1.1
*/
void schedule(const ccSchedulerFunc& callback, void *target, long key, float interval, unsigned int repeat, float delay, bool paused);
void schedule(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused);
/** calls scheduleSelector with kRepeatForever and a 0 delay */
void schedule(const ccSchedulerFunc& callback, void *target, long key, float interval, bool paused);
void schedule(SEL_SCHEDULE selector, Ref *target, float interval, bool paused);
/** Schedules the 'update' selector for a given target with a given priority.
The 'update' selector will be called every frame.
The lower the priority, the earlier it is called.
@since v3.0
@lua NA
*/
void scheduleUpdate(const ccSchedulerFunc& callback, void *target, int priority, bool paused);
/** Checks whether a selector for a given taget is scheduled.
@since v3.0.0
*/
bool isScheduled(void *target, long key);
/** Unschedule a selector for a given target.
If you want to unschedule the "update", use unscheudleUpdateForTarget.
@since v3.0
*/
void unschedule(void *target, long key);
/** Unschedules the update selector for a given target
@since v3.0
*/
void unscheduleUpdate(void *target);
/** Unschedules all selectors for a given target.
This also includes the "update" selector.
@since v3.0
*/
void unscheduleAllForTarget(void *target);
// OLD METHODS
/** The scheduled method will be called every 'interval' seconds.
If paused is true, then it won't be called until it is resumed.
If 'interval' is 0, it will be called every frame, but if so, it's recommended to use 'scheduleUpdateForTarget:' instead.
If the selector is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
repeat let the action be repeated repeat + 1 times, use kRepeatForever to let the action run continuously
delay is the amount of time the action will wait before it'll start
@since v0.99.3, repeat and delay added in v1.1
*/
void scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused);
/** calls scheduleSelector with kRepeatForever and a 0 delay */
void scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, bool paused);
template <class T>
void scheduleUpdateForTarget(T *target, int priority, bool paused)
void scheduleUpdate(T *target, int priority, bool paused)
{
target->retain();
this->scheduleUpdate([=](float dt){
this->schedulePerFrame([target](float dt){
target->update(dt);
}, target, priority, paused);
}
/** Checks whether a selector for a given taget is scheduled.
@since v3.0.0
*/
bool isScheduledForTarget(SEL_SCHEDULE selector, Ref *target);
/** Unschedule a selector for a given target.
If you want to unschedule the "update", use unscheudleUpdateForTarget.
@since v0.99.3
*/
void unscheduleSelector(SEL_SCHEDULE selector, Ref *target);
/** Unschedules the update selector for a given target
@since v0.99.3
*/
void unscheduleUpdateForTarget(Ref *target);
///
/** Unschedules all selectors from all targets.
You should NEVER call this method, unless you know what you are doing.
@since v0.99.3
*/
void unscheduleAll(void);
/** Unschedules all selectors from all targets with a minimum priority.
You should only call this with kPriorityNonSystemMin or higher.
@since v2.0.0
*/
void unscheduleAllWithMinPriority(int minPriority);
#if CC_ENABLE_SCRIPT_BINDING
// schedule for script bindings
/** The scheduled script callback will be called every 'interval' seconds.
If paused is true, then it won't be called until it is resumed.
If 'interval' is 0, it will be called every frame.
return schedule script entry ID, used for unscheduleScriptFunc().
*/
unsigned int scheduleScriptFunc(unsigned int handler, float interval, bool paused);
#endif
/////////////////////////////////////
// unschedule
/** Unschedules a callback for a key and a given target.
If you want to unschedule the 'callbackPerFrame', use unscheduleUpdate.
@since v3.0
*/
void unschedule(const std::string& key, void *target);
/** Unschedule a selector for a given target.
If you want to unschedule the "update", use unscheudleUpdate.
@since v3.0
*/
void unschedule(SEL_SCHEDULE selector, Ref *target);
/** Unschedules the update selector for a given target
@since v0.99.3
*/
void unscheduleUpdate(void *target);
/** Unschedules all selectors for a given target.
This also includes the "update" selector.
@since v0.99.3
@js unscheduleCallbackForTarget
@lua NA
*/
void unscheduleAllForTarget(void *target);
/** Unschedules all selectors from all targets.
You should NEVER call this method, unless you know what you are doing.
@since v0.99.3
*/
void unscheduleAll(void);
/** Unschedules all selectors from all targets with a minimum priority.
You should only call this with kPriorityNonSystemMin or higher.
@since v2.0.0
*/
void unscheduleAllWithMinPriority(int minPriority);
#if CC_ENABLE_SCRIPT_BINDING
/** Unschedule a script entry. */
void unscheduleScriptEntry(unsigned int scheduleScriptEntryID);
#endif
/////////////////////////////////////
// isScheduled
/** Checks whether a callback associated with 'key' and 'target' is scheduled.
@since v3.0.0
*/
bool isScheduled(const std::string& key, void *target);
/** Checks whether a selector for a given taget is scheduled.
@since v3.0
*/
bool isScheduled(SEL_SCHEDULE selector, Ref *target);
/////////////////////////////////////
/** Pauses the target.
All scheduled selectors/update for a given target won't be 'ticked' until the target is resumed.
If the target is not present, nothing happens.
@ -317,8 +360,71 @@ public:
@since v3.0
*/
void performFunctionInCocosThread( const std::function<void()> &function);
/////////////////////////////////////
// Deprecated methods:
/** The scheduled method will be called every 'interval' seconds.
If paused is true, then it won't be called until it is resumed.
If 'interval' is 0, it will be called every frame, but if so, it's recommended to use 'scheduleUpdateForTarget:' instead.
If the selector is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
repeat let the action be repeated repeat + 1 times, use kRepeatForever to let the action run continuously
delay is the amount of time the action will wait before it'll start
@deprecated Please use 'Scheduler::schedule' instead.
@since v0.99.3, repeat and delay added in v1.1
*/
CC_DEPRECATED_ATTRIBUTE void scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused)
{
schedule(selector, target, interval, repeat, delay, paused);
};
/** calls scheduleSelector with kRepeatForever and a 0 delay
* @deprecated Please use 'Scheduler::schedule' instead.
*/
CC_DEPRECATED_ATTRIBUTE void scheduleSelector(SEL_SCHEDULE selector, Ref *target, float interval, bool paused)
{
schedule(selector, target, interval, paused);
};
/** Schedules the 'update' selector for a given target with a given priority.
The 'update' selector will be called every frame.
The lower the priority, the earlier it is called.
@deprecated Please use 'Scheduler::scheduleUpdate' instead.
@since v0.99.3
*/
template <class T>
CC_DEPRECATED_ATTRIBUTE void scheduleUpdateForTarget(T* target, int priority, bool paused) { scheduleUpdate(target, priority, paused); };
/** Unschedule a selector for a given target.
If you want to unschedule the "update", use unscheudleUpdateForTarget.
@deprecated Please use 'Scheduler::unschedule' instead.
@since v0.99.3
*/
CC_DEPRECATED_ATTRIBUTE void unscheduleSelector(SEL_SCHEDULE selector, Ref *target) { unschedule(selector, target); };
/** Checks whether a selector for a given taget is scheduled.
@deprecated Please use 'Scheduler::isScheduled' instead.
@since v0.99.3
*/
CC_DEPRECATED_ATTRIBUTE bool isScheduledForTarget(Ref *target, SEL_SCHEDULE selector) { return isScheduled(selector, target); };
/** Unschedules the update selector for a given target
@deprecated Please use 'Scheduler::unscheduleUpdate' instead.
@since v0.99.3
*/
CC_DEPRECATED_ATTRIBUTE void unscheduleUpdateForTarget(Ref *target) { return unscheduleUpdate(target); };
protected:
/** Schedules the 'callback' function for a given target with a given priority.
The 'callback' selector will be called every frame.
The lower the priority, the earlier it is called.
@note This method is only for internal use.
@since v3.0
*/
void schedulePerFrame(const ccSchedulerFunc& callback, void *target, int priority, bool paused);
void removeHashElement(struct _hashSelectorEntry *element);
void removeUpdateFromHash(struct _listEntry *entry);

View File

@ -74,10 +74,8 @@ SchedulerScriptHandlerEntry* SchedulerScriptHandlerEntry::create(int handler, fl
bool SchedulerScriptHandlerEntry::init(float interval, bool paused)
{
_timer = new Timer();
_timer = new TimerScriptHandler();
_timer->initWithScriptHandler(_handler, interval);
_timer->autorelease();
_timer->retain();
_paused = paused;
LUALOG("[LUA] ADD script schedule: %d, entryID: %d", _handler, _entryId);
return true;

View File

@ -42,7 +42,7 @@ typedef struct lua_State lua_State;
NS_CC_BEGIN
class Timer;
class TimerScriptHandler;
class Layer;
class MenuItem;
class CallFunc;
@ -108,7 +108,7 @@ public:
* @js NA
* @lua NA
*/
cocos2d::Timer* getTimer(void) {
TimerScriptHandler* getTimer(void) {
return _timer;
}
/**
@ -143,7 +143,7 @@ private:
}
bool init(float interval, bool paused);
cocos2d::Timer* _timer;
TimerScriptHandler* _timer;
bool _paused;
bool _markedForDeletion;
};

View File

@ -277,6 +277,7 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
Sprite::Sprite(void)
: _shouldBeHidden(false)
, _texture(nullptr)
, _insideBounds(true)
{
}
@ -586,16 +587,19 @@ void Sprite::updateTransform(void)
// draw
void Sprite::draw(void)
void Sprite::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if(isInsideBounds())
// Don't do calculate the culling if the transform was not updated
_insideBounds = transformUpdated ? isInsideBounds() : _insideBounds;
if(_insideBounds)
{
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, _modelViewTransform);
Director::getInstance()->getRenderer()->addCommand(&_quadCommand);
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, transform);
renderer->addCommand(&_quadCommand);
#if CC_SPRITE_DEBUG_DRAW
_customDebugDrawCommand.init(_globalZOrder);
_customDebugDrawCommand.func = CC_CALLBACK_0(Sprite::drawDebugData, this);
Director::getInstance()->getRenderer()->addCommand(&_customDebugDrawCommand);
renderer->addCommand(&_customDebugDrawCommand);
#endif //CC_SPRITE_DEBUG_DRAW
}
}

View File

@ -424,7 +424,7 @@ public:
virtual void setAnchorPoint(const Point& anchor) override;
virtual void ignoreAnchorPointForPosition(bool value) override;
virtual void setVisible(bool bVisible) override;
virtual void draw(void) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void setOpacityModifyRGB(bool modify) override;
virtual bool isOpacityModifyRGB(void) const override;
/// @}
@ -573,6 +573,8 @@ protected:
bool _flippedX; /// Whether the sprite is flipped horizontally or not
bool _flippedY; /// Whether the sprite is flipped vertically or not
bool _insideBounds; /// whether or not the sprite was inside bounds the previous frame
private:
CC_DISALLOW_COPY_AND_ASSIGN(Sprite);
};

View File

@ -131,7 +131,7 @@ SpriteBatchNode::~SpriteBatchNode()
// override visit
// don't call visit on it's children
void SpriteBatchNode::visit(void)
void SpriteBatchNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
CC_PROFILER_START_CATEGORY(kProfilerCategoryBatchSprite, "CCSpriteBatchNode - visit");
@ -147,12 +147,20 @@ void SpriteBatchNode::visit(void)
return;
}
kmGLPushMatrix();
sortAllChildren();
transform();
draw();
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();
setOrderOfArrival(0);
@ -345,7 +353,7 @@ void SpriteBatchNode::reorderBatch(bool reorder)
_reorderChildDirty=reorder;
}
void SpriteBatchNode::draw()
void SpriteBatchNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
// Optimization: Fast Dispatch
if( _textureAtlas->getTotalQuads() == 0 )
@ -361,8 +369,8 @@ void SpriteBatchNode::draw()
_shaderProgram,
_blendFunc,
_textureAtlas,
_modelViewTransform);
Director::getInstance()->getRenderer()->addCommand(&_batchCommand);
transform);
renderer->addCommand(&_batchCommand);
}
void SpriteBatchNode::increaseAtlasCapacity(void)

View File

@ -155,7 +155,7 @@ public:
*/
virtual const BlendFunc& getBlendFunc() const override;
virtual void visit() override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
using Node::addChild;
virtual void addChild(Node * child, int zOrder, int tag) override;
@ -164,7 +164,7 @@ public:
virtual void removeChild(Node *child, bool cleanup) override;
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
virtual void sortAllChildren() override;
virtual void draw(void) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual std::string getDescription() const override;
/** Inserts a quad at a certain index into the texture atlas. The Sprite won't be added into the children array.

View File

@ -242,7 +242,7 @@ const std::string& TextFieldTTF::getContentText()
return _inputText;
}
void TextFieldTTF::draw()
void TextFieldTTF::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if (_delegate && _delegate->onDraw(this))
{
@ -250,14 +250,14 @@ void TextFieldTTF::draw()
}
if (_inputText.length())
{
LabelTTF::draw();
LabelTTF::draw(renderer, transform, transformUpdated);
return;
}
// draw placeholder
Color3B color = getColor();
setColor(_colorSpaceHolder);
LabelTTF::draw();
LabelTTF::draw(renderer, transform, transformUpdated);
setColor(color);
}

View File

@ -173,7 +173,7 @@ protected:
bool _secureTextEntry;
protected:
virtual void draw();
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
//////////////////////////////////////////////////////////////////////////
// IMEDelegate interface

View File

@ -240,14 +240,6 @@ void TextureAtlas::setupIndices()
for( int i=0; i < _capacity; i++)
{
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
_indices[i*6+0] = i*4+0;
_indices[i*6+1] = i*4+0;
_indices[i*6+2] = i*4+2;
_indices[i*6+3] = i*4+1;
_indices[i*6+4] = i*4+3;
_indices[i*6+5] = i*4+3;
#else
_indices[i*6+0] = i*4+0;
_indices[i*6+1] = i*4+1;
_indices[i*6+2] = i*4+2;
@ -256,7 +248,6 @@ void TextureAtlas::setupIndices()
_indices[i*6+3] = i*4+3;
_indices[i*6+4] = i*4+2;
_indices[i*6+5] = i*4+1;
#endif
}
}
@ -648,11 +639,7 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
#endif
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) );
#else
glDrawElements(GL_TRIANGLES, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
#if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -689,11 +676,7 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])));
#else
glDrawElements(GL_TRIANGLES, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])));
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

View File

@ -55,6 +55,9 @@ Supported features:
* OpenGL component: V3F, C4B, T2F.
The quads are rendered using an OpenGL ES VBO.
To render the quads using an interleaved vertex array list, you should modify the ccConfig.h file
@warning If you want to use TextureAtlas, you'd better setup GL status before it's rendered.
Otherwise, the effect of TextureAtlas will be affected by the GL status of other nodes.
*/
class CC_DLL TextureAtlas : public Ref
{

View File

@ -123,7 +123,7 @@ void TextureCache::addImageAsync(const std::string &path, std::function<void(Tex
if (0 == _asyncRefCount)
{
Director::getInstance()->getScheduler()->schedule(CC_CALLBACK_1(TextureCache::addImageAsyncCallBack, this), this, schedule_selector_to_key(schedule_selector(TextureCache::addImageAsyncCallBack)), 0, false);
Director::getInstance()->getScheduler()->schedule(schedule_selector(TextureCache::addImageAsyncCallBack), this, 0, false);
}
++_asyncRefCount;
@ -277,7 +277,7 @@ void TextureCache::addImageAsyncCallBack(float dt)
--_asyncRefCount;
if (0 == _asyncRefCount)
{
Director::getInstance()->getScheduler()->unschedule(this, schedule_selector_to_key(schedule_selector(TextureCache::addImageAsyncCallBack)));
Director::getInstance()->getScheduler()->unschedule(schedule_selector(TextureCache::addImageAsyncCallBack), this);
}
}
}

View File

@ -97,36 +97,33 @@ void TransitionScene::sceneOrder()
_isInSceneOnTop = true;
}
void TransitionScene::draw()
void TransitionScene::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Scene::draw();
Scene::draw(renderer, transform, transformUpdated);
if( _isInSceneOnTop ) {
_outScene->visit();
_inScene->visit();
_outScene->visit(renderer, transform, transformUpdated);
_inScene->visit(renderer, transform, transformUpdated);
} else {
_inScene->visit();
_outScene->visit();
_inScene->visit(renderer, transform, transformUpdated);
_outScene->visit(renderer, transform, transformUpdated);
}
}
void TransitionScene::finish()
{
kmMat4 identity;
kmMat4Identity(&identity);
// clean up
_inScene->setVisible(true);
_inScene->setPosition(Point(0,0));
_inScene->setScale(1.0f);
_inScene->setRotation(0.0f);
_inScene->setAdditionalTransform(identity);
_inScene->setAdditionalTransform(nullptr);
_outScene->setVisible(false);
_outScene->setPosition(Point(0,0));
_outScene->setScale(1.0f);
_outScene->setRotation(0.0f);
_outScene->setAdditionalTransform(identity);
_outScene->setAdditionalTransform(nullptr);
//[self schedule:@selector(setNewScene:) interval:0];
this->schedule(schedule_selector(TransitionScene::setNewScene), 0);
@ -1258,7 +1255,7 @@ TransitionCrossFade* TransitionCrossFade::create(float t, Scene* scene)
return nullptr;
}
void TransitionCrossFade::draw()
void TransitionCrossFade::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
// override draw since both scenes (textures) are rendered in 1 scene
}
@ -1407,19 +1404,19 @@ void TransitionTurnOffTiles::onExit()
TransitionScene::onExit();
}
void TransitionTurnOffTiles::draw()
void TransitionTurnOffTiles::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Scene::draw();
Scene::draw(renderer, transform, transformUpdated);
if( _isInSceneOnTop )
{
_outSceneProxy->visit();
_inScene->visit();
_outSceneProxy->visit(renderer, transform, transformUpdated);
_inScene->visit(renderer, transform, transformUpdated);
}
else
{
_inScene->visit();
_outSceneProxy->visit();
_inScene->visit(renderer, transform, transformUpdated);
_outSceneProxy->visit(renderer, transform, transformUpdated);
}
}
@ -1487,10 +1484,10 @@ void TransitionSplitCols::switchTargetToInscene()
_gridProxy->setTarget(_inScene);
}
void TransitionSplitCols::draw()
void TransitionSplitCols::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Scene::draw();
_gridProxy->visit();
Scene::draw(renderer, transform, transformUpdated);
_gridProxy->visit(renderer, transform, transformUpdated);
}
void TransitionSplitCols::onExit()
@ -1603,19 +1600,19 @@ void TransitionFadeTR::onExit()
TransitionScene::onExit();
}
void TransitionFadeTR::draw()
void TransitionFadeTR::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Scene::draw();
Scene::draw(renderer, transform, transformUpdated);
if( _isInSceneOnTop )
{
_outSceneProxy->visit();
_inScene->visit();
_outSceneProxy->visit(renderer, transform, transformUpdated);
_inScene->visit(renderer, transform, transformUpdated);
}
else
{
_inScene->visit();
_outSceneProxy->visit();
_inScene->visit(renderer, transform, transformUpdated);
_outSceneProxy->visit(renderer, transform, transformUpdated);
}
}

View File

@ -91,7 +91,7 @@ public:
//
// Overrides
//
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void cleanup() override;
@ -609,7 +609,7 @@ public :
* @js NA
* @lua NA
*/
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
/**
* @js NA
* @lua NA
@ -647,7 +647,7 @@ public :
virtual void onEnter() override;
virtual void onExit() override;
virtual ActionInterval * easeActionWithAction(ActionInterval * action) override;
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
TransitionTurnOffTiles();
@ -680,7 +680,7 @@ public:
virtual void onEnter() override;
virtual ActionInterval * easeActionWithAction(ActionInterval * action) override;
virtual void onExit() override;
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
TransitionSplitCols();
virtual ~TransitionSplitCols();
@ -731,7 +731,7 @@ public:
virtual void onEnter() override;
virtual ActionInterval* easeActionWithAction(ActionInterval * action) override;
virtual void onExit() override;
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
TransitionFadeTR();
virtual ~TransitionFadeTR();

View File

@ -92,31 +92,31 @@ void TransitionPageTurn::onDisablePolygonOffset()
glPolygonOffset(0, 0);
}
void TransitionPageTurn::draw()
void TransitionPageTurn::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Scene::draw();
Scene::draw(renderer, transform, transformUpdated);
if( _isInSceneOnTop ) {
_outSceneProxy->visit();
_outSceneProxy->visit(renderer, transform, transformUpdated);
_enableOffsetCmd.init(_globalZOrder);
_enableOffsetCmd.func = CC_CALLBACK_0(TransitionPageTurn::onEnablePolygonOffset, this);
Director::getInstance()->getRenderer()->addCommand(&_enableOffsetCmd);
_inSceneProxy->visit();
renderer->addCommand(&_enableOffsetCmd);
_inSceneProxy->visit(renderer, transform, transformUpdated);
_disableOffsetCmd.init(_globalZOrder);
_disableOffsetCmd.func = CC_CALLBACK_0(TransitionPageTurn::onDisablePolygonOffset, this);
Director::getInstance()->getRenderer()->addCommand(&_disableOffsetCmd);
renderer->addCommand(&_disableOffsetCmd);
} else {
_inSceneProxy->visit();
_inSceneProxy->visit(renderer, transform, transformUpdated);
_enableOffsetCmd.init(_globalZOrder);
_enableOffsetCmd.func = CC_CALLBACK_0(TransitionPageTurn::onEnablePolygonOffset, this);
Director::getInstance()->getRenderer()->addCommand(&_enableOffsetCmd);
renderer->addCommand(&_enableOffsetCmd);
_outSceneProxy->visit();
_outSceneProxy->visit(renderer, transform, transformUpdated);
_disableOffsetCmd.init(_globalZOrder);
_disableOffsetCmd.func = CC_CALLBACK_0(TransitionPageTurn::onDisablePolygonOffset, this);
Director::getInstance()->getRenderer()->addCommand(&_disableOffsetCmd);
renderer->addCommand(&_disableOffsetCmd);
}
}

View File

@ -72,7 +72,7 @@ public:
//
// Overrides
//
virtual void draw() override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
/**
* Creates a base transition with duration and incoming scene.

View File

@ -161,17 +161,6 @@ Only valid for cocos2d-mac. Not supported on cocos2d-ios.
#define CC_SPRITEBATCHNODE_RENDER_SUBPIXEL 1
#endif
/** @def CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
Use GL_TRIANGLE_STRIP instead of GL_TRIANGLES when rendering the texture atlas.
It seems it is the recommend way, but it is much slower, so, enable it at your own risk
To enable set it to a value different than 0. Disabled by default.
*/
#ifndef CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
#define CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP 0
#endif
/** @def CC_TEXTURE_ATLAS_USE_VAO
By default, TextureAtlas (used by many cocos2d classes) will use VAO (Vertex Array Objects).
Apple recommends its usage but they might consume a lot of memory, specially if you use many of them.

View File

@ -154,11 +154,11 @@ void ActionObject::play()
}
if (_loop)
{
_pScheduler->scheduleSelector(schedule_selector(ActionObject::simulationActionUpdate), this, 0.0f , kRepeatForever, 0.0f, false);
_pScheduler->schedule(schedule_selector(ActionObject::simulationActionUpdate), this, 0.0f , kRepeatForever, 0.0f, false);
}
else
{
_pScheduler->scheduleSelector(schedule_selector(ActionObject::simulationActionUpdate), this, 0.0f, false);
_pScheduler->schedule(schedule_selector(ActionObject::simulationActionUpdate), this, 0.0f, false);
}
}
@ -178,7 +178,7 @@ void ActionObject::stop()
{
e->stopAction();
}
_pScheduler->unscheduleSelector(schedule_selector(ActionObject::simulationActionUpdate), this);
_pScheduler->unschedule(schedule_selector(ActionObject::simulationActionUpdate), this);
_bPause = false;
}

View File

@ -29,7 +29,6 @@ THE SOFTWARE.
#include "cocostudio/CCDatas.h"
#include "cocostudio/CCSkin.h"
#include "renderer/CCQuadCommand.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCGroupCommand.h"
#include "CCShaderCache.h"
@ -378,7 +377,7 @@ void Armature::update(float dt)
_armatureTransformDirty = false;
}
void Armature::draw()
void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if (_parentBone == nullptr && _batchNode == nullptr)
{
@ -408,17 +407,17 @@ void Armature::draw()
{
skin->setBlendFunc(bone->getBlendFunc());
}
skin->draw();
skin->draw(renderer, transform, transformUpdated);
}
break;
case CS_DISPLAY_ARMATURE:
{
node->draw();
node->draw(renderer, transform, transformUpdated);
}
break;
default:
{
node->visit();
node->visit(renderer, transform, transformUpdated);
CC_NODE_DRAW_SETUP();
}
break;
@ -426,7 +425,7 @@ void Armature::draw()
}
else if(Node *node = dynamic_cast<Node *>(object))
{
node->visit();
node->visit(renderer, transform, transformUpdated);
CC_NODE_DRAW_SETUP();
}
}
@ -445,18 +444,27 @@ void Armature::onExit()
}
void Armature::visit()
void Armature::visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
kmGLPushMatrix();
transform();
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
sortAllChildren();
draw();
draw(renderer, _modelViewTransform, dirty);
// reset for next frame
_orderOfArrival = 0;

View File

@ -156,9 +156,9 @@ public:
* @js NA
* @lua NA
*/
virtual void visit() override;
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void update(float dt) override;
virtual void draw() override;
virtual void onEnter() override;
virtual void onExit() override;

View File

@ -101,18 +101,27 @@ void BatchNode::removeChild(Node* child, bool cleanup)
Node::removeChild(child, cleanup);
}
void BatchNode::visit()
void BatchNode::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
kmGLPushMatrix();
transform();
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
sortAllChildren();
draw();
draw(renderer, _modelViewTransform, dirty);
// reset for next frame
_orderOfArrival = 0;
@ -120,7 +129,7 @@ void BatchNode::visit()
kmGLPopMatrix();
}
void BatchNode::draw()
void BatchNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
if (_children.empty())
{
@ -141,14 +150,14 @@ void BatchNode::draw()
pushed = true;
}
armature->visit();
armature->visit(renderer, transform, transformUpdated);
}
else
{
Director::getInstance()->getRenderer()->popGroup();
renderer->popGroup();
pushed = false;
((Node *)object)->visit();
((Node *)object)->visit(renderer, transform, transformUpdated);
}
}
}

View File

@ -56,15 +56,8 @@ public:
virtual void addChild(cocos2d::Node *pChild, int zOrder) override;
virtual void addChild(cocos2d::Node *pChild, int zOrder, int tag) override;
virtual void removeChild(cocos2d::Node* child, bool cleanup) override;
/**
* @js NA
* @lua NA
*/
virtual void visit() override;
/**
* @js NA
*/
void draw() override;
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
void generateGroupCommand();

View File

@ -363,7 +363,7 @@ void DataReaderHelper::addDataFromFileAsync(const std::string& imagePath, const
if (0 == _asyncRefCount)
{
Director::getInstance()->getScheduler()->scheduleSelector(schedule_selector(DataReaderHelper::addDataAsyncCallBack), this, 0, false);
Director::getInstance()->getScheduler()->schedule(schedule_selector(DataReaderHelper::addDataAsyncCallBack), this, 0, false);
}
++_asyncRefCount;
@ -466,7 +466,7 @@ void DataReaderHelper::addDataAsyncCallBack(float dt)
if (0 == _asyncRefCount)
{
_asyncRefTotalCount = 0;
Director::getInstance()->getScheduler()->unscheduleSelector(schedule_selector(DataReaderHelper::addDataAsyncCallBack), this);
Director::getInstance()->getScheduler()->unschedule(schedule_selector(DataReaderHelper::addDataAsyncCallBack), this);
}
}
}

View File

@ -93,7 +93,8 @@ void DisplayFactory::updateDisplay(Bone *bone, float dt, bool dirty)
break;
default:
{
display->setAdditionalTransform(bone->getNodeToArmatureTransform());
kmMat4 transform = bone->getNodeToArmatureTransform();
display->setAdditionalTransform(&transform);
}
break;
}
@ -262,6 +263,7 @@ void DisplayFactory::createParticleDisplay(Bone *bone, DecorativeDisplay *decoDi
ParticleSystem *system = ParticleSystemQuad::create(displayData->displayName.c_str());
system->removeFromParent();
system->cleanup();
Armature *armature = bone->getArmature();
if (armature)

View File

@ -170,6 +170,7 @@ void DisplayManager::addDisplay(Node *display, int index)
displayData = ParticleDisplayData::create();
display->removeFromParent();
display->cleanup();
Armature *armature = _bone->getArmature();
if (armature)

View File

@ -474,7 +474,7 @@ void WidgetPropertiesReader0250::setPropsForCheckBoxFromJsonDictionary(Widget*wi
{
checkBox->loadTextures(backGroundFileName_tp, backGroundSelectedFileName_tp, frontCrossFileName_tp,backGroundDisabledFileName_tp,frontCrossDisabledFileName_tp);
}
checkBox->setSelectedState(DICTOOL->getBooleanValue_json(options, "selectedState"));
setColorPropsForWidgetFromJsonDictionary(widget,options);
}
@ -1364,7 +1364,7 @@ void WidgetPropertiesReader0300::setPropsForCheckBoxFromJsonDictionary(Widget*wi
default:
break;
}
checkBox->setSelectedState(DICTOOL->getBooleanValue_json(options, "selectedState"));
setColorPropsForWidgetFromJsonDictionary(widget,options);
}

View File

@ -219,14 +219,14 @@ kmMat4 Skin::getNodeToWorldTransformAR() const
return TransformConcat( _bone->getArmature()->getNodeToWorldTransform(),displayTransform);
}
void Skin::draw()
void Skin::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
kmMat4 mv;
kmGLGetMatrix(KM_GL_MODELVIEW, &mv);
//TODO implement z order
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, mv);
Director::getInstance()->getRenderer()->addCommand(&_quadCommand);
renderer->addCommand(&_quadCommand);
}
void Skin::setBone(Bone *bone)

View File

@ -54,7 +54,7 @@ public:
kmMat4 getNodeToWorldTransform() const override;
kmMat4 getNodeToWorldTransformAR() const;
virtual void draw() override;
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
/**
* @js NA

View File

@ -70,7 +70,6 @@ void Skeleton::initialize () {
setOpacityModifyRGB(true);
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
scheduleUpdate();
}
void Skeleton::setSkeletonData (spSkeletonData *skeletonData, bool isOwnsSkeletonData) {
@ -126,22 +125,16 @@ void Skeleton::update (float deltaTime) {
spSkeleton_update(skeleton, deltaTime * timeScale);
}
void Skeleton::draw()
void Skeleton::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLGetMatrix(KM_GL_MODELVIEW, &_oldTransMatrix);
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(Skeleton::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
renderer->addCommand(&_customCommand);
}
void Skeleton::onDraw ()
{
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLPushMatrix();
kmGLLoadMatrix(&_oldTransMatrix);
CC_NODE_DRAW_SETUP();
GL::blendFunc(blendFunc.src, blendFunc.dst);
@ -198,46 +191,50 @@ void Skeleton::onDraw ()
textureAtlas->removeAllQuads();
}
if (debugSlots) {
// Slots.
DrawPrimitives::setDrawColor4B(0, 0, 255, 255);
glLineWidth(1);
Point points[4];
V3F_C4B_T2F_Quad tmpQuad;
for (int i = 0, n = skeleton->slotCount; i < n; i++) {
spSlot* slot = skeleton->drawOrder[i];
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
spRegionAttachment_updateQuad(attachment, slot, &tmpQuad);
points[0] = Point(tmpQuad.bl.vertices.x, tmpQuad.bl.vertices.y);
points[1] = Point(tmpQuad.br.vertices.x, tmpQuad.br.vertices.y);
points[2] = Point(tmpQuad.tr.vertices.x, tmpQuad.tr.vertices.y);
points[3] = Point(tmpQuad.tl.vertices.x, tmpQuad.tl.vertices.y);
DrawPrimitives::drawPoly(points, 4, true);
}
}
if (debugBones) {
// Bone lengths.
glLineWidth(2);
DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i];
float x = bone->data->length * bone->m00 + bone->worldX;
float y = bone->data->length * bone->m10 + bone->worldY;
DrawPrimitives::drawLine(Point(bone->worldX, bone->worldY), Point(x, y));
}
// Bone origins.
DrawPrimitives::setPointSize(4);
DrawPrimitives::setDrawColor4B(0, 0, 255, 255); // Root bone is blue.
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i];
DrawPrimitives::drawPoint(Point(bone->worldX, bone->worldY));
if (i == 0) DrawPrimitives::setDrawColor4B(0, 255, 0, 255);
}
}
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLPopMatrix();
if(debugBones || debugSlots) {
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
if (debugSlots) {
// Slots.
DrawPrimitives::setDrawColor4B(0, 0, 255, 255);
glLineWidth(1);
Point points[4];
V3F_C4B_T2F_Quad tmpQuad;
for (int i = 0, n = skeleton->slotCount; i < n; i++) {
spSlot* slot = skeleton->drawOrder[i];
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
spRegionAttachment_updateQuad(attachment, slot, &tmpQuad);
points[0] = Point(tmpQuad.bl.vertices.x, tmpQuad.bl.vertices.y);
points[1] = Point(tmpQuad.br.vertices.x, tmpQuad.br.vertices.y);
points[2] = Point(tmpQuad.tr.vertices.x, tmpQuad.tr.vertices.y);
points[3] = Point(tmpQuad.tl.vertices.x, tmpQuad.tl.vertices.y);
DrawPrimitives::drawPoly(points, 4, true);
}
}
if (debugBones) {
// Bone lengths.
glLineWidth(2);
DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i];
float x = bone->data->length * bone->m00 + bone->worldX;
float y = bone->data->length * bone->m10 + bone->worldY;
DrawPrimitives::drawLine(Point(bone->worldX, bone->worldY), Point(x, y));
}
// Bone origins.
DrawPrimitives::setPointSize(4);
DrawPrimitives::setDrawColor4B(0, 0, 255, 255); // Root bone is blue.
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i];
DrawPrimitives::drawPoint(Point(bone->worldX, bone->worldY));
if (i == 0) DrawPrimitives::setDrawColor4B(0, 255, 0, 255);
}
}
kmGLPopMatrix();
}
}
TextureAtlas* Skeleton::getTextureAtlas (spRegionAttachment* regionAttachment) const {
@ -275,6 +272,16 @@ Rect Skeleton::getBoundingBox () const {
return Rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
}
void Skeleton::onEnter() {
Node::onEnter();
scheduleUpdate();
}
void Skeleton::onExit() {
Node::onExit();
unscheduleUpdate();
}
// --- Convenience methods for Skeleton_* functions.
void Skeleton::updateWorldTransform () {

View File

@ -67,8 +67,10 @@ public:
virtual ~Skeleton ();
virtual void update (float deltaTime) override;
virtual void draw() override;
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
void onDraw();
void onEnter() override;
void onExit() override;
virtual cocos2d::Rect getBoundingBox () const override;
// --- Convenience methods for common Skeleton_* functions.
@ -109,9 +111,7 @@ private:
// Util function that setting blend-function by nextRenderedTexture's premultiplied flag
void setFittedBlendingFunc(cocos2d::TextureAtlas * nextRenderedTexture);
cocos2d::CustomCommand _customCommand;
kmMat4 _oldTransMatrix;
cocos2d::CustomCommand _customCommand;
};
}

View File

@ -152,6 +152,11 @@ void Button::setScale9Enabled(bool able)
setCapInsetsDisabledRenderer(_capInsetsDisabled);
setBright(_bright);
}
bool Button::isScale9Enabled()
{
return _scale9Enabled;
}
void Button::ignoreContentAdaptWithSize(bool ignore)
{
@ -326,6 +331,11 @@ void Button::setCapInsetsNormalRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonNormalRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsNormalRenderer()
{
return _capInsetsNormal;
}
void Button::setCapInsetsPressedRenderer(const Rect &capInsets)
{
@ -336,6 +346,11 @@ void Button::setCapInsetsPressedRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonClickedRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsPressedRenderer()
{
return _capInsetsPressed;
}
void Button::setCapInsetsDisabledRenderer(const Rect &capInsets)
{
@ -346,6 +361,11 @@ void Button::setCapInsetsDisabledRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonDisableRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsDisabledRenderer()
{
return _capInsetsDisabled;
}
void Button::onPressStateChangedToNormal()
{
@ -366,8 +386,7 @@ void Button::onPressStateChangedToNormal()
else
{
_buttonNormalRenderer->stopAllActions();
Action *zoomAction = ScaleTo::create(0.05f, _normalTextureScaleXInSize, _normalTextureScaleYInSize);
_buttonNormalRenderer->runAction(zoomAction);
_buttonNormalRenderer->setScale(_normalTextureScaleXInSize, _normalTextureScaleYInSize);
}
}
@ -393,8 +412,7 @@ void Button::onPressStateChangedToPressed()
_buttonClickedRenderer->setVisible(true);
_buttonDisableRenderer->setVisible(false);
_buttonNormalRenderer->stopAllActions();
Action *zoomAction = ScaleTo::create(0.05f, _pressedTextureScaleXInSize + 0.1f, _pressedTextureScaleYInSize + 0.1f);
_buttonNormalRenderer->runAction(zoomAction);
_buttonNormalRenderer->setScale(_normalTextureScaleXInSize + 0.1f, _normalTextureScaleYInSize + 0.1f);
}
}

View File

@ -107,6 +107,8 @@ public:
*/
void setCapInsetsNormalRenderer(const Rect &capInsets);
const Rect& getCapInsetsNormalRenderer();
/**
* Sets capinsets for button, if button is using scale9 renderer.
*
@ -114,6 +116,8 @@ public:
*/
void setCapInsetsPressedRenderer(const Rect &capInsets);
const Rect& getCapInsetsPressedRenderer();
/**
* Sets capinsets for button, if button is using scale9 renderer.
*
@ -121,6 +125,8 @@ public:
*/
void setCapInsetsDisabledRenderer(const Rect &capInsets);
const Rect& getCapInsetsDisabledRenderer();
//override "setAnchorPoint" of widget.
virtual void setAnchorPoint(const Point &pt) override;
@ -131,6 +137,8 @@ public:
*/
virtual void setScale9Enabled(bool able);
bool isScale9Enabled();
//override "setFlipX" of widget.
virtual void setFlipX(bool flipX) override;

View File

@ -206,6 +206,11 @@ void ImageView::setScale9Enabled(bool able)
}
setCapInsets(_capInsets);
}
bool ImageView::isScale9Enabled()
{
return _scale9Enabled;
}
void ImageView::ignoreContentAdaptWithSize(bool ignore)
{
@ -226,6 +231,11 @@ void ImageView::setCapInsets(const Rect &capInsets)
STATIC_CAST_SCALE9SPRITE->setCapInsets(capInsets);
}
const Rect& ImageView::getCapInsets()
{
return _capInsets;
}
void ImageView::setAnchorPoint(const Point &pt)
{
Widget::setAnchorPoint(pt);

View File

@ -75,6 +75,8 @@ public:
*/
void setScale9Enabled(bool able);
bool isScale9Enabled();
/**
* Sets capinsets for imageview, if imageview is using scale9 renderer.
*
@ -82,6 +84,8 @@ public:
*/
void setCapInsets(const Rect &capInsets);
const Rect& getCapInsets();
//override "setFlipX" method of widget.
virtual void setFlipX(bool flipX) override;

View File

@ -67,6 +67,7 @@ _scissorRectDirty(false),
_clippingRect(Rect::ZERO),
_clippingParent(nullptr),
_doLayoutDirty(true),
_clippingRectDirty(true),
_currentStencilEnabled(GL_FALSE),
_currentStencilWriteMask(~0),
_currentStencilFunc(GL_ALWAYS),
@ -95,6 +96,8 @@ void Layout::onEnter()
{
_clippingStencil->onEnter();
}
_doLayoutDirty = true;
_clippingRectDirty = true;
}
void Layout::onExit()
@ -150,6 +153,23 @@ void Layout::addChild(Node *child, int zOrder, int tag)
Widget::addChild(child, zOrder, tag);
_doLayoutDirty = true;
}
void Layout::removeChild(Node *child, bool cleanup)
{
Widget::removeChild(child, cleanup);
_doLayoutDirty = true;
}
void Layout::removeAllChildren()
{
Widget::removeAllChildren();
}
void Layout::removeAllChildrenWithCleanup(bool cleanup)
{
Widget::removeAllChildrenWithCleanup(cleanup);
_doLayoutDirty = true;
}
bool Layout::isClippingEnabled()
{
@ -167,7 +187,7 @@ bool Layout::hitTest(const Point &pt)
return false;
}
void Layout::visit()
void Layout::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (!_enabled)
{
@ -178,10 +198,10 @@ void Layout::visit()
switch (_clippingType)
{
case LAYOUT_CLIPPING_STENCIL:
stencilClippingVisit();
stencilClippingVisit(renderer, parentTransform, parentTransformUpdated);
break;
case LAYOUT_CLIPPING_SCISSOR:
scissorClippingVisit();
scissorClippingVisit(renderer, parentTransform, parentTransformUpdated);
break;
default:
break;
@ -189,7 +209,7 @@ void Layout::visit()
}
else
{
Node::visit();
Node::visit(renderer, parentTransform, parentTransformUpdated);
}
}
@ -199,17 +219,24 @@ void Layout::sortAllChildren()
doLayout();
}
void Layout::stencilClippingVisit()
void Layout::stencilClippingVisit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if(!_visible)
return;
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
transform();
kmGLLoadMatrix(&_modelViewTransform);
//Add group command
Renderer* renderer = Director::getInstance()->getRenderer();
_groupCommand.init(_globalZOrder);
renderer->addCommand(&_groupCommand);
@ -219,7 +246,7 @@ void Layout::stencilClippingVisit()
_beforeVisitCmdStencil.func = CC_CALLBACK_0(Layout::onBeforeVisitStencil, this);
renderer->addCommand(&_beforeVisitCmdStencil);
_clippingStencil->visit();
_clippingStencil->visit(renderer, _modelViewTransform, dirty);
_afterDrawStencilCmd.init(_globalZOrder);
_afterDrawStencilCmd.func = CC_CALLBACK_0(Layout::onAfterDrawStencil, this);
@ -236,19 +263,19 @@ void Layout::stencilClippingVisit()
auto node = _children.at(i);
if ( node && node->getLocalZOrder() < 0 )
node->visit();
node->visit(renderer, _modelViewTransform, dirty);
else
break;
}
// self draw
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit();
(*it)->visit(renderer, _modelViewTransform, dirty);
}
else
{
this->draw();
this->draw(renderer, _modelViewTransform, dirty);
}
_afterVisitCmdStencil.init(_globalZOrder);
@ -333,15 +360,13 @@ void Layout::onAfterVisitScissor()
glDisable(GL_SCISSOR_TEST);
}
void Layout::scissorClippingVisit()
void Layout::scissorClippingVisit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated)
{
Renderer* renderer = Director::getInstance()->getRenderer();
_beforeVisitCmdScissor.init(_globalZOrder);
_beforeVisitCmdScissor.func = CC_CALLBACK_0(Layout::onBeforeVisitScissor, this);
renderer->addCommand(&_beforeVisitCmdScissor);
Node::visit();
Node::visit(renderer, parentTransform, parentTransformUpdated);
_afterVisitCmdScissor.init(_globalZOrder);
_afterVisitCmdScissor.func = CC_CALLBACK_0(Layout::onAfterVisitScissor, this);
@ -405,6 +430,11 @@ void Layout::setClippingType(LayoutClippingType type)
setClippingEnabled(clippingEnabled);
}
LayoutClippingType Layout::getClippingType()
{
return _clippingType;
}
void Layout::setStencilClippingSize(const Size &size)
{
if (_clippingEnabled && _clippingType == LAYOUT_CLIPPING_STENCIL)
@ -422,79 +452,83 @@ void Layout::setStencilClippingSize(const Size &size)
const Rect& Layout::getClippingRect()
{
Point worldPos = convertToWorldSpace(Point::ZERO);
AffineTransform t = getNodeToWorldAffineTransform();
float scissorWidth = _size.width*t.a;
float scissorHeight = _size.height*t.d;
Rect parentClippingRect;
Layout* parent = this;
bool firstClippingParentFounded = false;
while (parent)
if (_clippingRectDirty)
{
parent = dynamic_cast<Layout*>(parent->getParent());
if(parent)
Point worldPos = convertToWorldSpace(Point::ZERO);
AffineTransform t = getNodeToWorldAffineTransform();
float scissorWidth = _size.width*t.a;
float scissorHeight = _size.height*t.d;
Rect parentClippingRect;
Layout* parent = this;
bool firstClippingParentFounded = false;
while (parent)
{
if (parent->isClippingEnabled())
parent = dynamic_cast<Layout*>(parent->getParent());
if(parent)
{
if (!firstClippingParentFounded)
if (parent->isClippingEnabled())
{
_clippingParent = parent;
firstClippingParentFounded = true;
break;
if (!firstClippingParentFounded)
{
_clippingParent = parent;
firstClippingParentFounded = true;
break;
}
}
}
}
}
if (_clippingParent)
{
parentClippingRect = _clippingParent->getClippingRect();
float finalX = worldPos.x - (scissorWidth * _anchorPoint.x);
float finalY = worldPos.y - (scissorHeight * _anchorPoint.y);
float finalWidth = scissorWidth;
float finalHeight = scissorHeight;
float leftOffset = worldPos.x - parentClippingRect.origin.x;
if (leftOffset < 0.0f)
if (_clippingParent)
{
finalX = parentClippingRect.origin.x;
finalWidth += leftOffset;
parentClippingRect = _clippingParent->getClippingRect();
float finalX = worldPos.x - (scissorWidth * _anchorPoint.x);
float finalY = worldPos.y - (scissorHeight * _anchorPoint.y);
float finalWidth = scissorWidth;
float finalHeight = scissorHeight;
float leftOffset = worldPos.x - parentClippingRect.origin.x;
if (leftOffset < 0.0f)
{
finalX = parentClippingRect.origin.x;
finalWidth += leftOffset;
}
float rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.origin.x + parentClippingRect.size.width);
if (rightOffset > 0.0f)
{
finalWidth -= rightOffset;
}
float topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.origin.y + parentClippingRect.size.height);
if (topOffset > 0.0f)
{
finalHeight -= topOffset;
}
float bottomOffset = worldPos.y - parentClippingRect.origin.y;
if (bottomOffset < 0.0f)
{
finalY = parentClippingRect.origin.x;
finalHeight += bottomOffset;
}
if (finalWidth < 0.0f)
{
finalWidth = 0.0f;
}
if (finalHeight < 0.0f)
{
finalHeight = 0.0f;
}
_clippingRect.origin.x = finalX;
_clippingRect.origin.y = finalY;
_clippingRect.size.width = finalWidth;
_clippingRect.size.height = finalHeight;
}
float rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.origin.x + parentClippingRect.size.width);
if (rightOffset > 0.0f)
else
{
finalWidth -= rightOffset;
_clippingRect.origin.x = worldPos.x - (scissorWidth * _anchorPoint.x);
_clippingRect.origin.y = worldPos.y - (scissorHeight * _anchorPoint.y);
_clippingRect.size.width = scissorWidth;
_clippingRect.size.height = scissorHeight;
}
float topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.origin.y + parentClippingRect.size.height);
if (topOffset > 0.0f)
{
finalHeight -= topOffset;
}
float bottomOffset = worldPos.y - parentClippingRect.origin.y;
if (bottomOffset < 0.0f)
{
finalY = parentClippingRect.origin.x;
finalHeight += bottomOffset;
}
if (finalWidth < 0.0f)
{
finalWidth = 0.0f;
}
if (finalHeight < 0.0f)
{
finalHeight = 0.0f;
}
_clippingRect.origin.x = finalX;
_clippingRect.origin.y = finalY;
_clippingRect.size.width = finalWidth;
_clippingRect.size.height = finalHeight;
}
else
{
_clippingRect.origin.x = worldPos.x - (scissorWidth * _anchorPoint.x);
_clippingRect.origin.y = worldPos.y - (scissorHeight * _anchorPoint.y);
_clippingRect.size.width = scissorWidth;
_clippingRect.size.height = scissorHeight;
_clippingRectDirty = false;
}
return _clippingRect;
}
@ -505,6 +539,7 @@ void Layout::onSizeChanged()
setContentSize(_size);
setStencilClippingSize(_size);
_doLayoutDirty = true;
_clippingRectDirty = true;
if (_backGroundImage)
{
_backGroundImage->setPosition(Point(_size.width/2.0f, _size.height/2.0f));
@ -612,6 +647,11 @@ void Layout::setBackGroundImageCapInsets(const Rect &capInsets)
static_cast<extension::Scale9Sprite*>(_backGroundImage)->setCapInsets(capInsets);
}
}
const Rect& Layout::getBackGroundImageCapInsets()
{
return _backGroundImageCapInsets;
}
void Layout::supplyTheLayoutParameterLackToChild(Widget *child)
{
@ -739,6 +779,11 @@ void Layout::setBackGroundColorType(LayoutBackGroundColorType type)
break;
}
}
LayoutBackGroundColorType Layout::getBackGroundColorType()
{
return _colorType;
}
void Layout::setBackGroundColor(const Color3B &color)
{
@ -748,6 +793,11 @@ void Layout::setBackGroundColor(const Color3B &color)
_colorRender->setColor(color);
}
}
const Color3B& Layout::getBackGroundColor()
{
return _cColor;
}
void Layout::setBackGroundColor(const Color3B &startColor, const Color3B &endColor)
{
@ -762,6 +812,16 @@ void Layout::setBackGroundColor(const Color3B &startColor, const Color3B &endCol
_gradientRender->setEndColor(endColor);
}
}
const Color3B& Layout::getBackGroundStartColor()
{
return _gStartColor;
}
const Color3B& Layout::getBackGroundEndColor()
{
return _gEndColor;
}
void Layout::setBackGroundColorOpacity(int opacity)
{
@ -780,6 +840,11 @@ void Layout::setBackGroundColorOpacity(int opacity)
break;
}
}
int Layout::getBackGroundColorOpacity()
{
return _cOpacity;
}
void Layout::setBackGroundColorVector(const Point &vector)
{
@ -789,6 +854,11 @@ void Layout::setBackGroundColorVector(const Point &vector)
_gradientRender->setVector(vector);
}
}
const Point& Layout::getBackGroundColorVector()
{
return _alongVector;
}
const Size& Layout::getBackGroundImageTextureSize() const
{
@ -1192,128 +1262,50 @@ void Layout::doLayout()
case RELATIVE_LOCATION_ABOVE_LEFTALIGN:
finalPosY += mg.bottom;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT)
{
finalPosY += relativeWidgetMargin.top;
}
finalPosX += mg.left;
break;
case RELATIVE_LOCATION_ABOVE_RIGHTALIGN:
finalPosY += mg.bottom;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT)
{
finalPosY += relativeWidgetMargin.top;
}
finalPosX -= mg.right;
break;
case RELATIVE_LOCATION_ABOVE_CENTER:
finalPosY += mg.bottom;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT)
{
finalPosY += relativeWidgetMargin.top;
}
break;
case RELATIVE_LOCATION_LEFT_OF_TOPALIGN:
finalPosX -= mg.right;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL)
{
finalPosX -= relativeWidgetMargin.left;
}
finalPosY -= mg.top;
break;
case RELATIVE_LOCATION_LEFT_OF_BOTTOMALIGN:
finalPosX -= mg.right;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL)
{
finalPosX -= relativeWidgetMargin.left;
}
finalPosY += mg.bottom;
break;
case RELATIVE_LOCATION_LEFT_OF_CENTER:
finalPosX -= mg.right;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_LEFT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_NONE
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL)
{
finalPosX -= relativeWidgetMargin.left;
}
break;
case RELATIVE_LOCATION_RIGHT_OF_TOPALIGN:
finalPosX += mg.left;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL)
{
finalPosX += relativeWidgetMargin.right;
}
finalPosY -= mg.top;
break;
case RELATIVE_LOCATION_RIGHT_OF_BOTTOMALIGN:
finalPosX += mg.left;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL)
{
finalPosX += relativeWidgetMargin.right;
}
finalPosY += mg.bottom;
break;
case RELATIVE_LOCATION_RIGHT_OF_CENTER:
finalPosX += mg.left;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_TOP_RIGHT
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL)
{
finalPosX += relativeWidgetMargin.right;
}
break;
case RELATIVE_LOCATION_BELOW_LEFTALIGN:
finalPosY -= mg.top;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL)
{
finalPosY -= relativeWidgetMargin.bottom;
}
finalPosX += mg.left;
break;
case RELATIVE_LOCATION_BELOW_RIGHTALIGN:
finalPosY -= mg.top;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL)
{
finalPosY -= relativeWidgetMargin.bottom;
}
finalPosX -= mg.right;
break;
case RELATIVE_LOCATION_BELOW_CENTER:
finalPosY -= mg.top;
if (relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_LEFT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM
&& relativeWidgetLP->getAlign() != RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL)
{
finalPosY -= relativeWidgetMargin.bottom;
}
break;
default:
break;

View File

@ -91,6 +91,8 @@ public:
*/
void setBackGroundImageCapInsets(const Rect& capInsets);
const Rect& getBackGroundImageCapInsets();
/**
* Sets Color Type for layout.
*
@ -98,6 +100,8 @@ public:
*/
void setBackGroundColorType(LayoutBackGroundColorType type);
LayoutBackGroundColorType getBackGroundColorType();
/**
* Sets background iamge use scale9 renderer.
*
@ -105,6 +109,8 @@ public:
*/
void setBackGroundImageScale9Enabled(bool enabled);
bool isBackGroundImageScale9Enabled();
/**
* Sets background color for layout, if color type is LAYOUT_COLOR_SOLID
*
@ -112,6 +118,8 @@ public:
*/
void setBackGroundColor(const Color3B &color);
const Color3B& getBackGroundColor();
/**
* Sets background color for layout, if color type is LAYOUT_COLOR_GRADIENT
*
@ -121,6 +129,10 @@ public:
*/
void setBackGroundColor(const Color3B &startColor, const Color3B &endColor);
const Color3B& getBackGroundStartColor();
const Color3B& getBackGroundEndColor();
/**
* Sets background opacity layout.
*
@ -128,6 +140,8 @@ public:
*/
void setBackGroundColorOpacity(int opacity);
int getBackGroundColorOpacity();
/**
* Sets background color vector for layout, if color type is LAYOUT_COLOR_GRADIENT
*
@ -135,6 +149,8 @@ public:
*/
void setBackGroundColorVector(const Point &vector);
const Point& getBackGroundColorVector();
/**
* Remove the background image of layout.
*/
@ -158,6 +174,8 @@ public:
void setClippingType(LayoutClippingType type);
LayoutClippingType getClippingType();
/**
* Gets if layout is clipping enabled.
*
@ -209,8 +227,25 @@ public:
*/
virtual void addChild(Node* child, int zOrder, int tag) override;
virtual void visit();
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void removeChild(Node* child, bool cleanup = true) override;
/**
* Removes all children from the container with a cleanup.
*
* @see `removeAllChildrenWithCleanup(bool)`
*/
virtual void removeAllChildren() override;
/**
* Removes all children from the container, and do a cleanup to all running actions depending on the cleanup parameter.
*
* @param cleanup true if all running actions on all children nodes should be cleanup, false oterwise.
* @js removeAllChildren
* @lua removeAllChildren
*/
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
virtual void sortAllChildren() override;
void requestDoLayout();
@ -234,8 +269,8 @@ protected:
virtual void copySpecialProperties(Widget* model) override;
virtual void copyClonedWidgetChildren(Widget* model) override;
void stencilClippingVisit();
void scissorClippingVisit();
void stencilClippingVisit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated);
void scissorClippingVisit(Renderer *renderer, const kmMat4& parentTransform, bool parentTransformUpdated);
void setStencilClippingSize(const Size& size);
const Rect& getClippingRect();
@ -273,6 +308,7 @@ protected:
Rect _clippingRect;
Layout* _clippingParent;
bool _doLayoutDirty;
bool _clippingRectDirty;
//clipping

View File

@ -1,26 +1,26 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "gui/UILayoutParameter.h"
#include "gui/UILayout.h"
@ -56,6 +56,23 @@ LayoutParameterType LayoutParameter::getLayoutType() const
{
return _layoutParameterType;
}
LayoutParameter* LayoutParameter::clone()
{
LayoutParameter* clonedParameter = createCloneInstance();
clonedParameter->copyProperties(this);
return clonedParameter;
}
LayoutParameter* LayoutParameter::createCloneInstance()
{
return LayoutParameter::create();
}
void LayoutParameter::copyProperties(LayoutParameter *model)
{
_margin = model->_margin;
}
LinearLayoutParameter* LinearLayoutParameter::create()
{
@ -78,6 +95,21 @@ LinearGravity LinearLayoutParameter::getGravity() const
{
return _linearGravity;
}
LayoutParameter* LinearLayoutParameter::createCloneInstance()
{
return LinearLayoutParameter::create();
}
void LinearLayoutParameter::copyProperties(LayoutParameter *model)
{
LayoutParameter::copyProperties(model);
LinearLayoutParameter* parameter = dynamic_cast<LinearLayoutParameter*>(model);
if (parameter)
{
setGravity(parameter->_linearGravity);
}
}
RelativeLayoutParameter* RelativeLayoutParameter::create()
{
@ -120,6 +152,23 @@ const char* RelativeLayoutParameter::getRelativeName() const
{
return _relativeLayoutName.c_str();
}
LayoutParameter* RelativeLayoutParameter::createCloneInstance()
{
return RelativeLayoutParameter::create();
}
void RelativeLayoutParameter::copyProperties(LayoutParameter *model)
{
LayoutParameter::copyProperties(model);
RelativeLayoutParameter* parameter = dynamic_cast<RelativeLayoutParameter*>(model);
if (parameter)
{
setAlign(parameter->_relativeAlign);
setRelativeName(parameter->_relativeLayoutName.c_str());
setRelativeToWidgetName(parameter->_relativeWidgetName.c_str());
}
}
}

View File

@ -1,26 +1,26 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __LAYOUTPARMETER_H__
#define __LAYOUTPARMETER_H__
@ -86,6 +86,10 @@ public:
* @return LayoutParameterType
*/
LayoutParameterType getLayoutType() const;
LayoutParameter* clone();
virtual LayoutParameter* createCloneInstance();
virtual void copyProperties(LayoutParameter* model);
protected:
Margin _margin;
LayoutParameterType _layoutParameterType;
@ -130,6 +134,8 @@ public:
* @return LinearGravity
*/
LinearGravity getGravity() const;
virtual LayoutParameter* createCloneInstance() override;
virtual void copyProperties(LayoutParameter* model) override;
protected:
LinearGravity _linearGravity;
};
@ -202,6 +208,9 @@ public:
* @return name
*/
const char* getRelativeName() const;
virtual LayoutParameter* createCloneInstance() override;
virtual void copyProperties(LayoutParameter* model) override;
protected:
RelativeAlign _relativeAlign;
std::string _relativeWidgetName;

View File

@ -347,6 +347,11 @@ void ListView::setItemsMargin(float margin)
_itemsMargin = margin;
_refreshViewDirty = true;
}
float ListView::getItemsMargin()
{
return _itemsMargin;
}
void ListView::setDirection(SCROLLVIEW_DIR dir)
{

View File

@ -150,6 +150,8 @@ public:
*/
void setItemsMargin(float margin);
float getItemsMargin();
virtual void sortAllChildren() override;
ssize_t getCurSelectedIndex() const;

View File

@ -196,6 +196,11 @@ void LoadingBar::setScale9Enabled(bool enabled)
setCapInsets(_capInsets);
}
bool LoadingBar::isScale9Enabled()
{
return _scale9Enabled;
}
void LoadingBar::setCapInsets(const Rect &capInsets)
{
_capInsets = capInsets;
@ -206,6 +211,11 @@ void LoadingBar::setCapInsets(const Rect &capInsets)
static_cast<extension::Scale9Sprite*>(_barRenderer)->setCapInsets(capInsets);
}
const Rect& LoadingBar::getCapInsets()
{
return _capInsets;
}
void LoadingBar::setPercent(int percent)
{
if ( percent < 0 || percent > 100)
@ -334,6 +344,7 @@ void LoadingBar::copySpecialProperties(Widget *widget)
loadTexture(loadingBar->_textureFile.c_str(), loadingBar->_renderBarTexType);
setCapInsets(loadingBar->_capInsets);
setPercent(loadingBar->_percent);
setDirection(loadingBar->_barType);
}
}

View File

@ -106,6 +106,8 @@ public:
*/
void setScale9Enabled(bool enabled);
bool isScale9Enabled();
/**
* Sets capinsets for loadingbar, if loadingbar is using scale9 renderer.
*
@ -113,6 +115,8 @@ public:
*/
void setCapInsets(const Rect &capInsets);
const Rect& getCapInsets();
//override "ignoreContentAdaptWithSize" method of widget.
virtual void ignoreContentAdaptWithSize(bool ignore) override;

View File

@ -273,6 +273,46 @@ Widget* ScrollView::getChildByName(const char *name)
{
return _innerContainer->getChildByName(name);
}
void ScrollView::addNode(Node* node)
{
Layout::addNode(node);
}
void ScrollView::addNode(Node * node, int zOrder)
{
Layout::addNode(node, zOrder);
}
void ScrollView::addNode(Node* node, int zOrder, int tag)
{
_innerContainer->addNode(node, zOrder, tag);
}
Node* ScrollView::getNodeByTag(int tag)
{
return _innerContainer->getNodeByTag(tag);
}
Vector<Node*>& ScrollView::getNodes()
{
return _innerContainer->getNodes();
}
void ScrollView::removeNode(Node* node)
{
_innerContainer->removeNode(node);
}
void ScrollView::removeNodeByTag(int tag)
{
_innerContainer->removeNodeByTag(tag);
}
void ScrollView::removeAllNodes()
{
_innerContainer->removeAllNodes();
}
void ScrollView::moveChildren(float offsetX, float offsetY)
{

View File

@ -274,6 +274,22 @@ public:
virtual Widget* getChildByName(const char* name) override;
virtual void addNode(Node* node) override;
virtual void addNode(Node * node, int zOrder) override;
virtual void addNode(Node* node, int zOrder, int tag) override;
virtual Node * getNodeByTag(int tag) override;
virtual Vector<Node*>& getNodes() override;
virtual void removeNode(Node* node) override;
virtual void removeNodeByTag(int tag) override;
virtual void removeAllNodes() override;
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override;
virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override;
virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override;

View File

@ -216,6 +216,11 @@ void Slider::setScale9Enabled(bool able)
setCapInsetsBarRenderer(_capInsetsBarRenderer);
setCapInsetProgressBarRebderer(_capInsetsProgressBarRenderer);
}
bool Slider::isScale9Enabled()
{
return _scale9Enabled;
}
void Slider::ignoreContentAdaptWithSize(bool ignore)
{
@ -241,6 +246,11 @@ void Slider::setCapInsetsBarRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_barRenderer)->setCapInsets(capInsets);
}
const Rect& Slider::getCapInsetsBarRenderer()
{
return _capInsetsBarRenderer;
}
void Slider::setCapInsetProgressBarRebderer(const Rect &capInsets)
{
@ -251,6 +261,11 @@ void Slider::setCapInsetProgressBarRebderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_progressBarRenderer)->setCapInsets(capInsets);
}
const Rect& Slider::getCapInsetsProgressBarRebderer()
{
return _capInsetsProgressBarRenderer;
}
void Slider::loadSlidBallTextures(const char* normal,const char* pressed,const char* disabled,TextureResType texType)
{

View File

@ -77,6 +77,8 @@ public:
*/
void setScale9Enabled(bool able);
bool isScale9Enabled();
/**
* Sets capinsets for slider, if slider is using scale9 renderer.
*
@ -91,6 +93,8 @@ public:
*/
void setCapInsetsBarRenderer(const Rect &capInsets);
const Rect& getCapInsetsBarRenderer();
/**
* Sets capinsets for slider, if slider is using scale9 renderer.
*
@ -98,6 +102,8 @@ public:
*/
void setCapInsetProgressBarRebderer(const Rect &capInsets);
const Rect& getCapInsetsProgressBarRebderer();
/**
* Load textures for slider ball.
*

View File

@ -98,6 +98,11 @@ void Text::setFontSize(int size)
_labelRenderer->setFontSize(size);
labelScaleChangedWithSize();
}
int Text::getFontSize()
{
return _fontSize;
}
void Text::setFontName(const std::string& name)
{
@ -105,36 +110,53 @@ void Text::setFontName(const std::string& name)
_labelRenderer->setFontName(name);
labelScaleChangedWithSize();
}
const std::string& Text::getFontName()
{
return _fontName;
}
void Text::setTextAreaSize(const Size &size)
{
_labelRenderer->setDimensions(size);
labelScaleChangedWithSize();
}
const Size& Text::getTextAreaSize()
{
return _labelRenderer->getDimensions();
}
void Text::setTextHorizontalAlignment(TextHAlignment alignment)
{
_labelRenderer->setHorizontalAlignment(alignment);
labelScaleChangedWithSize();
}
TextHAlignment Text::getTextHorizontalAlignment()
{
return _labelRenderer->getHorizontalAlignment();
}
void Text::setTextVerticalAlignment(TextVAlignment alignment)
{
_labelRenderer->setVerticalAlignment(alignment);
labelScaleChangedWithSize();
}
TextVAlignment Text::getTextVerticalAlignment()
{
return _labelRenderer->getVerticalAlignment();
}
void Text::setTouchScaleChangeEnabled(bool enable)
{
_touchScaleChangeEnabled = enable;
_normalScaleValueX = getScaleX();
_normalScaleValueY = getScaleY();
}
void Text::setScale(float fScale)
{
Widget::setScale(fScale);
_normalScaleValueX = _normalScaleValueY = fScale;
}
void Text::setScaleX(float fScaleX)
@ -158,7 +180,7 @@ void Text::onPressStateChangedToNormal()
{
return;
}
clickScale(_normalScaleValueX, _normalScaleValueY);
_labelRenderer->setScale(_normalScaleValueX, _normalScaleValueY);
}
void Text::onPressStateChangedToPressed()
@ -167,9 +189,7 @@ void Text::onPressStateChangedToPressed()
{
return;
}
_normalScaleValueX = getScaleX();
_normalScaleValueY = getScaleY();
clickScale(_normalScaleValueX + _onSelectedScaleOffset, _normalScaleValueY + _onSelectedScaleOffset);
_labelRenderer->setScale(_normalScaleValueX + _onSelectedScaleOffset, _normalScaleValueY + _onSelectedScaleOffset);
}
void Text::onPressStateChangedToDisabled()
@ -177,12 +197,6 @@ void Text::onPressStateChangedToDisabled()
}
void Text::clickScale(float scaleX, float scaleY)
{
setScaleX(scaleX);
setScaleY(scaleY);
}
void Text::setFlipX(bool flipX)
{
_labelRenderer->setFlippedX(flipX);
@ -231,6 +245,7 @@ void Text::labelScaleChangedWithSize()
{
_labelRenderer->setScale(1.0f);
_size = _labelRenderer->getContentSize();
_normalScaleValueX = _normalScaleValueY = 1.0f;
}
else
{
@ -244,6 +259,8 @@ void Text::labelScaleChangedWithSize()
float scaleY = _size.height / textureSize.height;
_labelRenderer->setScaleX(scaleX);
_labelRenderer->setScaleY(scaleY);
_normalScaleValueX = scaleX;
_normalScaleValueY = scaleY;
}
}

View File

@ -81,6 +81,8 @@ public:
*/
void setFontSize(int size);
int getFontSize();
/**
* Sets the font name of label.
*
@ -88,6 +90,8 @@ public:
*/
void setFontName(const std::string& name);
const std::string& getFontName();
/**
* Sets the touch scale enabled of label.
*
@ -157,8 +161,17 @@ public:
virtual std::string getDescription() const override;
void setTextAreaSize(const Size &size);
const Size& getTextAreaSize();
void setTextHorizontalAlignment(TextHAlignment alignment);
void setTextVerticalAlignment(TextVAlignment alignment);
TextHAlignment getTextHorizontalAlignment();
void setTextVerticalAlignment(TextVAlignment alignment);
TextVAlignment getTextVerticalAlignment();
protected:
virtual bool init() override;
virtual void initRenderer() override;
@ -166,7 +179,6 @@ protected:
virtual void onPressStateChangedToPressed() override;
virtual void onPressStateChangedToDisabled() override;
virtual void onSizeChanged() override;
void clickScale(float scaleX, float scaleY);
void labelScaleChangedWithSize();
virtual Widget* createCloneInstance() override;
virtual void copySpecialProperties(Widget* model) override;

View File

@ -319,6 +319,11 @@ void TextField::setTouchSize(const Size &size)
_touchWidth = size.width;
_touchHeight = size.height;
}
Size TextField::getTouchSize()
{
return Size(_touchWidth, _touchHeight);
}
void TextField::setText(const std::string& text)
{
@ -345,18 +350,33 @@ void TextField::setPlaceHolder(const std::string& value)
_textFieldRenderer->setPlaceHolder(value);
textfieldRendererScaleChangedWithSize();
}
const std::string& TextField::getPlaceHolder()
{
return _textFieldRenderer->getPlaceHolder();
}
void TextField::setFontSize(int size)
{
_textFieldRenderer->setFontSize(size);
textfieldRendererScaleChangedWithSize();
}
int TextField::getFontSize()
{
return _textFieldRenderer->getFontSize();
}
void TextField::setFontName(const std::string& name)
{
_textFieldRenderer->setFontName(name);
textfieldRendererScaleChangedWithSize();
}
const std::string& TextField::getFontName()
{
return _textFieldRenderer->getFontName();
}
void TextField::didNotSelectSelf()
{
@ -414,6 +434,11 @@ void TextField::setPasswordStyleText(const char *styleText)
_passwordStyleText = styleText;
}
const char* TextField::getPasswordStyleText()
{
return _passwordStyleText.c_str();
}
void TextField::update(float dt)
{

View File

@ -108,10 +108,14 @@ public:
virtual ~TextField();
static TextField* create();
void setTouchSize(const Size &size);
Size getTouchSize();
void setText(const std::string& text);
void setPlaceHolder(const std::string& value);
const std::string& getPlaceHolder();
void setFontSize(int size);
int getFontSize();
void setFontName(const std::string& name);
const std::string& getFontName();
virtual void didNotSelectSelf();
const std::string& getStringValue();
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override;
@ -122,6 +126,7 @@ public:
void setPasswordEnabled(bool enable);
bool isPasswordEnabled();
void setPasswordStyleText(const char* styleText);
const char* getPasswordStyleText();
virtual void update(float dt) override;
bool getAttachWithIME();
void setAttachWithIME(bool attach);

View File

@ -108,11 +108,11 @@ void Widget::onExit()
Node::onExit();
}
void Widget::visit()
void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (_enabled)
{
Node::visit();
Node::visit(renderer, parentTransform, parentTransformUpdated);
}
}
@ -1065,6 +1065,11 @@ void Widget::copyProperties(Widget *widget)
setOpacity(widget->getOpacity());
setCascadeOpacityEnabled(widget->isCascadeOpacityEnabled());
setCascadeColorEnabled(widget->isCascadeColorEnabled());
Map<int, LayoutParameter*>& layoutParameterDic = widget->_layoutParameterDictionary;
for (auto iter = layoutParameterDic.begin(); iter != layoutParameterDic.end(); ++iter)
{
setLayoutParameter(iter->second->clone());
}
onSizeChanged();
}

View File

@ -331,7 +331,7 @@ public:
virtual void removeAllNodes();
virtual void visit() override;
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
/**
* Sets the touch event target/selector of the menu item

View File

@ -481,7 +481,10 @@ void HttpClient::send(HttpRequest* request)
void HttpClient::dispatchResponseCallbacks()
{
// log("CCHttpClient::dispatchResponseCallbacks is running");
//occurs when cocos thread fires but the network thread has already quited
if (nullptr == s_responseQueue) {
return;
}
HttpResponse* response = nullptr;
s_responseQueueMutex.lock();

View File

@ -359,7 +359,7 @@ void SIOClientImpl::onOpen(WebSocket* ws)
iter->second->onOpen();
}
Director::getInstance()->getScheduler()->scheduleSelector(schedule_selector(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false);
Director::getInstance()->getScheduler()->schedule(schedule_selector(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false);
log("SIOClientImpl::onOpen socket connected!");
}

View File

@ -122,7 +122,7 @@ WsThreadHelper::WsThreadHelper()
_UIWsMessageQueue = new std::list<WsMessage*>();
_subThreadWsMessageQueue = new std::list<WsMessage*>();
Director::getInstance()->getScheduler()->scheduleUpdateForTarget(this, 0, false);
Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
}
WsThreadHelper::~WsThreadHelper()
@ -699,6 +699,8 @@ void WebSocket::onUIThreadReceiveMessage(WsMessage* msg)
break;
case WS_MSG_TO_UITHREAD_CLOSE:
{
//Waiting for the subThread safety exit
_wsHelper->joinSubThread();
_delegate->onClose(this);
}
break;

View File

@ -75,6 +75,7 @@ PhysicsBody::PhysicsBody()
, _group(0)
, _positionResetTag(false)
, _rotationResetTag(false)
, _rotationOffset(0)
{
}
@ -347,7 +348,7 @@ void PhysicsBody::setPosition(Point position)
{
if (!_positionResetTag)
{
cpBodySetPos(_info->getBody(), PhysicsHelper::point2cpv(position));
cpBodySetPos(_info->getBody(), PhysicsHelper::point2cpv(position + _positionOffset));
}
_positionResetTag = false;
}
@ -356,7 +357,7 @@ void PhysicsBody::setRotation(float rotation)
{
if (!_rotationResetTag)
{
cpBodySetAngle(_info->getBody(), -PhysicsHelper::float2cpfloat(rotation * M_PI / 180.0f));
cpBodySetAngle(_info->getBody(), -PhysicsHelper::float2cpfloat((rotation + _rotationOffset) * (M_PI / 180.0f)));
}
_rotationResetTag = false;
@ -365,12 +366,12 @@ void PhysicsBody::setRotation(float rotation)
Point PhysicsBody::getPosition() const
{
cpVect vec = cpBodyGetPos(_info->getBody());
return PhysicsHelper::cpv2point(vec);
return PhysicsHelper::cpv2point(vec) - _positionOffset;
}
float PhysicsBody::getRotation() const
{
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->getBody()) / M_PI * 180.0f);
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->getBody()) * (180.0f / M_PI)) - _rotationOffset;
}
PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape, bool addMassAndMoment/* = true*/)
@ -767,27 +768,18 @@ void PhysicsBody::setResting(bool rest) const
void PhysicsBody::update(float delta)
{
if (_node != nullptr && _dynamic && !isResting())
if (_node != nullptr)
{
cpVect pos = cpBodyGetPos(_info->getBody());
cpVect prePos = _info->getPosition();
cpVect rot = cpBodyGetRot(_info->getBody());
cpVect preRot = _info->getRotation();
Node* parent = _node->getParent();
// only reset the node position when body position/rotation changed.
if (std::abs(pos.x - prePos.x) >= 0.3f || std::abs(pos.y - prePos.y) >= 0.3f
|| std::abs(rot.x - preRot.x) >= 0.01f || std::abs(rot.y - preRot.y) >= 0.01f)
{
_positionResetTag = true;
_rotationResetTag = true;
_node->setPosition(getPosition());
_info->setPosition(pos);
_node->setRotation(getRotation());
_info->setRotation(rot);
}
Point position = parent != nullptr ? parent->convertToNodeSpace(getPosition()) : getPosition();
_positionResetTag = true;
_rotationResetTag = true;
_node->setPosition(position);
_node->setRotation(getRotation());
// damping compute
if (_isDamping)
if (_isDamping && _dynamic && !isResting())
{
_info->getBody()->v.x *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
_info->getBody()->v.y *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
@ -834,6 +826,36 @@ void PhysicsBody::setGroup(int group)
}
}
void PhysicsBody::setPositionOffset(const Point& position)
{
if (!_positionOffset.equals(position))
{
Point pos = getPosition();
_positionOffset = position;
setPosition(pos);
}
}
Point PhysicsBody::getPositionOffset() const
{
return _positionOffset;
}
void PhysicsBody::setRotationOffset(float rotation)
{
if (std::abs(_rotationOffset - rotation) > 0.5f)
{
float rot = getRotation();
_rotationOffset = rotation;
setRotation(rot);
}
}
float PhysicsBody::getRotationOffset() const
{
return _rotationOffset;
}
Point PhysicsBody::world2Local(const Point& point)
{
return PhysicsHelper::cpv2point(cpBodyWorld2Local(_info->getBody(), PhysicsHelper::point2cpv(point)));

View File

@ -192,6 +192,15 @@ public:
/** get the body rotation. */
float getRotation() const;
/** set body position offset, it's the position witch relative to node */
void setPositionOffset(const Point& position);
/** get body position offset. */
Point getPositionOffset() const;
/** set body rotation offset, it's the rotation witch relative to node */
void setRotationOffset(float rotation);
/** set the body rotation offset */
float getRotationOffset() const;
/**
* @brief test the body is dynamic or not.
* a dynamic body will effect with gravity.
@ -332,6 +341,8 @@ protected:
bool _positionResetTag; /// To avoid reset the body position when body invoke Node::setPosition().
bool _rotationResetTag; /// To avoid reset the body rotation when body invoke Node::setRotation().
Point _positionOffset;
float _rotationOffset;
friend class PhysicsWorld;
friend class PhysicsShape;

View File

@ -39,10 +39,6 @@ class PhysicsBodyInfo
public:
inline cpBody* getBody() const { return _body; }
inline void setBody(cpBody* body) { _body = body; }
inline cpVect getPosition() const { return _position; }
inline void setPosition(cpVect& vect) { _position = vect; }
inline cpVect getRotation() const { return _rotation; }
inline void setRotation(cpVect& vect) { _rotation = vect; }
private:
PhysicsBodyInfo();
@ -50,8 +46,6 @@ private:
private:
cpBody* _body;
cpVect _position;
cpVect _rotation;
friend class PhysicsBody;
};

View File

@ -769,14 +769,14 @@ void Scale9Sprite::setInsetBottom(float insetBottom)
this->updateCapInset();
}
void Scale9Sprite::visit()
void Scale9Sprite::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if(this->_positionsAreDirty)
{
this->updatePositions();
this->_positionsAreDirty = false;
}
Node::visit();
Node::visit(renderer, parentTransform, parentTransformUpdated);
}
void Scale9Sprite::setColor(const Color3B& color)

View File

@ -261,7 +261,7 @@ public:
* @js NA
* @lua NA
*/
virtual void visit() override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void setOpacityModifyRGB(bool bValue) override;
virtual bool isOpacityModifyRGB(void) const override;
virtual void setOpacity(GLubyte opacity) override;

View File

@ -28,6 +28,8 @@
NS_CC_EXT_BEGIN
static const float CHECK_EDITBOX_POSITION_INTERVAL = 0.1f;
EditBox::EditBox(void)
: _editBoxImpl(NULL)
, _delegate(NULL)
@ -316,9 +318,9 @@ void EditBox::setAnchorPoint(const Point& anchorPoint)
}
}
void EditBox::visit(void)
void EditBox::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
ControlButton::visit();
ControlButton::visit(renderer, parentTransform, parentTransformUpdated);
if (_editBoxImpl != NULL)
{
_editBoxImpl->visit();
@ -332,8 +334,19 @@ void EditBox::onEnter(void)
{
_editBoxImpl->onEnter();
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
this->schedule(schedule_selector(EditBox::updatePosition), CHECK_EDITBOX_POSITION_INTERVAL);
#endif
}
void EditBox::updatePosition(float dt)
{
if (nullptr != _editBoxImpl) {
_editBoxImpl->updatePosition(dt);
}
}
void EditBox::onExit(void)
{
ControlButton::onExit();

View File

@ -379,7 +379,7 @@ public:
* @js NA
* @lua NA
*/
virtual void visit(void) override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
/**
* @js NA
* @lua NA
@ -418,6 +418,7 @@ public:
void touchDownAction(Ref *sender, Control::EventType controlEvent);
protected:
void updatePosition(float dt);
EditBoxImpl* _editBoxImpl;
EditBoxDelegate* _delegate;

View File

@ -69,6 +69,11 @@ public:
virtual void setVisible(bool visible) = 0;
virtual void setContentSize(const Size& size) = 0;
virtual void setAnchorPoint(const Point& anchorPoint) = 0;
/**
* check the editbox's position, update it when needed
*/
virtual void updatePosition(float dt){};
/**
* @js NA
* @lua NA

View File

@ -101,6 +101,7 @@ public:
virtual void setVisible(bool visible);
virtual void setContentSize(const Size& size);
virtual void setAnchorPoint(const Point& anchorPoint);
virtual void updatePosition(float dt) override;
/**
* @js NA
* @lua NA
@ -116,7 +117,6 @@ public:
virtual void closeKeyboard();
virtual void onEndEditing();
private:
void initInactiveLabels(const Size& size);
void setInactiveText(const char* pText);

View File

@ -614,7 +614,6 @@ void EditBoxImplIOS::setAnchorPoint(const Point& anchorPoint)
void EditBoxImplIOS::visit(void)
{
}
void EditBoxImplIOS::onEnter(void)
@ -626,6 +625,15 @@ void EditBoxImplIOS::onEnter(void)
}
}
void EditBoxImplIOS::updatePosition(float dt)
{
if (nullptr != _systemControl) {
this->adjustTextFieldPosition();
}
}
void EditBoxImplIOS::adjustTextFieldPosition()
{
Size contentSize = _editBox->getContentSize();

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