//------------------------------------------------------------------------------------- void Proxy::initClientCellPropertys() { if(getClientMailbox() == NULL) return; Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->getID(); ENTITY_PROPERTY_UID spaceuid = ENTITY_BASE_PROPERTY_UTYPE_SPACEID; Mercury::FixedMessages::MSGInfo* msgInfo = Mercury::FixedMessages::getSingleton().isFixed("Property::spaceID"); if(msgInfo != NULL) { spaceuid = msgInfo->msgid; } (*pBundle) << spaceuid << this->getSpaceID(); MemoryStream* s = MemoryStream::ObjPool().createObject(); addPositionAndDirectionToStream(*s); (*pBundle).append(s); MemoryStream::ObjPool().reclaimObject(s); // celldata获取客户端感兴趣的数据初始化客户端 如:ALL_CLIENTS s = MemoryStream::ObjPool().createObject(); addCellDataToStream(ED_FLAG_ALL_CLIENTS|ED_FLAG_CELL_PUBLIC_AND_OWN|ED_FLAG_OWN_CLIENT, s); (*pBundle).append(*s); MemoryStream::ObjPool().reclaimObject(s); //getClientMailbox()->postMail((*pBundle)); //Mercury::Bundle::ObjPool().reclaimObject(pBundle); sendToClient(ClientInterface::onUpdatePropertys, pBundle); }
//------------------------------------------------------------------------------------- void Entity::backupCellData() { AUTO_SCOPED_PROFILE("backup"); if(baseMailbox_ != NULL) { // 将当前的cell部分数据打包 一起发送给base部分备份 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::onBackupEntityCellData); (*pBundle) << id_; MemoryStream* s = MemoryStream::ObjPool().createObject(); addPositionAndDirectionToStream(*s); (*pBundle).append(s); MemoryStream::ObjPool().reclaimObject(s); s = MemoryStream::ObjPool().createObject(); addCellDataToStream(ENTITY_CELL_DATA_FLAGS, s); (*pBundle).append(s); MemoryStream::ObjPool().reclaimObject(s); baseMailbox_->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } else { WARNING_MSG(boost::format("Entity::backupCellData(): %1% %2% has no base!\n") % this->getScriptName() % this->getID()); } }
//------------------------------------------------------------------------------------- void Base::addCellDataToStream(uint32 flags, MemoryStream* s, bool useAliasID) { addPositionAndDirectionToStream(*s, useAliasID); if (!cellDataDict_) return; ScriptDefModule::PROPERTYDESCRIPTION_MAP& propertyDescrs = pScriptModule_->getCellPropertyDescriptions(); ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator iter = propertyDescrs.begin(); for(; iter != propertyDescrs.end(); ++iter) { PropertyDescription* propertyDescription = iter->second; if(flags == 0 || (flags & propertyDescription->getFlags()) > 0) { PyObject* pyVal = PyDict_GetItemString(cellDataDict_, propertyDescription->getName()); if(useAliasID && pScriptModule_->usePropertyDescrAlias()) { (*s) << propertyDescription->aliasIDAsUint8(); } else { (*s) << propertyDescription->getUType(); } if(!propertyDescription->getDataType()->isSameType(pyVal)) { ERROR_MSG(fmt::format("{}::addCellDataToStream: {}({}) not is ({})!\n", this->scriptName(), propertyDescription->getName(), (pyVal ? pyVal->ob_type->tp_name : "unknown"), propertyDescription->getDataType()->getName())); PyObject* pydefval = propertyDescription->getDataType()->parseDefaultStr(""); propertyDescription->getDataType()->addToStream(s, pydefval); Py_DECREF(pydefval); } else { propertyDescription->getDataType()->addToStream(s, pyVal); } if (PyErr_Occurred()) { PyErr_PrintEx(0); DEBUG_MSG(fmt::format("{}::addCellDataToStream: {} error!\n", this->scriptName(), propertyDescription->getName())); } } } }
//------------------------------------------------------------------------------------- void Base::addPersistentsDataToStream(uint32 flags, MemoryStream* s) { std::vector<ENTITY_PROPERTY_UID> log; // 再将base中存储属性取出 PyObject* pydict = PyObject_GetAttrString(this, "__dict__"); // 先将celldata中的存储属性取出 ScriptDefModule::PROPERTYDESCRIPTION_MAP& propertyDescrs = scriptModule_->getPersistentPropertyDescriptions(); ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator iter = propertyDescrs.begin(); if(scriptModule_->hasCell()) { addPositionAndDirectionToStream(*s); } for(; iter != propertyDescrs.end(); ++iter) { PropertyDescription* propertyDescription = iter->second; std::vector<ENTITY_PROPERTY_UID>::const_iterator finditer = std::find(log.begin(), log.end(), propertyDescription->getUType()); if(finditer != log.end()) continue; const char* attrname = propertyDescription->getName(); if(propertyDescription->isPersistent() && (flags & propertyDescription->getFlags()) > 0) { PyObject *key = PyUnicode_FromString(attrname); if(cellDataDict_ != NULL && PyDict_Contains(cellDataDict_, key) > 0) { PyObject* pyVal = PyDict_GetItemString(cellDataDict_, attrname); if(!propertyDescription->getDataType()->isSameType(pyVal)) { CRITICAL_MSG(fmt::format("{}::addPersistentsDataToStream: {} persistent[{}] type(curr_py: {} != {}) is error.\n", this->scriptName(), this->id(), attrname, (pyVal ? pyVal->ob_type->tp_name : "unknown"), propertyDescription->getDataType()->getName())); } else { (*s) << propertyDescription->getUType(); log.push_back(propertyDescription->getUType()); propertyDescription->addPersistentToStream(s, pyVal); DEBUG_PERSISTENT_PROPERTY("addCellPersistentsDataToStream", attrname); } } else if(PyDict_Contains(pydict, key) > 0) { PyObject* pyVal = PyDict_GetItem(pydict, key); if(!propertyDescription->getDataType()->isSameType(pyVal)) { CRITICAL_MSG(fmt::format("{}::addPersistentsDataToStream: {} persistent[{}] type(curr_py: {} != {}) is error.\n", this->scriptName(), this->id(), attrname, (pyVal ? pyVal->ob_type->tp_name : "unknown"), propertyDescription->getDataType()->getName())); } else { (*s) << propertyDescription->getUType(); log.push_back(propertyDescription->getUType()); propertyDescription->addPersistentToStream(s, pyVal); DEBUG_PERSISTENT_PROPERTY("addBasePersistentsDataToStream", attrname); } } else { CRITICAL_MSG(fmt::format("{}::addPersistentsDataToStream: {} not found Persistent[{}].\n", this->scriptName(), this->id(), attrname)); } Py_DECREF(key); } SCRIPT_ERROR_CHECK(); } Py_XDECREF(pydict); SCRIPT_ERROR_CHECK(); }