diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index b087aa457418..192a44a72302 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -712,7 +712,7 @@ CC_CONSTRUCTOR_ACCESS : PolygonInfo _polyInfo; // opacity and RGB protocol - bool _opacityModifyRGB; + bool _opacityModifyRGB = false; // image is flipped bool _flippedX; /// Whether the sprite is flipped horizontally or not diff --git a/cocos/network/SocketIO.cpp b/cocos/network/SocketIO.cpp index 5c5f146cd97b..dc436bc3a94d 100644 --- a/cocos/network/SocketIO.cpp +++ b/cocos/network/SocketIO.cpp @@ -35,6 +35,8 @@ #include "network/HttpClient.h" #include "network/Uri.h" #include "network/WebSocket.h" + +#include #include #include #include @@ -80,8 +82,8 @@ class SocketIOPacket std::vector getData()const{ return _args; }; virtual std::string stringify()const; - static SocketIOPacket * createPacketWithType(const std::string& type, SocketIOVersion version); - static SocketIOPacket * createPacketWithTypeIndex(int type, SocketIOVersion version); + static std::shared_ptr createPacketWithType(const std::string& type, SocketIOVersion version); + static std::shared_ptr createPacketWithTypeIndex(int type, SocketIOVersion version); protected: std::string _pId;//id message std::string _ack;// @@ -306,37 +308,38 @@ SocketIOPacketV10x::~SocketIOPacketV10x() _endpoint = ""; } -SocketIOPacket * SocketIOPacket::createPacketWithType(const std::string& type, SocketIOPacket::SocketIOVersion version) +std::shared_ptr SocketIOPacket::createPacketWithType(const std::string& type, SocketIOPacket::SocketIOVersion version) { - SocketIOPacket *ret; - switch (version) + if(version == SocketIOPacket::SocketIOVersion::V09x) { - case SocketIOPacket::SocketIOVersion::V09x: - ret = new (std::nothrow) SocketIOPacket; - break; - case SocketIOPacket::SocketIOVersion::V10x: - ret = new (std::nothrow) SocketIOPacketV10x; - break; + auto ret = std::make_shared(); + ret->initWithType(type); + return ret; + } + else if(version == SocketIOPacket::SocketIOVersion::V10x) + { + auto ret = std::make_shared(); + ret->initWithType(type); + return ret; } - ret->initWithType(type); - return ret; + return nullptr; } - -SocketIOPacket * SocketIOPacket::createPacketWithTypeIndex(int type, SocketIOPacket::SocketIOVersion version) +std::shared_ptr SocketIOPacket::createPacketWithTypeIndex(int type, SocketIOPacket::SocketIOVersion version) { - SocketIOPacket *ret; - switch (version) + if(version == SocketIOPacket::SocketIOVersion::V09x) { - case SocketIOPacket::SocketIOVersion::V09x: - ret = new (std::nothrow) SocketIOPacket; - break; - case SocketIOPacket::SocketIOVersion::V10x: - return new (std::nothrow) SocketIOPacketV10x; - break; + auto ret = std::make_shared(); + ret->initWithTypeIndex(type); + return ret; } - ret->initWithTypeIndex(type); - return ret; + else if(version == SocketIOPacket::SocketIOVersion::V10x) + { + auto ret = std::make_shared(); + ret->initWithTypeIndex(type); + return ret; + } + return nullptr; } /** @@ -344,8 +347,8 @@ SocketIOPacket * SocketIOPacket::createPacketWithTypeIndex(int type, SocketIOPac * Clients/endpoints may share the same impl to accomplish multiplexing on the same websocket */ class SIOClientImpl : - public cocos2d::Ref, - public WebSocket::Delegate + public WebSocket::Delegate, + public std::enable_shared_from_this { private: int _heartbeat, _timeout; @@ -363,7 +366,7 @@ class SIOClientImpl : SIOClientImpl(const Uri& uri, const std::string& caFilePath); virtual ~SIOClientImpl(); - static SIOClientImpl* create(const Uri& uri, const std::string& caFilePath); + static std::shared_ptr create(const Uri& uri, const std::string& caFilePath); virtual void onOpen(WebSocket* ws); virtual void onMessage(WebSocket* ws, const WebSocket::Data& data); @@ -386,7 +389,7 @@ class SIOClientImpl : void send(const std::string& endpoint, const std::string& s); void send(const std::string& endpoint, const std::vector& s); - void send(SocketIOPacket *packet); + void send(std::shared_ptr& packet); void emit(const std::string& endpoint, const std::string& eventname, const std::string& args); void emit(const std::string& endpoint, const std::string& eventname, const std::vector& args); @@ -430,7 +433,14 @@ void SIOClientImpl::handshake() request->setUrl(pre.str()); request->setRequestType(HttpRequest::Type::GET); - request->setResponseCallback(CC_CALLBACK_2(SIOClientImpl::handshakeResponse, this)); + std::weak_ptr self = shared_from_this(); + auto callback = [self](HttpClient* client, HttpResponse *resp) { + auto conn = self.lock(); + if (conn) { + conn->handshakeResponse(client, resp); + } + }; + request->setResponseCallback(callback); request->setTag("handshake"); CCLOGINFO("SIOClientImpl::handshake() waiting"); @@ -627,13 +637,13 @@ void SIOClientImpl::disconnect() _ws->close(); } -SIOClientImpl* SIOClientImpl::create(const Uri& uri, const std::string& caFilePath) +std::shared_ptr SIOClientImpl::create(const Uri& uri, const std::string& caFilePath) { SIOClientImpl *s = new (std::nothrow) SIOClientImpl(uri, caFilePath); if (s && s->init()) { - return s; + return std::shared_ptr(s); } return nullptr; @@ -651,7 +661,7 @@ void SIOClientImpl::addClient(const std::string& endpoint, SIOClient* client) void SIOClientImpl::connectToEndpoint(const std::string& endpoint) { - SocketIOPacket *packet = SocketIOPacket::createPacketWithType("connect", _version); + auto packet = SocketIOPacket::createPacketWithType("connect", _version); packet->setEndpoint(endpoint); this->send(packet); } @@ -679,7 +689,7 @@ void SIOClientImpl::disconnectFromEndpoint(const std::string& endpoint) void SIOClientImpl::heartbeat(float /*dt*/) { - SocketIOPacket *packet = SocketIOPacket::createPacketWithType("heartbeat", _version); + auto packet = SocketIOPacket::createPacketWithType("heartbeat", _version); this->send(packet); @@ -692,7 +702,7 @@ void SIOClientImpl::send(const std::string& endpoint, const std::vectorsetEndpoint(endpoint); for(auto &i : s) { @@ -715,7 +725,7 @@ void SIOClientImpl::send(const std::string& endpoint, const std::string& s) send(endpoint, t); } -void SIOClientImpl::send(SocketIOPacket *packet) +void SIOClientImpl::send(std::shared_ptr& packet) { std::string req = packet->toString(); if (_connected) @@ -730,7 +740,7 @@ void SIOClientImpl::send(SocketIOPacket *packet) void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventname, const std::string& args) { CCLOGINFO("Emitting event \"%s\"", eventname.c_str()); - SocketIOPacket *packet = SocketIOPacket::createPacketWithType("event", _version); + auto packet = SocketIOPacket::createPacketWithType("event", _version); packet->setEndpoint(endpoint == "/" ? "" : endpoint); packet->setEvent(eventname); packet->addData(args); @@ -740,7 +750,7 @@ void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventna void SIOClientImpl::emit(const std::string& endpoint, const std::string& eventname, const std::vector& args) { CCLOGINFO("Emitting event \"%s\"", eventname.c_str()); - SocketIOPacket *packet = SocketIOPacket::createPacketWithType("event", _version); + auto packet = SocketIOPacket::createPacketWithType("event", _version); packet->setEndpoint(endpoint == "/" ? "" : endpoint); packet->setEvent(eventname); for (auto &arg : args) { @@ -753,7 +763,9 @@ void SIOClientImpl::onOpen(WebSocket* /*ws*/) { _connected = true; - SocketIO::getInstance()->addSocket(_uri.getAuthority(), this); + auto self = shared_from_this(); + + SocketIO::getInstance()->addSocket(_uri.getAuthority(), self); if (_version == SocketIOPacket::SocketIOVersion::V10x) { @@ -761,14 +773,20 @@ void SIOClientImpl::onOpen(WebSocket* /*ws*/) _ws->send(s); } - Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(SIOClientImpl::heartbeat), this, (_heartbeat * .9f), false); + std::weak_ptr selfWeak = shared_from_this(); + auto f = [selfWeak](float dt) { + auto conn = selfWeak.lock(); + if(conn) + conn->heartbeat(dt); + }; + + Director::getInstance()->getScheduler()->schedule(f, this, (_heartbeat * .9f), false, "heart_beat"); for (auto& client : _clients) { client.second->onOpen(); } - CCLOGINFO("SIOClientImpl::onOpen socket connected!"); } void SIOClientImpl::onMessage(WebSocket* /*ws*/, const WebSocket::Data& data) @@ -1012,11 +1030,9 @@ void SIOClientImpl::onClose(WebSocket* /*ws*/) _connected = false; if (Director::getInstance()) Director::getInstance()->getScheduler()->unscheduleAllForTarget(this); - + SocketIO::getInstance()->removeSocket(_uri.getAuthority()); } - - this->release(); } void SIOClientImpl::onError(WebSocket* /*ws*/, const WebSocket::ErrorCode& error) @@ -1025,13 +1041,12 @@ void SIOClientImpl::onError(WebSocket* /*ws*/, const WebSocket::ErrorCode& error } //begin SIOClient methods -SIOClient::SIOClient(const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate) +SIOClient::SIOClient(const std::string& path, std::shared_ptr& impl, SocketIO::SIODelegate& delegate) : _path(path) , _connected(false) , _socket(impl) , _delegate(&delegate) { - CC_SAFE_RETAIN(_socket); } SIOClient::~SIOClient() @@ -1040,7 +1055,6 @@ SIOClient::~SIOClient() { _socket->disconnectFromEndpoint(_path); } - CC_SAFE_RELEASE(_socket); } void SIOClient::onOpen() @@ -1108,7 +1122,6 @@ void SIOClient::disconnect() { setConnected(false); _socket->disconnectFromEndpoint(_path); - this->release(); } @@ -1116,7 +1129,6 @@ void SIOClient::socketClosed() { setConnected(false); _delegate->onClose(this); - this->release(); } @@ -1125,7 +1137,7 @@ bool SIOClient::isConnected() const return _connected && _socket && _socket->_connected ; } -void SIOClient::setConnected(bool connected) +void SIOClient::setConnected(bool connected) { _connected = connected; } @@ -1196,8 +1208,8 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele { Uri uriObj = Uri::parse(uri); - SIOClientImpl *socket = SocketIO::getInstance()->getSocket(uriObj.getAuthority()); - SIOClient *c = nullptr; + std::shared_ptr socket = SocketIO::getInstance()->getSocket(uriObj.getAuthority()); + SIOClient * c = nullptr; std::string path = uriObj.getPath(); if (path.empty()) @@ -1233,7 +1245,7 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele c->disconnect(); CCLOG("SocketIO: recreate a new socket, new client, connect"); - SIOClientImpl* newSocket = SIOClientImpl::create(uriObj, caFilePath); + std::shared_ptr newSocket = SIOClientImpl::create(uriObj, caFilePath); SIOClient *newC = new (std::nothrow) SIOClient(path, newSocket, delegate); newSocket->addClient(path, newC); @@ -1246,14 +1258,16 @@ SIOClient* SocketIO::connect(const std::string& uri, SocketIO::SIODelegate& dele return c; } -SIOClientImpl* SocketIO::getSocket(const std::string& uri) +std::shared_ptr SocketIO::getSocket(const std::string& uri) { - return _sockets.at(uri); + auto p = _sockets.find(uri); + if(p == _sockets.end()) return nullptr; + return p->second.lock(); } -void SocketIO::addSocket(const std::string& uri, SIOClientImpl* socket) +void SocketIO::addSocket(const std::string& uri, std::shared_ptr& socket) { - _sockets.insert(uri, socket); + _sockets.emplace(uri, socket); } void SocketIO::removeSocket(const std::string& uri) diff --git a/cocos/network/SocketIO.h b/cocos/network/SocketIO.h index 52957acb0a35..55d229303912 100644 --- a/cocos/network/SocketIO.h +++ b/cocos/network/SocketIO.h @@ -181,10 +181,11 @@ class CC_DLL SocketIO static SocketIO *_inst; - cocos2d::Map _sockets; + std::unordered_map> _sockets; - SIOClientImpl* getSocket(const std::string& uri); - void addSocket(const std::string& uri, SIOClientImpl* socket); + std::shared_ptr getSocket(const std::string& uri); + void addSocket(const std::string& uri, std::shared_ptr& socket); void removeSocket(const std::string& uri); friend class SIOClientImpl; @@ -210,9 +211,9 @@ class CC_DLL SIOClient std::string _path, _tag; bool _connected; - SIOClientImpl* _socket; - - SocketIO::SIODelegate* _delegate; + std::shared_ptr _socket; + + SocketIO::SIODelegate* _delegate = nullptr; EventRegistry _eventRegistry; @@ -236,7 +237,7 @@ class CC_DLL SIOClient * @param impl the SIOClientImpl object. * @param delegate the SIODelegate object. */ - SIOClient(const std::string& path, SIOClientImpl* impl, SocketIO::SIODelegate& delegate); + SIOClient(const std::string& path, std::shared_ptr& impl, SocketIO::SIODelegate& delegate); /** * Destructor of SIOClient class. */ diff --git a/cocos/network/WebSocket.cpp b/cocos/network/WebSocket.cpp index f1eddfbe6a69..892da61e36c7 100644 --- a/cocos/network/WebSocket.cpp +++ b/cocos/network/WebSocket.cpp @@ -468,11 +468,11 @@ class WebSocketFrame return false; } - _data.reserve(LWS_PRE + len); - _data.resize(LWS_PRE, 0x00); + _data.resize(LWS_PRE + len); + if (len > 0) { - _data.insert(_data.end(), buf, buf + len); + std::copy(buf, buf + len, _data.begin() + LWS_PRE); } _payload = _data.data() + LWS_PRE; @@ -545,7 +545,7 @@ WebSocket::WebSocket() WebSocket::~WebSocket() { LOGD("In the destructor of WebSocket (%p)\n", this); - + std::lock_guard lk(__instanceMutex); if (__websocketInstances != nullptr)