//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", getScriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } Mercury::Channel* lpChannel = clientMailbox_->getChannel(); if(proxy) { EntityMailbox* mb = proxy->getClientMailbox(); if(mb != NULL) { ERROR_MSG(boost::format("Proxy::giveClientTo: %1%[%2%] give client to %3%[%4%], %5% have clientMailbox.\n") % getScriptName() % getID() % proxy->getScriptName() % proxy->getID() % proxy->getScriptName()); onGiveClientToFailure(); return; } if(getCellMailbox()) { // 通知cell丢失客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onResetWitness); (*pBundle) << this->getID(); getCellMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } entitiesEnabled_ = false; getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); proxy->onGiveClientTo(lpChannel); setClientMailbox(NULL); addr(Mercury::Address::NONE); if(proxy->getClientMailbox() != NULL) { // 通知client销毁当前entity Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onEntityDestroyed); (*pBundle) << this->getID(); proxy->getClientMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } } }
//------------------------------------------------------------------------------------- void Proxy::onClientDeath(void) { DEBUG_MSG("%s::onClientDeath: %d.\n", this->getScriptName(), this->getID()); if(getClientMailbox() != NULL) { Py_DECREF(getClientMailbox()); setClientMailbox(NULL); addr(Mercury::Address::NONE); } SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onClientDeath")); }
//------------------------------------------------------------------------------------- void Entity::onLoseWitness(Mercury::Channel* pChannel) { KBE_ASSERT(this->getClientMailbox() != NULL && this->hasWitness()); getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); setClientMailbox(NULL); pWitness_->detach(this); Witness::ObjPool().reclaimObject(pWitness_); pWitness_ = NULL; SCOPED_PROFILE(SCRIPTCALL_PROFILE); SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onLoseWitness")); }
//------------------------------------------------------------------------------------- void Proxy::onGiveClientTo(Mercury::Channel* lpChannel) { setClientMailbox(new EntityMailbox(this->scriptModule_, &lpChannel->addr(), 0, id_, MAILBOX_TYPE_CLIENT)); addr(lpChannel->addr()); Baseapp::getSingleton().createClientProxies(this); if(getCellMailbox()) { // 通知cell获得客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onGetWitness); getCellMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } }
//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { Mercury::Channel* lpChannel = clientMailbox_->getChannel(); if(lpChannel == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.\n", getScriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(proxy) { EntityMailbox* mb = proxy->getClientMailbox(); if(mb != NULL) { ERROR_MSG("Proxy::giveClientTo: %s[%ld] give client to %s[%ld], %s have clientMailbox.", getScriptName(), getID(), proxy->getScriptName(), proxy->getID(), proxy->getScriptName()); onGiveClientToFailure(); return; } if(getCellMailbox()) { // 通知cell丢失客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onLoseWitness); getCellMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); proxy->onGiveClientTo(lpChannel); setClientMailbox(NULL); addr(Mercury::Address::NONE); } }
//------------------------------------------------------------------------------------- void Proxy::onClientDeath(void) { if(getClientMailbox() == NULL) { ERROR_MSG(boost::format("%1%::onClientDeath: %2%, channel is null!\n") % this->getScriptName() % this->getID()); return; } SCOPED_PROFILE(SCRIPTCALL_PROFILE); DEBUG_MSG(boost::format("%1%::onClientDeath: %2%.\n") % this->getScriptName() % this->getID()); Py_DECREF(getClientMailbox()); setClientMailbox(NULL); addr(Mercury::Address::NONE); entitiesEnabled_ = false; SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onClientDeath")); }
//------------------------------------------------------------------------------------- void Entity::onGetWitness(Mercury::Channel* pChannel) { KBE_ASSERT(this->getBaseMailbox() != NULL && !this->hasWitness()); PyObject* clientMailbox = PyObject_GetAttrString(this->getBaseMailbox(), "client"); KBE_ASSERT(clientMailbox != Py_None); EntityMailbox* client = static_cast<EntityMailbox*>(clientMailbox); // Py_INCREF(clientMailbox); 这里不需要增加引用, 因为每次都会产生一个新的对象 setClientMailbox(client); pWitness_ = Witness::ObjPool().createObject(); pWitness_->attach(this); Space* space = Spaces::findSpace(this->getSpaceID()); if(space) { space->onEntityAttachWitness(this); } SCOPED_PROFILE(SCRIPTCALL_PROFILE); SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onGetWitness")); }