// Copyright 2008-2018 Yolo Technologies, Inc. All Rights Reserved. https://www.comblockengine.com



#include "kbcmd.h"

#include "client_sdk.h"

#include "client_sdk_unity.h"	

#include "entitydef/entitydef.h"

#include "entitydef/scriptdef_module.h"

#include "entitydef/property.h"

#include "entitydef/method.h"

#include "entitydef/datatype.h"

#include "network/fixed_messages.h"



namespace KBEngine {	



static std::string headerBody = "/*\n\tGenerated by KBEngine!\n\tPlease do not modify this file!\n#REPLACE#\ttools = kbcmd\n*/\n\n";

static std::string moduleSuffix = "Base";



//-------------------------------------------------------------------------------------

ClientSDKUnity::ClientSDKUnity():

	ClientSDK(),

	initBody_()

{

}



//-------------------------------------------------------------------------------------

ClientSDKUnity::~ClientSDKUnity()

{



}



//-------------------------------------------------------------------------------------

std::string ClientSDKUnity::typeToType(const std::string& type)

{

	if (type == "INT8")

	{

		return "SByte";

	}

	else if (type == "INT16")

	{

		return "Int16";

	}

	else if (type == "INT32")

	{

		return "Int32";

	}

	else if (type == "INT64")

	{

		return "Int64";

	}

	else if (type == "UINT8")

	{

		return "Byte";

	}

	else if (type == "UINT16")

	{

		return "UInt16";

	}

	else if (type == "UINT32")

	{

		return "UInt32";

	}

	else if (type == "UINT64")

	{

		return "UInt64";

	}

	else if (type == "FLOAT")

	{

		return "float";

	}

	else if (type == "DOUBLE")

	{

		return "double";

	}

	else if (type == "STRING")

	{

		return "string";

	}

	else if (type == "UNICODE")

	{

		return "string";

	}

	else if (type == "PYTHON")

	{

		return "byte[]";

	}

	else if (type == "PY_DICT")

	{

		return "byte[]";

	}

	else if (type == "PY_TUPLE")

	{

		return "byte[]";

	}

	else if (type == "PY_LIST")

	{

		return "byte[]";

	}

	else if (type == "BLOB")

	{

		return "byte[]";

	}

	else if (type == "ARRAY")

	{

		return "List";

	}

	else if (type == "FIXED_DICT")

	{

		return "Dictionary";

	}

#ifdef CLIENT_NO_FLOAT

	else if (type == "VECTOR2")

	{

		return "Vector2Int";

	}

	else if (type == "VECTOR3")

	{

		return "Vector3Int";

	}

	else if (type == "VECTOR4")

	{

		return "Vector4Int";

	}

#else

	else if (type == "VECTOR2")

	{

		return "Vector2";

	}

	else if (type == "VECTOR3")

	{

		return "Vector3";

	}

	else if (type == "VECTOR4")

	{

		return "Vector4";

	}

#endif

	else if (type == "ENTITYCALL")

	{

		return "byte[]";

	}



	return type;

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateTypeFileName()

{

	sourcefileName_ = "KBETypes.cs";

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateEntityModuleFileName(const std::string& moduleName)

{

	sourcefileName_ = moduleName + moduleSuffix + ".cs";

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateServerErrorDescrsModuleFileName()

{

	sourcefileName_ = "ServerErrorDescrs.cs";

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateEngineMessagesModuleFileName()

{

	sourcefileName_ = "Messages.cs";

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateDefsCustomTypesModuleFileName()

{

	sourcefileName_ = "CustomDataTypes.cs";

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeServerErrorDescrsModuleBegin()

{

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", "");



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += fmt::format("\tpublic struct {}\n\t{{\n\t\tpublic string name;\n\t\tpublic string descr;\n\t\tpublic UInt16 id;\n", "ServerErr");

	sourcefileBody_ += "\t}";



	sourcefileBody_ += "\n\n\t// defined in */res/server/server_errors.xml\n\n";

	sourcefileBody_ += fmt::format("\tpublic class {}\n\t{{\n", "ServerErrorDescrs");

	sourcefileBody_ += "\t\tpublic static Dictionary<UInt16, ServerErr> serverErrs = new Dictionary<UInt16, ServerErr>();\n\n";



	sourcefileBody_ += "\t\tpublic ServerErrorDescrs()\n\t\t{\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeServerErrorDescrsModuleErrDescr(int errorID, const std::string& errname, const std::string& errdescr)

{

	sourcefileBody_ += fmt::format("\t\t\t{{\n\t\t\t\tServerErr e;\n\t\t\t\te.id = {};\n\t\t\t\te.name = \"{}\";\n\t\t\t\te.descr = \"{}\";\n\n\t\t\t\tserverErrs.Add(e.id, e);\n", errorID, errname, errdescr);

	sourcefileBody_ += "\t\t\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeServerErrorDescrsModuleEnd()

{

	sourcefileBody_ += "\n\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic void Clear()\n\t\t{\n\t\t\tserverErrs.Clear();\n\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic string serverErrStr(UInt16 id)\n\t\t{\n\t\t\tServerErr e;\n\t\t\tif(!serverErrs.TryGetValue(id, out e))\n\t\t\t{\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\treturn e.name + \"[\" + e.descr + \"]\";\n\t\t}\n\n";

	sourcefileBody_ += "\t\tpublic ServerErr serverErr(UInt16 id)\n\t\t{\n\t\t\tServerErr e;\n\t\t\tserverErrs.TryGetValue(id, out e);\n\t\t\treturn e;\n\t\t}\n\n";



	sourcefileBody_ += "\n\n\n\t}\n}";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEngineMessagesModuleBegin()

{

	initBody_ = "";

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", "");



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += "\tusing MessageID = System.UInt16;\n\n";



	sourcefileBody_ += "\t// engine-c++ messages\n\n";

	sourcefileBody_ += fmt::format("\tpublic class {}\n\t{{\n", "Message");



	sourcefileBody_ += "\t\tpublic MessageID id = 0;\n";

	sourcefileBody_ += "\t\tpublic string name;\n";

	sourcefileBody_ += "\t\tpublic Int16 msglen = -1;\n";

	sourcefileBody_ += "\t\tpublic List<Byte> argtypes = null;\n";

	sourcefileBody_ += "\t\tpublic sbyte argsType = 0;\n";



	sourcefileBody_ += "\n\t\tpublic Message(MessageID msgid, string msgname, Int16 length, sbyte argstype, List<Byte> msgargtypes)\n\t\t{\n";

	sourcefileBody_ += "\t\t\tid = msgid;\n";

	sourcefileBody_ += "\t\t\tname = msgname;\n";

	sourcefileBody_ += "\t\t\tmsglen = length;\n";

	sourcefileBody_ += "\t\t\targsType = argstype;\n\n";



	sourcefileBody_ += "\t\t\targtypes = msgargtypes;\n";



	sourcefileBody_ += "\t\t\t// Dbg.DEBUG_MSG(string.Format(\"Message::Message() : ({ 0 } / {1} / {2})!\", \n";

	sourcefileBody_ += "\t\t\t//\t\tmsgname, msgid, msglen));";



	sourcefileBody_ += "\n\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic virtual void handleMessage(MemoryStream msgstream)\n";

	sourcefileBody_ += "\t\t{\n";

	sourcefileBody_ += "\t\t}\n";



	sourcefileBody_ += "\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEngineMessagesModuleMessage(Network::ExposedMessageInfo& messageInfos, COMPONENT_TYPE componentType)

{

	sourcefileBody_ += fmt::format("\tpublic class Message_{} : Message\n\t{{\n", messageInfos.name);



	sourcefileBody_ += fmt::format("\n\t\tpublic Message_{}(MessageID msgid, string msgname, Int16 length, sbyte argstype, List<Byte> msgargtypes):\n\t\t\tbase(msgid, msgname, length, argstype, msgargtypes)\n\t\t{{\n", messageInfos.name);

	sourcefileBody_ += "\n\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic override void handleMessage(MemoryStream msgstream)\n";

	sourcefileBody_ += "\t\t{\n";



	if (messageInfos.argsTypes.size() == 0)

	{

		initBody_ += fmt::format("\t\t\tMessages.messages[\"{}\"] = new Message_{}({}, \"{}\", {}, {}, ", 

			messageInfos.name, messageInfos.name, messageInfos.id, messageInfos.name, messageInfos.msgLen, (int)messageInfos.argsType);



		initBody_ += "new List<Byte>());\n";



		if (componentType == CLIENT_TYPE)

		{

			if (messageInfos.argsType < 0)

			{

				sourcefileBody_ += fmt::format("\t\t\tKBEngineApp.app.{}(msgstream);\n", messageInfos.name);

			}

			else

			{

				sourcefileBody_ += fmt::format("\t\t\tKBEngineApp.app.{}();\n", messageInfos.name);

			}

		}

	}

	else

	{

		std::string argsparse = "";

		std::string giveargs = "";

		initBody_ += fmt::format("\n\t\t\tList<Byte> {}_argstypes = new List<Byte>();\n", messageInfos.name);



		for (size_t i = 0; i < messageInfos.argsTypes.size(); ++i)
		{
			int argindex = static_cast<int>(i + 1);
			std::string nativetype = datatype2nativetype(messageInfos.argsTypes[i]);



			KBE_ASSERT(nativetype != "FIXED_DICT" && nativetype != "ARRAY" && nativetype != "PYTHON" && nativetype != "ENTITYCALL");



			std::string readName = nativetype;

			std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

			readName[0] = std::toupper(readName[0]);



			argsparse += fmt::format("\t\t\t{} arg{} = msgstream.read{}();\n", typeToType(nativetype), argindex, readName);

			giveargs += fmt::format("arg{}, ", argindex);

			initBody_ += fmt::format("\t\t\t{}_argstypes.Add({});\n", messageInfos.name, (int)messageInfos.argsTypes[i]);

		}



		if (giveargs.size() > 0)

			giveargs.erase(giveargs.size() - 2, 2);



		initBody_ += fmt::format("\t\t\tMessages.messages[\"{}\"] = new Message_{}({}, \"{}\", {}, {}, {}_argstypes);\n", 

			messageInfos.name, messageInfos.name, messageInfos.id, messageInfos.name, messageInfos.msgLen, (int)messageInfos.argsType, messageInfos.name);

		

		if (componentType == CLIENT_TYPE)

		{

			sourcefileBody_ += argsparse;

			sourcefileBody_ += fmt::format("\t\t\tKBEngineApp.app.{}({});\n", messageInfos.name, giveargs);

		}

	}



	if (componentType == CLIENT_TYPE)

	{

		initBody_ += fmt::format("\t\t\tMessages.clientMessages[{}] = Messages.messages[\"{}\"];\n\n", messageInfos.id, messageInfos.name);

	}

	else if (componentType == LOGINAPP_TYPE)

	{

		initBody_ += fmt::format("\t\t\tMessages.loginappMessages[{}] = Messages.messages[\"{}\"];\n\n", messageInfos.id, messageInfos.name);

	}

	else if (componentType == BASEAPP_TYPE)

	{

		initBody_ += fmt::format("\t\t\tMessages.baseappMessages[{}] = Messages.messages[\"{}\"];\n\n", messageInfos.id, messageInfos.name);

	}



	sourcefileBody_ += "\t\t}\n";



	sourcefileBody_ += "\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEngineMessagesModuleEnd()

{

	sourcefileBody_ += fmt::format("\tpublic class {}\n\t{{\n", "Messages");



	sourcefileBody_ += "\t\tpublic static Dictionary<MessageID, Message> loginappMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<MessageID, Message> baseappMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<MessageID, Message> clientMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<string, Message> messages = new Dictionary<string, Message>();\n";



	sourcefileBody_ += "\n\t\tpublic static void clear()\n\t\t{\n";



	sourcefileBody_ += "\t\t\tloginappMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\t\tbaseappMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\t\tclientMessages = new Dictionary<MessageID, Message>();\n";

	sourcefileBody_ += "\t\t\tmessages = new Dictionary<string, Message>();\n";

	sourcefileBody_ += "\n\t\t\tinit();";



	sourcefileBody_ += "\n\t\t}\n\n";



	sourcefileBody_ += "\n\t\tpublic static bool init()\n\t\t{\n";



	sourcefileBody_ += initBody_;



	sourcefileBody_ += "\n\t\t\treturn true;";

	sourcefileBody_ += "\n\t\t}";

	sourcefileBody_ += "\n\t}";

	sourcefileBody_ += "\n}";

	return true;

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onCreateEntityDefsModuleFileName()

{

	sourcefileName_ = "EntityDef.cs";

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleBegin()

{

	initBody_ = "";

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", "");



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += fmt::format("\tpublic class {}\n\t{{\n", "EntityDef");



	sourcefileBody_ += "\t\tpublic static Dictionary<string, UInt16> datatype2id = new Dictionary<string, UInt16>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<string, DATATYPE_BASE> datatypes = new Dictionary<string, DATATYPE_BASE>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<UInt16, DATATYPE_BASE> id2datatypes = new Dictionary<UInt16, DATATYPE_BASE>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<string, Int32> entityclass = new Dictionary<string, Int32>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<string, ScriptModule> moduledefs = new Dictionary<string, ScriptModule>();\n";

	sourcefileBody_ += "\t\tpublic static Dictionary<UInt16, ScriptModule> idmoduledefs = new Dictionary<UInt16, ScriptModule>();\n";



	sourcefileBody_ += "\n\t\tpublic static bool init()\n\t\t{\n";

	sourcefileBody_ += "\t\t\tinitDataTypes();\n";

	sourcefileBody_ += "\t\t\tinitDefTypes();\n";

	sourcefileBody_ += "\t\t\tinitScriptModules();\n";

	sourcefileBody_ += "\t\t\treturn true;\n";

	sourcefileBody_ += "\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic static bool reset()\n\t\t{\n";

	sourcefileBody_ += "\t\t\tclear();\n";

	sourcefileBody_ += "\t\t\treturn init();\n";

	sourcefileBody_ += "\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic static void clear()\n";

	sourcefileBody_ += "\t\t{\n";

	sourcefileBody_ += "\t\t\tdatatype2id.Clear();\n";

	sourcefileBody_ += "\t\t\tdatatypes.Clear();\n";

	sourcefileBody_ += "\t\t\tid2datatypes.Clear();\n";

	sourcefileBody_ += "\t\t\tentityclass.Clear();\n";

	sourcefileBody_ += "\t\t\tmoduledefs.Clear();\n";

	sourcefileBody_ += "\t\t\tidmoduledefs.Clear();\n";

	sourcefileBody_ += "\t\t}\n\n";



	sourcefileBody_ += "\t\tpublic static void initDataTypes()\n";

	sourcefileBody_ += "\t\t{\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"UINT8\"] = new DATATYPE_UINT8();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"UINT16\"] = new DATATYPE_UINT16();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"UINT32\"] = new DATATYPE_UINT32();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"UINT64\"] = new DATATYPE_UINT64();\n\n";



	sourcefileBody_ += "\t\t\tdatatypes[\"INT8\"] = new DATATYPE_INT8();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"INT16\"] = new DATATYPE_INT16();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"INT32\"] = new DATATYPE_INT32();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"INT64\"] = new DATATYPE_INT64();\n\n";



	sourcefileBody_ += "\t\t\tdatatypes[\"FLOAT\"] = new DATATYPE_FLOAT();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"DOUBLE\"] = new DATATYPE_DOUBLE();\n\n";



	sourcefileBody_ += "\t\t\tdatatypes[\"STRING\"] = new DATATYPE_STRING();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"VECTOR2\"] = new DATATYPE_VECTOR2();\n\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"VECTOR3\"] = new DATATYPE_VECTOR3();\n\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"VECTOR4\"] = new DATATYPE_VECTOR4();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"PYTHON\"] = new DATATYPE_PYTHON();\n\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"UNICODE\"] = new DATATYPE_UNICODE();\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"ENTITYCALL\"] = new DATATYPE_ENTITYCALL();\n\n";

	sourcefileBody_ += "\t\t\tdatatypes[\"BLOB\"] = new DATATYPE_BLOB();\n";

	sourcefileBody_ += "\t\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleEnd()

{

	sourcefileBody_ += "\t}\n\n\n}";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitScriptBegin()

{

	sourcefileBody_ += "\t\tpublic static void initScriptModules()\n";

	sourcefileBody_ += "\t\t{\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitScriptEnd()

{

	sourcefileBody_ += "\t\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitDefTypesBegin()

{

	sourcefileBody_ += "\t\tpublic static void initDefTypes()\n";

	sourcefileBody_ += "\t\t{\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitDefTypesEnd()

{

	sourcefileBody_ += "\t\t\tforeach(string datatypeStr in EntityDef.datatypes.Keys)\n\t\t\t{\n";

	sourcefileBody_ += "\t\t\t\tDATATYPE_BASE dataType = EntityDef.datatypes[datatypeStr];\n";

	sourcefileBody_ += "\t\t\t\tif(dataType != null)\n\t\t\t\t{\n";

	sourcefileBody_ += "\t\t\t\t\tdataType.bind();\n\t\t\t\t}\n\t\t\t}\n";



	sourcefileBody_ += "\t\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitDefType(const DataType* pDataType)

{

	uint16 typeID = datatype2id(pDataType->getName());

	if (typeID == 0 || strcmp(pDataType->getName(), "FIXED_DICT") == 0 || strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		typeID = pDataType->id();

		KBE_ASSERT(typeID > datatype2id("KBE_DATATYPE2ID_MAX"));

	}



	static std::map< int, std::string > type2name;



	sourcefileBody_ += fmt::format("\t\t\t{{\n");

	sourcefileBody_ += fmt::format("\t\t\t\tUInt16 utype = {};\n", typeID);



	std::string typeName = (strlen(pDataType->aliasName()) > 0 ? pDataType->aliasName() : fmt::format("AnonymousArray_{}", typeID));

	sourcefileBody_ += fmt::format("\t\t\t\tstring typeName = \"{}\";\n", typeName);



	std::map< int, std::string >::iterator iter = type2name.find(typeID);

	if(iter == type2name.end())

		type2name[typeID] = (strlen(pDataType->getName()) > 0 ? pDataType->getName() : typeName);



	if (strcmp(pDataType->getName(), "FIXED_DICT") == 0)

	{

		sourcefileBody_ += fmt::format("\t\t\t\tDATATYPE_{} datatype = new DATATYPE_{}();\n", typeName, typeName);

		sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.datatypes[typeName] = datatype;\n");

	}

	else if (strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		FixedArrayType* pFixedArrayType = const_cast<FixedArrayType*>(static_cast<const FixedArrayType*>(pDataType));

		typeID = datatype2id(pFixedArrayType->getDataType()->getName());



		if (typeID == 0 || strcmp(pFixedArrayType->getDataType()->getName(), "FIXED_DICT") == 0 ||

			strcmp(pFixedArrayType->getDataType()->getName(), "ARRAY") == 0)

			typeID = pFixedArrayType->getDataType()->id();



		sourcefileBody_ += fmt::format("\t\t\t\tDATATYPE_{} datatype = new DATATYPE_{}();\n", typeName, typeName);

		sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.datatypes[typeName] = datatype;\n");

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\t\t\tstring name = \"{}\";\n", pDataType->getName());

		sourcefileBody_ += fmt::format("\t\t\t\tDATATYPE_BASE val = null;\n");

		sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.datatypes.TryGetValue(name, out val);\n");

		sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.datatypes[typeName] = val;\n");

	}



	sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.id2datatypes[utype] = EntityDef.datatypes[typeName];\n");

	sourcefileBody_ += fmt::format("\t\t\t\tEntityDef.datatype2id[typeName] = utype;\n");

	sourcefileBody_ += fmt::format("\t\t\t}}\n\n");



	return true;

}



//-------------------------------------------------------------------------------------

void ClientSDKUnity::onEntityCallModuleFileName(const std::string& moduleName)

{

	sourcefileName_ = std::string("EntityCall") + moduleName + moduleSuffix + ".cs";

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityCallBegin(ScriptDefModule* pScriptDefModule)

{

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", fmt::format("\t\n",

		sourcefileName_));



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += std::string("\t// defined in ") + pScriptDefModule->getDefSourceFile() + "\n";
	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityCallEnd(ScriptDefModule* pScriptDefModule)

{

	sourcefileBody_ += fmt::format("\t}}\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityCallMethodBegin(ScriptDefModule* pScriptDefModule, MethodDescription* pMethodDescription, const char* fillString1, const char* fillString2, COMPONENT_TYPE componentType)

{

	sourcefileBody_ += fmt::format("\t\tpublic void {}({})\n\t\t{{\n", pMethodDescription->getName(), fillString1);



	sourcefileBody_ += fmt::format("\t\t\tBundle pBundle = newCall(\"{}\", {});\n", pMethodDescription->getName(), (pScriptDefModule->isComponentModule() ? "entityComponentPropertyID" : "0"));

	sourcefileBody_ += fmt::format("\t\t\tif(pBundle == null)\n");

	sourcefileBody_ += fmt::format("\t\t\t\treturn;\n\n");



	std::vector<DataType*>& argTypes = pMethodDescription->getArgTypes();

	std::vector<DataType*>::iterator iter = argTypes.begin();



	std::string writeName;



	int i = 1;



	for (; iter != argTypes.end(); ++iter)

	{

		DataType* pDataType = (*iter);



		if (pDataType->type() == DATA_TYPE_FIXEDDICT)

		{

			writeName = fmt::format("((DATATYPE_{})EntityDef.id2datatypes[{}]).addToStreamEx(bundle, arg{})",

				pDataType->aliasName(), pDataType->id(), i);

		}

		else if (pDataType->type() == DATA_TYPE_FIXEDARRAY)

		{

			if (strlen(pDataType->aliasName()) > 0)

			{

				writeName = fmt::format("((DATATYPE_{})EntityDef.id2datatypes[{}]).addToStreamEx(bundle, arg{})",

					pDataType->aliasName(), pDataType->id(), i);

			}

			else

			{

				writeName = fmt::format("((DATATYPE_AnonymousArray_{})EntityDef.id2datatypes[{}]).addToStreamEx(bundle, arg{})",

					pDataType->id(), pDataType->id(), i);

			}

		}

		else

		{

			writeName = datatype2nativetype(pDataType->getName());

			std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

			writeName[0] = std::toupper(writeName[0]);



			writeName = fmt::format("bundle.write{}(arg{})", writeName, i);

		}



		sourcefileBody_ += fmt::format("\t\t\t{};\n", writeName);



		i++;

	}



	sourcefileBody_ += fmt::format("\t\t\tsendCall(null);\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityCallMethodEnd(ScriptDefModule* pScriptDefModule, MethodDescription* pMethodDescription)

{

	sourcefileBody_ += fmt::format("\t\t}}\n\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeBaseEntityCallBegin(ScriptDefModule* pScriptDefModule)

{

	std::string newModuleName;



	newModuleName = std::string("EntityBaseEntityCall_") + std::string(pScriptDefModule->getName()) + moduleSuffix;

	sourcefileBody_ += fmt::format("\tpublic class {} : EntityCall\n\t{{\n", newModuleName);



	if (!pScriptDefModule->isComponentModule())

	{

		std::string initstr = "";



		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();



			sourcefileBody_ += fmt::format("\t\tpublic EntityBaseEntityCall_{}{} {} = null;\n",

				pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix, pPropertyDescription->getName());



			initstr += fmt::format("\t\t\t{} = new EntityBaseEntityCall_{}{}({}, id);\n",

				pPropertyDescription->getName(), pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix, pPropertyDescription->getUType());

		}



		sourcefileBody_ += fmt::format("\n\t\tpublic {}(Int32 eid, string ename) : base(eid, ename)\n\t\t{{\n", newModuleName);

		sourcefileBody_ += initstr;

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\tpublic UInt16 entityComponentPropertyID = 0;\n");



		sourcefileBody_ += fmt::format("\n\t\tpublic {}(UInt16 ecpID, Int32 eid) : base(eid, \"{}\")\n\t\t{{\n", newModuleName, pScriptDefModule->getName());

		sourcefileBody_ += fmt::format("\t\t\tentityComponentPropertyID = ecpID;\n");

	}



	sourcefileBody_ += fmt::format("\t\t\ttype = ENTITYCALL_TYPE.ENTITYCALL_TYPE_BASE;\n");

	sourcefileBody_ += fmt::format("\t\t}}\n\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeBaseEntityCallEnd(ScriptDefModule* pScriptDefModule)

{

	sourcefileBody_ += fmt::format("\t}}\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeCellEntityCallBegin(ScriptDefModule* pScriptDefModule)

{

	std::string newModuleName;



	newModuleName = std::string("EntityCellEntityCall_") + std::string(pScriptDefModule->getName()) + moduleSuffix;

	sourcefileBody_ += fmt::format("\tpublic class {} : EntityCall\n\t{{\n", newModuleName);



	if (!pScriptDefModule->isComponentModule())

	{

		std::string initstr = "";



		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();



			sourcefileBody_ += fmt::format("\t\tpublic EntityCellEntityCall_{}{} {} = null;\n",

				pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix, pPropertyDescription->getName());



			initstr += fmt::format("\t\t\t{} = new EntityCellEntityCall_{}{}({}, id);\n",

				pPropertyDescription->getName(), pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix, pPropertyDescription->getUType());

		}



		sourcefileBody_ += fmt::format("\n\t\tpublic {}(Int32 eid, string ename) : base(eid, ename)\n\t\t{{\n", newModuleName);

		sourcefileBody_ += initstr;

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\tpublic UInt16 entityComponentPropertyID = 0;\n");



		sourcefileBody_ += fmt::format("\n\t\tpublic {}(UInt16 ecpID, Int32 eid) : base(eid, \"{}\")\n\t\t{{\n", newModuleName, pScriptDefModule->getName());

		sourcefileBody_ += fmt::format("\t\t\tentityComponentPropertyID = ecpID;\n");

		sourcefileBody_ += fmt::format("\t\t\tclassName = \"{}\";\n", pScriptDefModule->getName());

	}



	sourcefileBody_ += fmt::format("\t\t\ttype = ENTITYCALL_TYPE.ENTITYCALL_TYPE_CELL;\n");

	sourcefileBody_ += fmt::format("\t\t}}\n\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeCellEntityCallEnd(ScriptDefModule* pScriptDefModule)

{

	sourcefileBody_ += fmt::format("\t}}\n");

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeCustomDataTypesBegin()

{

	initBody_ = "";

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", "");



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeCustomDataTypesEnd()

{

	sourcefileBody_ += "\n}";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::createArrayChildClass(DataType* pRootDataType, DataType* pDataType, const std::string& className, const std::string& tabs, int numLayer)

{

	sourcefileBody_ += fmt::format("{}public class DATATYPE_{} : DATATYPE_BASE\n{}{{\n", tabs, className, tabs);



	uint16 typeID = datatype2id(pDataType->getName());

	if (typeID == 0 || strcmp(pDataType->getName(), "FIXED_DICT") == 0 || strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		typeID = pDataType->id();

		KBE_ASSERT(typeID > datatype2id("KBE_DATATYPE2ID_MAX"));

	}



	std::string readName;

	std::string typeName = (strlen(pDataType->aliasName()) > 0 ? pDataType->aliasName() : fmt::format("AnonymousArray_{}", typeID));



	bool isFixedType = strcmp(pDataType->getName(), "FIXED_DICT") == 0 ||

		strcmp(pDataType->getName(), "ARRAY") == 0;



	if (strcmp(pDataType->getName(), "FIXED_DICT") == 0)

	{

		readName = fmt::format("itemType.createFromStreamEx(stream)");



		sourcefileBody_ += fmt::format("{}\tprivate DATATYPE_{} itemType = new DATATYPE_{}();\n\n",

			tabs, pDataType->aliasName(), pDataType->aliasName());



		// 如果是非匿名的数组,则第一层解析应该直接设置为有名字的类别

		// 否则设置为系统List类别

		if (numLayer == 1)

		{

			if (strlen(pRootDataType->aliasName()) == 0 || pRootDataType->aliasName()[0] == '_')

			{

				typeName = fmt::format("List<{}>", typeName);

			}

			else

			{

				typeName = pRootDataType->aliasName();

			}

		}

		else

		{

			typeName = fmt::format("List<{}>", typeName);

		}



		sourcefileBody_ += fmt::format("{}\tpublic {} createFromStreamEx(MemoryStream stream)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tUInt32 size = stream.readUint32();\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{} datas = new {}();\n\n", tabs, typeName, typeName);

		sourcefileBody_ += fmt::format("{}\t\twhile(size > 0)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\t--size;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\tdatas.Add({});\n", tabs, readName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\treturn datas;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n\n", tabs);





		sourcefileBody_ += fmt::format("{}\tpublic void addToStreamEx(Bundle stream, {} v)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tstream.writeUint32((UInt32)v.Count);\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\tfor(int i=0; i<v.Count; ++i)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);



		std::string writeName;

		if (isFixedType)

		{

			writeName = fmt::format("itemType.addToStreamEx(stream, v[i])");

		}

		else

		{

			writeName = datatype2nativetype(pDataType->getName());

			std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

			writeName[0] = std::toupper(writeName[0]);

			writeName = fmt::format("stream.write{}(v[i])", writeName);

		}



		sourcefileBody_ += fmt::format("{}\t\t\t{};\n", tabs, writeName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n", tabs);

	}

	else if (strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		FixedArrayType* pFixedArrayType = static_cast<FixedArrayType*>(pDataType);



		std::string classNameStr = typeName;



		// 如果是非匿名的数组,则第一层解析应该直接设置为有名字的类别

		// 否则设置为系统List类别

		if (numLayer == 1)

		{

			if (strlen(pRootDataType->aliasName()) == 0 || pRootDataType->aliasName()[0] == '_')

			{

				typeName = "";

				getArrayType(pFixedArrayType, typeName);

				typeName = fmt::format("List<{}>", typeName);

			}

			else

			{

				typeName = pRootDataType->aliasName();

			}

		}

		else

		{

			typeName = "";

			getArrayType(pFixedArrayType, typeName);

			typeName = fmt::format("List<{}>", typeName);

		}



		readName = fmt::format("itemType.createFromStreamEx(stream)");



		std::string childClassName = classNameStr + "_ChildArray";

		sourcefileBody_ += fmt::format("{}\tprivate DATATYPE_{} itemType = new DATATYPE_{}();\n\n",

			tabs, childClassName, childClassName);



		if (!createArrayChildClass(pRootDataType, pFixedArrayType->getDataType(), childClassName, tabs + "\t", numLayer + 1))

			return false;



		sourcefileBody_ += fmt::format("{}\tpublic {} createFromStreamEx(MemoryStream stream)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tUInt32 size = stream.readUint32();\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{} datas = new {}();\n\n", tabs, typeName, typeName);

		sourcefileBody_ += fmt::format("{}\t\twhile(size > 0)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\t--size;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\tdatas.Add({});\n", tabs, readName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\treturn datas;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n\n", tabs);





		sourcefileBody_ += fmt::format("{}\tpublic void addToStreamEx(Bundle stream, {} v)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tstream.writeUint32((UInt32)v.Count);\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\tfor(int i=0; i<v.Count; ++i)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);



		std::string writeName;

		if (isFixedType)

		{

			writeName = fmt::format("itemType.addToStreamEx(stream, v[i])", writeName);

		}

		else

		{

			writeName = datatype2nativetype(pDataType->getName());

			std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

			writeName[0] = std::toupper(writeName[0]);

			writeName = fmt::format("stream.write{}(v[i])", writeName);

		}



		sourcefileBody_ += fmt::format("{}\t\t\t{};\n", tabs, writeName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n", tabs);

	}

	else

	{

		readName = datatype2nativetype(pDataType->getName());

		typeName = typeToType(readName);

		std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

		readName[0] = std::toupper(readName[0]);

		readName = fmt::format("stream.read{}()", readName);



		sourcefileBody_ += fmt::format("{}\tpublic List<{}> createFromStreamEx(MemoryStream stream)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tUInt32 size = stream.readUint32();\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\tList<{}> datas = new List<{}>();\n\n", tabs, typeName, typeName);

		sourcefileBody_ += fmt::format("{}\t\twhile(size > 0)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\t--size;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t\tdatas.Add({});\n", tabs, readName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\treturn datas;\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n\n", tabs);



		sourcefileBody_ += fmt::format("{}\tpublic void addToStreamEx(Bundle stream, List<{}> v)\n{}\t{{\n", tabs, typeName, tabs);

		sourcefileBody_ += fmt::format("{}\t\tstream.writeUint32((UInt32)v.Count);\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\tfor(int i=0; i<v.Count; ++i)\n", tabs);

		sourcefileBody_ += fmt::format("{}\t\t{{\n", tabs);



		std::string writeName;

		writeName = datatype2nativetype(pDataType->getName());

		std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

		writeName[0] = std::toupper(writeName[0]);

		writeName = fmt::format("stream.write{}(v[i])", writeName);



		sourcefileBody_ += fmt::format("{}\t\t\t{};\n", tabs, writeName);

		sourcefileBody_ += fmt::format("{}\t\t}};\n", tabs);

		sourcefileBody_ += fmt::format("{}\t}}\n", tabs);

	}



	sourcefileBody_ += fmt::format("{}}}\n\n", tabs);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeCustomDataType(const DataType* pDataType)

{

	uint16 typeID = datatype2id(pDataType->getName());

	if (typeID == 0 || strcmp(pDataType->getName(), "FIXED_DICT") == 0 || strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		typeID = pDataType->id();

		KBE_ASSERT(typeID > datatype2id("KBE_DATATYPE2ID_MAX"));

	}



	static std::map< int, std::string > type2name;



	std::string typeName = (strlen(pDataType->aliasName()) > 0 ? pDataType->aliasName() : fmt::format("AnonymousArray_{}", typeID));



	std::map< int, std::string >::iterator iter = type2name.find(typeID);

	if (iter == type2name.end())

		type2name[typeID] = (strlen(pDataType->getName()) > 0 ? pDataType->getName() : typeName);



	if (strcmp(pDataType->getName(), "FIXED_DICT") == 0)

	{

		sourcefileBody_ += fmt::format("\n\n\tpublic class DATATYPE_{} : DATATYPE_BASE\n\t{{\n", typeName);

		std::map<std::string, std::string> allClassName;



		FixedDictType* dictdatatype = const_cast<FixedDictType*>(static_cast<const FixedDictType*>(pDataType));



		// 先创建属性

		{

			FixedDictType::FIXEDDICT_KEYTYPE_MAP& keys = dictdatatype->getKeyTypes();

			FixedDictType::FIXEDDICT_KEYTYPE_MAP::const_iterator keyiter = keys.begin();

			for (; keyiter != keys.end(); ++keyiter)

			{

				DataType* pKeyDataType = keyiter->second->dataType;

				if (strcmp(pKeyDataType->getName(), "FIXED_DICT") == 0)

				{

					sourcefileBody_ += fmt::format("\t\tprivate DATATYPE_{} {}_DataType = new DATATYPE_{}();\n",

						pKeyDataType->aliasName(), keyiter->first, pKeyDataType->aliasName());

				}

				else if (strcmp(pKeyDataType->getName(), "ARRAY") == 0)

				{

					FixedArrayType* pFixedArrayType = const_cast<FixedArrayType*>(static_cast<const FixedArrayType*>(pKeyDataType));



					std::string className = pKeyDataType->aliasName();



					if (strlen(pFixedArrayType->aliasName()) == 0 || pFixedArrayType->aliasName()[0] == '_')

					{

						sourcefileBody_ += fmt::format("\t\tprivate DATATYPE_{} {}_DataType = new DATATYPE_{}();\n\n",

							className + "_ChildArray", keyiter->first, className + "_ChildArray");



						std::map<std::string, std::string>::iterator findChildClassNameIter = allClassName.find(className + "_ChildArray");



						if (findChildClassNameIter == allClassName.end())

						{

							allClassName[className + "_ChildArray"] = typeName;

							createArrayChildClass(pFixedArrayType, pFixedArrayType->getDataType(), className + "_ChildArray", "\t\t");

						}

					}

					else

					{

						sourcefileBody_ += fmt::format("\t\tprivate DATATYPE_{} {}_DataType = new DATATYPE_{}();\n\n",

							className, keyiter->first, className);

					}

				}

				else

				{

				}

			}

		}



		// 创建createFromStreamEx方法

		{

			sourcefileBody_ += fmt::format("\t\tpublic {} createFromStreamEx(MemoryStream stream)\n\t\t{{\n", typeName);



			sourcefileBody_ += fmt::format("\t\t\t{} datas = new {}();\n", typeName, typeName);



			FixedDictType::FIXEDDICT_KEYTYPE_MAP& keys = dictdatatype->getKeyTypes();

			FixedDictType::FIXEDDICT_KEYTYPE_MAP::const_iterator keyiter = keys.begin();

			for (; keyiter != keys.end(); ++keyiter)

			{

				DataType* pKeyDataType = keyiter->second->dataType;

				if (strcmp(pKeyDataType->getName(), "FIXED_DICT") == 0)

				{

					sourcefileBody_ += fmt::format("\t\t\tdatas.{} = {}_DataType.createFromStreamEx(stream);\n", keyiter->first, keyiter->first);

				}

				else if (strcmp(pKeyDataType->getName(), "ARRAY") == 0)

				{

					sourcefileBody_ += fmt::format("\t\t\tdatas.{} = {}_DataType.createFromStreamEx(stream);\n", keyiter->first, keyiter->first);

				}

				else

				{

					std::string readName = datatype2nativetype(pKeyDataType->getName());

					std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

					readName[0] = std::toupper(readName[0]);

					readName = fmt::format("stream.read{}()", readName);



					sourcefileBody_ += fmt::format("\t\t\tdatas.{} = {};\n", keyiter->first, readName);

				}

			}



			sourcefileBody_ += fmt::format("\t\t\treturn datas;\n");

			sourcefileBody_ += fmt::format("\t\t}}\n\n");

		}



		// 创建addToStreamEx方法

		{

			sourcefileBody_ += fmt::format("\t\tpublic void addToStreamEx(Bundle stream, {} v)\n\t\t{{\n", typeName);



			FixedDictType::FIXEDDICT_KEYTYPE_MAP& keys = dictdatatype->getKeyTypes();

			FixedDictType::FIXEDDICT_KEYTYPE_MAP::const_iterator keyiter = keys.begin();

			for (; keyiter != keys.end(); ++keyiter)

			{

				DataType* pKeyDataType = keyiter->second->dataType;

				if (strcmp(pKeyDataType->getName(), "FIXED_DICT") == 0)

				{

					sourcefileBody_ += fmt::format("\t\t\t{}_DataType.addToStreamEx(stream, v.{});\n", keyiter->first, keyiter->first);

				}

				else if (strcmp(pKeyDataType->getName(), "ARRAY") == 0)

				{

					sourcefileBody_ += fmt::format("\t\t\t{}_DataType.addToStreamEx(stream, v.{});\n", keyiter->first, keyiter->first);

				}

				else

				{

					std::string writeName = datatype2nativetype(pKeyDataType->getName());

					std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

					writeName[0] = std::toupper(writeName[0]);



					sourcefileBody_ += fmt::format("\t\t\tstream.write{}(v.{});\n", writeName, keyiter->first);

				}

			}



			sourcefileBody_ += fmt::format("\t\t}}\n");

		}



		sourcefileBody_ += fmt::format("\t}}\n\n");



	}

	else if (strcmp(pDataType->getName(), "ARRAY") == 0)

	{

		FixedArrayType* pFixedArrayType = const_cast<FixedArrayType*>(static_cast<const FixedArrayType*>(pDataType));

		typeID = datatype2id(pFixedArrayType->getDataType()->getName());



		if (typeID == 0 || strcmp(pFixedArrayType->getDataType()->getName(), "FIXED_DICT") == 0 ||

			strcmp(pFixedArrayType->getDataType()->getName(), "ARRAY") == 0)

			typeID = pFixedArrayType->getDataType()->id();



		std::string itemTypeName = typeToType(type2name[typeID]);

		if (itemTypeName == "")

		{

			itemTypeName = pFixedArrayType->getDataType()->aliasName();

		}



		std::string className = typeName;



		if (strlen(pFixedArrayType->aliasName()) == 0 || pFixedArrayType->aliasName()[0] == '_')

		{

			typeName = "";

			getArrayType(pFixedArrayType, typeName);

		}



		std::string readName;

		sourcefileBody_ += fmt::format("\n\n\tpublic class DATATYPE_{} : DATATYPE_BASE\n\t{{\n", className);



		bool isFixedType = strcmp(pFixedArrayType->getDataType()->getName(), "FIXED_DICT") == 0 ||

		strcmp(pFixedArrayType->getDataType()->getName(), "ARRAY") == 0;



		if (strcmp(pFixedArrayType->getDataType()->getName(), "FIXED_DICT") == 0)

		{

			readName = fmt::format("itemType.createFromStreamEx(stream)", readName);



			sourcefileBody_ += fmt::format("\t\tprivate DATATYPE_{} itemType = new DATATYPE_{}();\n\n",

			pFixedArrayType->getDataType()->aliasName(), pFixedArrayType->getDataType()->aliasName());



			sourcefileBody_ += fmt::format("\t\tpublic {} createFromStreamEx(MemoryStream stream)\n\t\t{{\n", typeName);

			sourcefileBody_ += fmt::format("\t\t\tUInt32 size = stream.readUint32();\n");

			sourcefileBody_ += fmt::format("\t\t\t{} datas = new {}();\n\n", typeName, typeName);

			sourcefileBody_ += fmt::format("\t\t\twhile(size > 0)\n");

			sourcefileBody_ += fmt::format("\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\t--size;\n");

			sourcefileBody_ += fmt::format("\t\t\t\tdatas.Add({});\n", readName);

			sourcefileBody_ += fmt::format("\t\t\t}};\n\n");

			sourcefileBody_ += fmt::format("\t\t\treturn datas;\n");

			sourcefileBody_ += fmt::format("\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\tpublic void addToStreamEx(Bundle stream, {} v)\n\t\t{{\n", typeName);

			sourcefileBody_ += fmt::format("\t\t\tstream.writeUint32((UInt32)v.Count);\n");

			sourcefileBody_ += fmt::format("\t\t\tfor(int i=0; i<v.Count; ++i)\n");

			sourcefileBody_ += fmt::format("\t\t\t{{\n");



			std::string writeName;

			if (isFixedType)

			{

				writeName = fmt::format("itemType.addToStreamEx(stream, v[i])", writeName);

			}

			else

			{

				writeName = datatype2nativetype(pFixedArrayType->getDataType()->getName());

				std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

				writeName[0] = std::toupper(writeName[0]);

				writeName = fmt::format("stream.write{}(v[i])", writeName);

			}



			sourcefileBody_ += fmt::format("\t\t\t\t{};\n", writeName);

			sourcefileBody_ += fmt::format("\t\t\t}};\n");

			sourcefileBody_ += fmt::format("\t\t}}\n");



			sourcefileBody_ += fmt::format("\t}}\n\n");

		}

		else if (strcmp(pFixedArrayType->getDataType()->getName(), "ARRAY") == 0)

		{

			readName = fmt::format("itemType.createFromStreamEx(stream)", readName);



			sourcefileBody_ += fmt::format("\t\tprivate DATATYPE_{} itemType = new DATATYPE_{}();\n\n",

				className + "_ChildArray", className + "_ChildArray");



			createArrayChildClass(pFixedArrayType, pFixedArrayType->getDataType(), className + "_ChildArray", "\t\t");



			sourcefileBody_ += fmt::format("\t\tpublic {} createFromStreamEx(MemoryStream stream)\n\t\t{{\n", typeName);

			sourcefileBody_ += fmt::format("\t\t\treturn {};\n", readName);

			sourcefileBody_ += fmt::format("\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\tpublic void addToStreamEx(Bundle stream, {} v)\n\t\t{{\n", typeName);

			std::string writeName = fmt::format("itemType.addToStreamEx(stream, v)", writeName);

			sourcefileBody_ += fmt::format("\t\t\t{};\n", writeName);

			sourcefileBody_ += fmt::format("\t\t}}\n");



			sourcefileBody_ += fmt::format("\t}}\n\n");

		}

		else

		{

			readName = datatype2nativetype(pFixedArrayType->getDataType()->getName());

			std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

			readName[0] = std::toupper(readName[0]);

			readName = fmt::format("stream.read{}()", readName);



			sourcefileBody_ += fmt::format("\t\tpublic {} createFromStreamEx(MemoryStream stream)\n\t\t{{\n", typeName);

			sourcefileBody_ += fmt::format("\t\t\tUInt32 size = stream.readUint32();\n");

			sourcefileBody_ += fmt::format("\t\t\t{} datas = new {}();\n\n", typeName, typeName);

			sourcefileBody_ += fmt::format("\t\t\twhile(size > 0)\n");

			sourcefileBody_ += fmt::format("\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\t--size;\n");

			sourcefileBody_ += fmt::format("\t\t\t\tdatas.Add({});\n", readName);

			sourcefileBody_ += fmt::format("\t\t\t}};\n\n");

			sourcefileBody_ += fmt::format("\t\t\treturn datas;\n");

			sourcefileBody_ += fmt::format("\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\tpublic void addToStreamEx(Bundle stream, {} v)\n\t\t{{\n", typeName);

			sourcefileBody_ += fmt::format("\t\t\tstream.writeUint32((UInt32)v.Count);\n");

			sourcefileBody_ += fmt::format("\t\t\tfor(int i=0; i<v.Count; ++i)\n");

			sourcefileBody_ += fmt::format("\t\t\t{{\n");



			std::string writeName;

			if (isFixedType)

			{

				writeName = fmt::format("itemType.addToStreamEx(stream, v[i])", writeName);

			}

			else

			{

				writeName = datatype2nativetype(pFixedArrayType->getDataType()->getName());

				std::transform(writeName.begin(), writeName.end(), writeName.begin(), tolower);

				writeName[0] = std::toupper(writeName[0]);

				writeName = fmt::format("stream.write{}(v[i])", writeName);

			}



			sourcefileBody_ += fmt::format("\t\t\t\t{};\n", writeName);

			sourcefileBody_ += fmt::format("\t\t\t}};\n");

			sourcefileBody_ += fmt::format("\t\t}}\n");



			sourcefileBody_ += fmt::format("\t}}\n\n");

		}

	}

	else

	{

	}



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitScript_ScriptModule(ScriptDefModule* pScriptDefModule)

{

	sourcefileBody_ += fmt::format("\t\t\tScriptModule p{}Module = new ScriptModule(\"{}\");\n", pScriptDefModule->getName(), pScriptDefModule->getName());

	sourcefileBody_ += fmt::format("\t\t\tEntityDef.moduledefs[\"{}\"] = p{}Module;\n", pScriptDefModule->getName(), pScriptDefModule->getName());

	sourcefileBody_ += fmt::format("\t\t\tEntityDef.idmoduledefs[{}] = p{}Module;\n\n", pScriptDefModule->getUType(), pScriptDefModule->getName());

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitScript_MethodDescr(ScriptDefModule* pScriptDefModule, MethodDescription* pDescr, COMPONENT_TYPE componentType)

{

	// 如果pDescr为None,并且是客户端方法,那么需要强制设定useMethodDescrAlias为true,否则默认为false将会出现问题

	if (!pDescr && componentType == CLIENT_TYPE)

	{

		sourcefileBody_ += fmt::format("\t\t\tp{}Module.useMethodDescrAlias = true;\n", pScriptDefModule->getName());

		return true;

	}



	assert(pDescr);



	sourcefileBody_ += fmt::format("\t\t\tList<DATATYPE_BASE> p{}_{}_args = new List<DATATYPE_BASE>();\n", pScriptDefModule->getName(), pDescr->getName());



	const std::vector<DataType*>& args = pDescr->getArgTypes();

	std::vector<DataType*>::const_iterator argiter = args.begin();

	for (; argiter != args.end(); ++argiter)

	{

		uint16 typeID = datatype2id((*argiter)->getName());

		if (typeID == 0 || strcmp((*argiter)->getName(), "FIXED_DICT") == 0 || strcmp((*argiter)->getName(), "ARRAY") == 0)

			typeID = (*argiter)->id();



		sourcefileBody_ += fmt::format("\t\t\tp{}_{}_args.Add(EntityDef.id2datatypes[{}]);\n", pScriptDefModule->getName(), pDescr->getName(), typeID);

	}



	sourcefileBody_ += fmt::format("\n\t\t\tMethod p{}_{} = new Method();\n", pScriptDefModule->getName(), pDescr->getName());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.name = \"{}\";\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->getName());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.methodUtype = {};\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->getUType());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.aliasID = {};\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->aliasID());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.args = p{}_{}_args;\n\n", pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());



	sourcefileBody_ += fmt::format("\t\t\tp{}Module.methods[\"{}\"] = p{}_{}; \n",

		pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());



	if (pDescr->aliasID() != -1)

	{

		if (componentType == CLIENT_TYPE)

		{

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.useMethodDescrAlias = true;\n", pScriptDefModule->getName());

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.idmethods[(UInt16)p{}_{}.aliasID] = p{}_{};\n\n",

				pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

		}

		else

		{

			KBE_ASSERT(false);

		}

	}

	else

	{

		if (componentType == CLIENT_TYPE)

		{

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.useMethodDescrAlias = false;\n", pScriptDefModule->getName());

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.idmethods[p{}_{}.methodUtype] = p{}_{};\n\n",

				pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

		} 

		if (componentType == BASEAPP_TYPE)

		{

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.base_methods[\"{}\"] = p{}_{};\n\n",

				pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());



			sourcefileBody_ += fmt::format("\t\t\tp{}Module.idbase_methods[p{}_{}.methodUtype] = p{}_{};\n\n",

				pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

		}

		else

		{

			sourcefileBody_ += fmt::format("\t\t\tp{}Module.cell_methods[\"{}\"] = p{}_{};\n\n",

				pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());



			sourcefileBody_ += fmt::format("\t\t\tp{}Module.idcell_methods[p{}_{}.methodUtype] = p{}_{};\n\n",

				pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

		}

	}



	sourcefileBody_ += fmt::format("\t\t\t//Dbg.DEBUG_MSG(\"EntityDef::initScriptModules: add({}), method({} / {}).\");\n\n",

		pScriptDefModule->getName(), pDescr->getName(), pDescr->getUType());



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityDefsModuleInitScript_PropertyDescr(ScriptDefModule* pScriptDefModule, PropertyDescription* pDescr)

{

	uint16 typeID = datatype2id(pDescr->getDataType()->getName());

	bool isFixedType = strcmp(pDescr->getDataType()->getName(), "FIXED_DICT") == 0 || strcmp(pDescr->getDataType()->getName(), "ARRAY") == 0;



	if (typeID == 0 || isFixedType)

		typeID = pDescr->getDataType()->id();



	sourcefileBody_ += fmt::format("\t\t\tProperty p{}_{} = new Property();\n", pScriptDefModule->getName(), pDescr->getName());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.name = \"{}\";\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->getName());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.properUtype = {};\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->getUType());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.properFlags = {};\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->getFlags());

	sourcefileBody_ += fmt::format("\t\t\tp{}_{}.aliasID = {};\n", pScriptDefModule->getName(), pDescr->getName(), pDescr->aliasID());



	if (isFixedType)

	{

		sourcefileBody_ += fmt::format("\t\t\tp{}_{}.defaultVal = EntityDef.id2datatypes[{}].parseDefaultValStr(\"{}\");\n",

			pScriptDefModule->getName(), pDescr->getName(), typeID, pDescr->getDefaultValStr());

	}

	else

	{

		std::string readName = typeToType(datatype2nativetype(typeID));



		if (readName == "Vector2" || readName == "Vector3" || readName == "Vector4")

		{

			sourcefileBody_ += fmt::format("\t\t\t{} {}_{}_defval = new {}();\n", readName, pScriptDefModule->getName(),

				pDescr->getName(), readName);

		}

		else if (readName == "string")

		{

			sourcefileBody_ += fmt::format("\t\t\t{} {}_{}_defval = \"\";\n", readName, pScriptDefModule->getName(),

				pDescr->getName());

		}

		else if (readName == "PYTHON" || readName == "PY_DICT" || readName == "PY_TUPLE" || readName == "PY_LIST" || readName == "byte[]")

		{

			sourcefileBody_ += fmt::format("\t\t\tbyte[] {}_{}_defval = new byte[0];\n", pScriptDefModule->getName(),

				pDescr->getName());

		}

		else if (pDescr->getDataType()->type() == DATA_TYPE_ENTITY_COMPONENT)

		{

		}

		else

		{

			sourcefileBody_ += fmt::format("\t\t\t{} {}_{}_defval;\n\t\t\t{}.TryParse(\"{}\", out {}_{}_defval);\n", readName, pScriptDefModule->getName(),

				pDescr->getName(), readName, pDescr->getDefaultValStr(), pScriptDefModule->getName(), pDescr->getName());

		}



		if (pDescr->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

			sourcefileBody_ += fmt::format("\t\t\tp{}_{}.defaultVal = {}_{}_defval;\n", pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

	}



	sourcefileBody_ += fmt::format("\t\t\tp{}Module.propertys[\"{}\"] = p{}_{}; \n\n", 

		pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());



	if (pDescr->aliasID() != -1)

	{

		sourcefileBody_ += fmt::format("\t\t\tp{}Module.usePropertyDescrAlias = true;\n", pScriptDefModule->getName());

		sourcefileBody_ += fmt::format("\t\t\tp{}Module.idpropertys[(UInt16)p{}_{}.aliasID] = p{}_{};\n\n",

			pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\t\tp{}Module.usePropertyDescrAlias = false;\n", pScriptDefModule->getName());

		sourcefileBody_ += fmt::format("\t\t\tp{}Module.idpropertys[p{}_{}.properUtype] = p{}_{};\n\n",

			pScriptDefModule->getName(), pScriptDefModule->getName(), pDescr->getName(), pScriptDefModule->getName(), pDescr->getName());

	}



	sourcefileBody_ += fmt::format("\t\t\t//Dbg.DEBUG_MSG(\"EntityDef::initScriptModules: add({}), property({} / {}).\");\n\n",

		pScriptDefModule->getName(), pDescr->getName(), pDescr->getUType());



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypesBegin()

{

	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", "");



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += "\n\n\t// defined in */scripts/entity_defs/types.xml\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypesEnd()

{

	sourcefileBody_ += "\n}";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeBegin(std::string typeName, FixedDictType* pDataType)

{

	sourcefileBody_ += fmt::format("\tpublic class {}\n\t{{\n", typeName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeEnd(std::string typeName, FixedDictType* pDataType)

{

	sourcefileBody_ += "\n\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeBegin(std::string typeName, FixedArrayType* pDataType, const std::string& parentClass)

{

	sourcefileBody_ += fmt::format("\tpublic class {}{}\n\t{{\n", typeName, (parentClass.size() > 0 ? std::string(" : ") + parentClass : ""));

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeEnd(std::string typeName, FixedArrayType* pDataType)

{

	sourcefileBody_ += "\n\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeBegin(std::string typeName, DataType* pDataType)

{

	sourcefileBody_ += fmt::format("\tpublic struct {}\n\t{{\n", typeName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeEnd(std::string typeName, DataType* pDataType)

{

	sourcefileBody_ += "\t}\n\n";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_AliasName(const std::string& itemName, const std::string& childItemName)

{

	if (childItemName == "UINT8" || childItemName == "UINT16" || childItemName == "UINT32" || childItemName == "UINT64" || 

		childItemName == "INT8" || childItemName == "INT16" || childItemName == "INT32" || childItemName == "INT64" || 

		childItemName == "FLOAT" || childItemName == "DOUBLE")

	{

		std::string ntype = typeToType(childItemName);

		sourcefileBody_ += fmt::format("\t\t{} value;\n\n", ntype);

		sourcefileBody_ += fmt::format("\t\t{}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\tthis.value = value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\treturn value.value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\t{} tvalue = ({})value;\n\t\t\treturn new {}(tvalue);\n\t\t}}\n\n", ntype, ntype, itemName);



		sourcefileBody_ += fmt::format("\t\tpublic static {} MaxValue\n\t\t{{\n", ntype);

		sourcefileBody_ += fmt::format("\t\t\tget\n\t\t\t{{\n\t\t\t\treturn {}.MaxValue;\n\t\t\t}}\n\t\t}}\n\n", ntype);



		sourcefileBody_ += fmt::format("\t\tpublic static {} MinValue\n\t\t{{\n", ntype);

		sourcefileBody_ += fmt::format("\t\t\tget\n\t\t\t{{\n\t\t\t\treturn {}.MinValue;\n\t\t\t}}\n\t\t}}\n", ntype);

	}

	else if (childItemName == "STRING" || childItemName == "UNICODE")

	{

		std::string ntype = typeToType(childItemName);

		sourcefileBody_ += fmt::format("\t\t{} value;\n\n", ntype);

		sourcefileBody_ += fmt::format("\t\t{}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\tthis.value = value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\treturn value.value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\t{} tvalue = ({})value;\n\t\t\treturn new {}(tvalue);\n\t\t}}\n", ntype, ntype, itemName);

	}

	else if (childItemName == "PYTHON" || childItemName == "PY_DICT" || childItemName == "PY_TUPLE" || 

		childItemName == "PY_LIST" || childItemName == "ENTITYCALL" || childItemName == "BLOB")

	{

		std::string ntype = "byte[]";

		sourcefileBody_ += fmt::format("\t\t{} value;\n\n", ntype);

		sourcefileBody_ += fmt::format("\t\t{}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\tthis.value = value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\treturn value.value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}(byte[] value)\n\t\t{{\n", itemName);

		sourcefileBody_ += fmt::format("\t\t\t{} tvalue = ({})value;\n\t\t\treturn new {}(tvalue);\n\t\t}}\n\n", ntype, ntype, itemName);



		sourcefileBody_ += fmt::format("\t\tpublic Byte this[int ID]\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tget {{ return value[ID]; }}\n\t\t\tset {{ this.value[ID] = value; }}\n\t\t}}\n");

	}

	else if (childItemName == "VECTOR2" || childItemName == "VECTOR3" || childItemName == "VECTOR4")

	{

		std::string ntype = typeToType(childItemName);

		sourcefileBody_ += fmt::format("\t\t{} value;\n\n", ntype);

		sourcefileBody_ += fmt::format("\t\t{}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\tthis.value = value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\treturn value.value;\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic static implicit operator {}({} value)\n\t\t{{\n", itemName, ntype);

		sourcefileBody_ += fmt::format("\t\t\t{} tvalue = ({})value;\n\t\t\treturn new {}(tvalue);\n\t\t}}\n\n", ntype, ntype, itemName);



		sourcefileBody_ += fmt::format("\t\tpublic float x\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\tget {{ return value.x; }}\n\t\t\tset {{ this.value.x = value; }}\n\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\tpublic float y\n\t\t{{\n", ntype, itemName);

		sourcefileBody_ += fmt::format("\t\t\tget {{ return value.y; }}\n\t\t\tset {{ this.value.y = value; }}\n\t\t}}\n\n");



		if (ntype == "Vector3")

		{

			sourcefileBody_ += fmt::format("\t\tpublic float z\n\t\t{{\n", ntype, itemName);

			sourcefileBody_ += fmt::format("\t\t\tget {{ return value.z; }}\n\t\t\tset {{ this.value.z = value; }}\n\t\t}}\n\n");

		}



		if (ntype == "Vector4")

		{

			sourcefileBody_ += fmt::format("\t\tpublic float z\n\t\t{{\n", ntype, itemName);

			sourcefileBody_ += fmt::format("\t\t\tget {{ return value.z; }}\n\t\t\tset {{ this.value.z = value; }}\n\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\tpublic float w\n\t\t{{\n", ntype, itemName);

			sourcefileBody_ += fmt::format("\t\t\tget {{ return value.w; }}\n\t\t\tset {{ this.value.w = value; }}\n\t\t}}\n");

		}

	}



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_INT8(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic SByte {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_INT16(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int16 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_INT32(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int32 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_INT64(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int64 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_UINT8(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic Byte {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_UINT16(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt16 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_UINT32(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt32 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_UINT64(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt64 {} = 0;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_FLOAT(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic float {} = 0f;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_DOUBLE(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic double {} = 0d;\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_STRING(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic string {} = \"\";\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_UNICODE(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic string {} = \"\";\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_PYTHON(const std::string& itemName, const std::string& childItemName)

{

	return writeTypeItemType_BLOB(itemName, childItemName);

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_PY_DICT(const std::string& itemName, const std::string& childItemName)

{

	return writeTypeItemType_BLOB(itemName, childItemName);

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_PY_TUPLE(const std::string& itemName, const std::string& childItemName)

{

	return writeTypeItemType_BLOB(itemName, childItemName);

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_PY_LIST(const std::string& itemName, const std::string& childItemName)

{

	return writeTypeItemType_BLOB(itemName, childItemName);

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_BLOB(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic byte[] {} = new byte[0];\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_ARRAY(const std::string& itemName, const std::string& childItemName, DataType* pDataType)

{

	std::string typeStr;



	if (childItemName.size() == 0 || childItemName[0] == '_')

	{

		getArrayType(pDataType, typeStr);

	}

	else

	{

		typeStr = childItemName;

	}



	sourcefileBody_ += fmt::format("\t\tpublic {} {} = new {}();\n", typeStr, itemName, typeStr);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_FIXED_DICT(const std::string& itemName, const std::string& childItemName, DataType* pDataType)

{

	sourcefileBody_ += fmt::format("\t\tpublic {} {} = new {}();\n", childItemName, itemName, childItemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_VECTOR2(const std::string& itemName, const std::string& childItemName)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector2Int {} = new Vector2Int(0, 0);\n", itemName);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector2 {} = new Vector2(0f, 0f);\n", itemName);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_VECTOR3(const std::string& itemName, const std::string& childItemName)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector3Int {} = new Vector3Int(0, 0, 0);\n", itemName);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector3 {} = new Vector3(0f, 0f, 0f);\n", itemName);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_VECTOR4(const std::string& itemName, const std::string& childItemName)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector4Int {} = new Vector4Int(0, 0, 0, 0);\n", itemName);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector4 {} = new Vector4(0f, 0f, 0f, 0f);\n", itemName);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeTypeItemType_ENTITYCALL(const std::string& itemName, const std::string& childItemName)

{

	sourcefileBody_ += fmt::format("\t\tpublic byte[] {} = new byte[0];\n", itemName);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityModuleBegin(ScriptDefModule* pEntityScriptDefModule)

{

	std::string newModuleName = fmt::format("{}{}", pEntityScriptDefModule->getName(), moduleSuffix);



	sourcefileBody_ = headerBody;

	strutil::kbe_replace(sourcefileBody_, "#REPLACE#", fmt::format("\tPlease inherit this module, such as: (class {} : {}{})\n",

		pEntityScriptDefModule->getName(), pEntityScriptDefModule->getName(), moduleSuffix));



	sourcefileBody_ += "namespace KBEngine\n{\n";

	sourcefileBody_ += "\tusing UnityEngine;\n";

	sourcefileBody_ += "\tusing System;\n";

	sourcefileBody_ += "\tusing System.Collections;\n";

	sourcefileBody_ += "\tusing System.Collections.Generic;\n\n";



	sourcefileBody_ += std::string("\t// defined in ") + pEntityScriptDefModule->getDefSourceFile() + "\n";


	if (pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\tpublic abstract class {} : EntityComponent\n\t{{\n", newModuleName);



		// 写entityCall属性

		sourcefileBody_ += fmt::format("\t\tpublic EntityBaseEntityCall_{} baseEntityCall = null;\n", newModuleName);

		sourcefileBody_ += fmt::format("\t\tpublic EntityCellEntityCall_{} cellEntityCall = null;\n\n", newModuleName);

	}

	else

	{

		sourcefileBody_ += fmt::format("\t// Please inherit and implement \"class {} : {}\"\n", pEntityScriptDefModule->getName(), newModuleName);

		sourcefileBody_ += fmt::format("\tpublic abstract class {} : Entity\n\t{{\n", newModuleName);



		// 写entityCall属性

		sourcefileBody_ += fmt::format("\t\tpublic EntityBaseEntityCall_{} baseEntityCall = null;\n", newModuleName);

		sourcefileBody_ += fmt::format("\t\tpublic EntityCellEntityCall_{} cellEntityCall = null;\n\n", newModuleName);

	}



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityModuleEnd(ScriptDefModule* pEntityScriptDefModule)

{

	sourcefileBody_ += "\t}\n}";

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::getArrayType(DataType* pDataType, std::string& outstr)

{

	if (pDataType->type() == DATA_TYPE_FIXEDARRAY)

	{

		FixedArrayType* pFixedArrayType = static_cast<FixedArrayType*>(pDataType);



		// 如果元素又是数组

		if (pFixedArrayType->getDataType()->type() == DATA_TYPE_FIXEDARRAY)

		{

			if (outstr.size() > 0)

				strutil::kbe_replace(outstr, pDataType->aliasName(), fmt::format("List<{}>", pFixedArrayType->getDataType()->aliasName()));

			else

				outstr = fmt::format("List<{}>", pFixedArrayType->getDataType()->aliasName());



			return getArrayType(pFixedArrayType->getDataType(), outstr);

		}

		else if (pFixedArrayType->getDataType()->type() == DATA_TYPE_FIXEDDICT)

		{

			if (outstr.size() > 0)

				strutil::kbe_replace(outstr, pDataType->aliasName(), pFixedArrayType->getDataType()->aliasName());

			else

				outstr = pFixedArrayType->getDataType()->aliasName();

		}

		else

		{

			if (outstr.size() > 0)

				strutil::kbe_replace(outstr, pDataType->aliasName(), typeToType(pFixedArrayType->getDataType()->getName()));

			else

				outstr = typeToType(pFixedArrayType->getDataType()->getName());

		}

	}



	outstr = fmt::format("List<{}>", outstr);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProcessMessagesMethod(ScriptDefModule* pEntityScriptDefModule)

{

	std::string ownstr = "";

	if (pEntityScriptDefModule->isComponentModule())

		ownstr = "owner.";



	// entityCall

	std::string newModuleName = fmt::format("{}{}", pEntityScriptDefModule->getName(), moduleSuffix);



	if (pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\n\t\tpublic override void createFromStream(MemoryStream stream)\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tbase.createFromStream(stream);\n");

		sourcefileBody_ += fmt::format("\t\t}}\n");



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onGetBase()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\townerID = owner.id;\n");

		sourcefileBody_ += fmt::format("\t\t\tbaseEntityCall = new EntityBaseEntityCall_{}(entityComponentPropertyID, ownerID);\n", newModuleName);

		sourcefileBody_ += fmt::format("\t\t}}\n");



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onGetCell()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\townerID = owner.id;\n");

		sourcefileBody_ += fmt::format("\t\t\tcellEntityCall = new EntityCellEntityCall_{}(entityComponentPropertyID, ownerID);\n", newModuleName);

		sourcefileBody_ += fmt::format("\t\t}}\n");



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onLoseCell()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tcellEntityCall = null;\n", newModuleName);

		sourcefileBody_ += fmt::format("\t\t}}\n");

	}



	if (!pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\n\t\tpublic {}()\n\t\t{{\n", newModuleName);

		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pEntityScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();



			sourcefileBody_ += fmt::format("\t\t\tforeach (System.Reflection.Assembly ass in AppDomain.CurrentDomain.GetAssemblies())\n\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\tType entityComponentScript = ass.GetType(\"KBEngine.{}\");\n", pEntityComponentType->pScriptDefModule()->getName());

			sourcefileBody_ += fmt::format("\t\t\t\tif(entityComponentScript != null)\n\t\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t{} = ({}{})Activator.CreateInstance(entityComponentScript);\n", pPropertyDescription->getName(), pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix);

			sourcefileBody_ += fmt::format("\t\t\t\t\t{}.owner = this;\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t\t{}.entityComponentPropertyID = {};\n", pPropertyDescription->getName(), pPropertyDescription->getUType());

			sourcefileBody_ += fmt::format("\t\t\t\t\t{}.name_ = \"{}\";\n", pPropertyDescription->getName(), pEntityComponentType->pScriptDefModule()->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t}}\n\t\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\t\tif({} == null)\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\tthrow new Exception(\"Please inherit and implement, such as: \\\"class {} : {}{}\\\"\");\n\n", pEntityComponentType->pScriptDefModule()->getName(), pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix);

		}



		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onComponentsEnterworld()\n\t\t{{\n");

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onEnterworld();\n", pPropertyDescription->getName());

		}



		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onComponentsLeaveworld()\n\t\t{{\n");

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onLeaveworld();\n", pPropertyDescription->getName());

		}



		sourcefileBody_ += "\t\t}\n";



		std::vector<PropertyDescription*> components;

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() == DATA_TYPE_ENTITY_COMPONENT)

				components.push_back(pPropertyDescription);

		}



		if (!components.empty())

		{

			sourcefileBody_ += fmt::format("\n\t\tpublic override List<EntityComponent> getComponents(string componentName, bool all)\n\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\tList<EntityComponent> founds = new List<EntityComponent>();\n\n");

			std::vector<PropertyDescription*>::const_iterator iter = components.begin();

			for (; iter != components.end(); ++iter)

			{

				PropertyDescription* pPropertyDescription = *iter;

				sourcefileBody_ += fmt::format("\t\t\tif ({}.name_ == componentName)\n\t\t\t{{\n", pPropertyDescription->getName());

				sourcefileBody_ += fmt::format("\t\t\t\tfounds.Add({});\n", pPropertyDescription->getName());

				sourcefileBody_ += fmt::format("\t\t\t\tif (!all)\n");

				sourcefileBody_ += fmt::format("\t\t\t\t\treturn founds;\n\t\t\t}}\n\n");

			}



			sourcefileBody_ += "\t\t\treturn founds;\n";

			sourcefileBody_ += "\t\t}\n";

		}

			

		sourcefileBody_ += fmt::format("\n\t\tpublic override void onGetBase()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tbaseEntityCall = new EntityBaseEntityCall_{}(id, className);\n", newModuleName);

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onGetBase();\n", pPropertyDescription->getName());

		}

		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onGetCell()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tcellEntityCall = new EntityCellEntityCall_{}(id, className);\n", newModuleName);

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onGetCell();\n", pPropertyDescription->getName());

		}

		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override void onLoseCell()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\tcellEntityCall = null;\n");

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onLoseCell();\n", pPropertyDescription->getName());

		}

		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override EntityCall getBaseEntityCall()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\treturn baseEntityCall;\n");

		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override EntityCall getCellEntityCall()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\treturn cellEntityCall;\n");

		sourcefileBody_ += "\t\t}\n";

	}



	// attach/detach组件

	if (!pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\n\t\tpublic override void attachComponents()\n\t\t{{\n");

		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pEntityScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onAttached(this);\n", pPropertyDescription->getName());

		}



		sourcefileBody_ += "\t\t}\n";



		sourcefileBody_ += fmt::format("\n\t\tpublic override void detachComponents()\n\t\t{{\n");

		propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t{}.onDetached(this);\n", pPropertyDescription->getName());

		}



		sourcefileBody_ += "\t\t}\n";

	}



	if (pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\n\t\tpublic override ScriptModule getScriptModule()\n\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\treturn EntityDef.moduledefs[\"{}\"];\n", pEntityScriptDefModule->getName());

		sourcefileBody_ += "\t\t}\n";

	}



	// 处理方法

	if (!pEntityScriptDefModule->isComponentModule())

		sourcefileBody_ += fmt::format("\n\t\tpublic override void onRemoteMethodCall(MemoryStream stream)\n\t\t{{\n");

	else

		sourcefileBody_ += fmt::format("\n\t\tpublic override void onRemoteMethodCall(UInt16 methodUtype, MemoryStream stream)\n\t\t{{\n");



	sourcefileBody_ += fmt::format("\t\t\tScriptModule sm = EntityDef.moduledefs[\"{}\"];\n\n", pEntityScriptDefModule->getName());

	

	if (!pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\t\t\tUInt16 methodUtype = 0;\n");

		sourcefileBody_ += fmt::format("\t\t\tUInt16 componentPropertyUType = 0;\n\n");



		sourcefileBody_ += fmt::format("\t\t\tif(sm.usePropertyDescrAlias)\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tcomponentPropertyUType = stream.readUint8();\n");

		sourcefileBody_ += fmt::format("\t\t\t}}\n");

		sourcefileBody_ += fmt::format("\t\t\telse\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tcomponentPropertyUType = stream.readUint16();\n");

		sourcefileBody_ += fmt::format("\t\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\t\tif(sm.useMethodDescrAlias)\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tmethodUtype = stream.readUint8();\n");



		bool foundComponentNoUseMethodDescrAlias = false;



		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pEntityScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();

			if (!pEntityComponentType->pScriptDefModule()->useMethodDescrAlias())

			{

				foundComponentNoUseMethodDescrAlias = true;

				break;

			}

		}



		if (foundComponentNoUseMethodDescrAlias)

		{

			sourcefileBody_ += fmt::format("\n\t\t\t\tif(componentPropertyUType > 0)\n");

			sourcefileBody_ += fmt::format("\t\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\tbool useComponentMethodDescrAlias = true;\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\tProperty pComponentPropertyDescription = sm.idpropertys[componentPropertyUType];\n\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\tswitch(pComponentPropertyDescription.properUtype)\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t{{\n");



			for (propIter = clientPropertys.begin(); propIter != clientPropertys.end(); ++propIter)

			{

				PropertyDescription* pPropertyDescription = propIter->second;



				if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

					continue;



				EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();

				if (!pEntityComponentType->pScriptDefModule()->useMethodDescrAlias())

				{

					sourcefileBody_ += fmt::format("\t\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

					sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tuseComponentMethodDescrAlias = false;\n", pPropertyDescription->getName());

					sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tbreak;\n");

				}

			}



			sourcefileBody_ += fmt::format("\t\t\t\t\t\tdefault:\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tbreak;\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t}}\n\n");



			sourcefileBody_ += fmt::format("\t\t\t\t\tif(!useComponentMethodDescrAlias)\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t\tstream.rpos -= 1;\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t\tmethodUtype = stream.readUint16();\n");

			sourcefileBody_ += fmt::format("\t\t\t\t\t}}\n");



			sourcefileBody_ += fmt::format("\t\t\t\t}}\n");

		}



		sourcefileBody_ += fmt::format("\t\t\t}}\n");

		sourcefileBody_ += fmt::format("\t\t\telse\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tmethodUtype = stream.readUint16();\n");

		sourcefileBody_ += fmt::format("\t\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\t\tMethod method = null;\n\n");



		sourcefileBody_ += fmt::format("\t\t\tif(componentPropertyUType == 0)\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tmethod = sm.idmethods[methodUtype];\n");

		sourcefileBody_ += fmt::format("\t\t\t}}\n");

		sourcefileBody_ += fmt::format("\t\t\telse\n");

		sourcefileBody_ += fmt::format("\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\tProperty pComponentPropertyDescription = sm.idpropertys[componentPropertyUType];\n");



		sourcefileBody_ += fmt::format("\t\t\t\tswitch(pComponentPropertyDescription.properUtype)\n\t\t\t\t{{\n");



		for (propIter = clientPropertys.begin(); propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;



			sourcefileBody_ += fmt::format("\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\t{}.onRemoteMethodCall(methodUtype, stream);\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

		}



		sourcefileBody_ += fmt::format("\t\t\t\t\tdefault:\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

		sourcefileBody_ += fmt::format("\t\t\t\t}}\n\n");

		sourcefileBody_ += fmt::format("\t\t\t\treturn;\n");

		sourcefileBody_ += fmt::format("\t\t\t}}\n\n");



		sourcefileBody_ += fmt::format("\t\t\tswitch(method.methodUtype)\n\t\t\t{{\n");

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\t\tMethod method = sm.idmethods[methodUtype];\n");

		sourcefileBody_ += fmt::format("\t\t\tswitch(method.methodUtype)\n\t\t\t{{\n");

	}



	ScriptDefModule::METHODDESCRIPTION_MAP& clientMethods = pEntityScriptDefModule->getClientMethodDescriptions();

	ScriptDefModule::METHODDESCRIPTION_MAP::iterator methodIter = clientMethods.begin();

	for (; methodIter != clientMethods.end(); ++methodIter)

	{

		MethodDescription* pMethodDescription = methodIter->second;



		sourcefileBody_ += fmt::format("\t\t\t\tcase {}:\n", pMethodDescription->getUType());

		

		std::vector<DataType*>& argTypes = pMethodDescription->getArgTypes();

		std::vector<DataType*>::iterator iter = argTypes.begin();



		int i = 1;

		std::string argsStr;



		for (; iter != argTypes.end(); ++iter)

		{

			DataType* pDataType = (*iter);



			uint16 typeID = datatype2id(pDataType->getName());

			if (typeID == 0 || strcmp(pDataType->getName(), "FIXED_DICT") == 0 || strcmp(pDataType->getName(), "ARRAY") == 0)

				typeID = pDataType->id();



			argsStr += fmt::format("{}_arg{}, ", pMethodDescription->getName(), i);



			std::string readName = datatype2nativetype(pDataType->getName());

			if (readName.size() > 0)

			{

				std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

				readName[0] = std::toupper(readName[0]);

			}



			std::string nativetype = datatype2nativetype(typeID);

			if (strcmp(pDataType->getName(), "FIXED_DICT") == 0)

			{

				sourcefileBody_ += fmt::format("\t\t\t\t\t{} {}_arg{} = ((DATATYPE_{})method.args[{}]).createFromStreamEx(stream);\n",

					pDataType->aliasName(), pMethodDescription->getName(), i, pDataType->aliasName(), (i - 1));

			}

			else if(strcmp(pDataType->getName(), "ARRAY") == 0)

			{

				std::string typestr;

				getArrayType(pDataType, typestr);



				if (strlen(pDataType->aliasName()) > 0)

				{

					sourcefileBody_ += fmt::format("\t\t\t\t\t{} {}_arg{} = ((DATATYPE_{})method.args[{}]).createFromStreamEx(stream);\n",

						pDataType->aliasName(), pMethodDescription->getName(), i, pDataType->aliasName(), (i - 1));

				}

				else

				{

					sourcefileBody_ += fmt::format("\t\t\t\t\t{} {}_arg{} = ((DATATYPE_AnonymousArray_{})method.args[{}]).createFromStreamEx(stream);\n",

						typestr, pMethodDescription->getName(), i, typeID, (i - 1));

				}

			}

			else

			{

				sourcefileBody_ += fmt::format("\t\t\t\t\t{} {}_arg{} = stream.read{}();\n",

					typeToType(nativetype), pMethodDescription->getName(), i, readName);

			}



			++i;

		}



		if (argsStr.size() > 0)

			argsStr.erase(argsStr.size() - 2, 2);



		sourcefileBody_ += fmt::format("\t\t\t\t\t{}({});\n", pMethodDescription->getName(), argsStr);

		sourcefileBody_ += fmt::format("\t\t\t\t\tbreak;\n");

	}



	sourcefileBody_ += fmt::format("\t\t\t\tdefault:\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\tbreak;\n");

	sourcefileBody_ += fmt::format("\t\t\t}};\n");

	sourcefileBody_ += "\t\t}\n";



	// 处理属性

	ENTITY_PROPERTY_UID posuid = 0;

	if (posuid == 0)

	{

		posuid = ENTITY_BASE_PROPERTY_UTYPE_POSITION_XYZ;

		Network::FixedMessages::MSGInfo* msgInfo =

			Network::FixedMessages::getSingleton().isFixed("Property::position");



		if (msgInfo != NULL)

			posuid = msgInfo->msgid;

	}



	PropertyDescription positionDescription(posuid, "VECTOR3", "position", ED_FLAG_ALL_CLIENTS, true, DataTypes::getDataType("VECTOR3"), false, "", 0, "", DETAIL_LEVEL_FAR);

	if (pEntityScriptDefModule->usePropertyDescrAlias() && positionDescription.aliasID() == -1)

		positionDescription.aliasID(ENTITY_BASE_PROPERTY_ALIASID_POSITION_XYZ);



	ENTITY_PROPERTY_UID diruid = 0;

	if (diruid == 0)

	{

		diruid = ENTITY_BASE_PROPERTY_UTYPE_DIRECTION_ROLL_PITCH_YAW;

		Network::FixedMessages::MSGInfo* msgInfo = Network::FixedMessages::getSingleton().isFixed("Property::direction");

		if (msgInfo != NULL)

			diruid = msgInfo->msgid;

	}



	PropertyDescription directionDescription(diruid, "VECTOR3", "direction", ED_FLAG_ALL_CLIENTS, true, DataTypes::getDataType("VECTOR3"), false, "", 0, "", DETAIL_LEVEL_FAR);

	if (pEntityScriptDefModule->usePropertyDescrAlias() && directionDescription.aliasID() == -1)

		directionDescription.aliasID(ENTITY_BASE_PROPERTY_ALIASID_DIRECTION_ROLL_PITCH_YAW);



	ENTITY_PROPERTY_UID spaceuid = 0;

	if (spaceuid == 0)

	{

		spaceuid = ENTITY_BASE_PROPERTY_UTYPE_SPACEID;

		Network::FixedMessages::MSGInfo* msgInfo = Network::FixedMessages::getSingleton().isFixed("Property::spaceID");

		if (msgInfo != NULL)

			spaceuid = msgInfo->msgid;

	}



	PropertyDescription spaceDescription(spaceuid, "UINT32", "spaceID", ED_FLAG_OWN_CLIENT, true, DataTypes::getDataType("UINT32"), false, "", 0, "", DETAIL_LEVEL_FAR);

	if (pEntityScriptDefModule->usePropertyDescrAlias() && spaceDescription.aliasID() == -1)

		spaceDescription.aliasID(ENTITY_BASE_PROPERTY_ALIASID_SPACEID);



	if(pEntityScriptDefModule->isComponentModule())

		sourcefileBody_ += fmt::format("\n\t\tpublic override void onUpdatePropertys(UInt16 propUtype, MemoryStream stream, int maxCount)\n\t\t{{\n");

	else

		sourcefileBody_ += fmt::format("\n\t\tpublic override void onUpdatePropertys(MemoryStream stream)\n\t\t{{\n");



	sourcefileBody_ += fmt::format("\t\t\tScriptModule sm = EntityDef.moduledefs[\"{}\"];\n", pEntityScriptDefModule->getName());

	sourcefileBody_ += fmt::format("\t\t\tDictionary<UInt16, Property> pdatas = sm.idpropertys;\n\n");



	if (pEntityScriptDefModule->isComponentModule())

		sourcefileBody_ += fmt::format("\t\t\twhile(stream.length() > 0 && maxCount-- != 0)\n");

	else

		sourcefileBody_ += fmt::format("\t\t\twhile(stream.length() > 0)\n");



	sourcefileBody_ += fmt::format("\t\t\t{{\n");



	sourcefileBody_ += fmt::format("\t\t\t\tUInt16 _t_utype = 0;\n");



	if (pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\t\t\t\tUInt16 _t_child_utype = propUtype;\n\n");

		sourcefileBody_ += fmt::format("\t\t\t\tif(_t_child_utype == 0)\n");

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\t\t\tUInt16 _t_child_utype = 0;\n\n");

	}



	sourcefileBody_ += fmt::format("\t\t\t\t{{\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\tif(sm.usePropertyDescrAlias)\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t{{\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t\t_t_utype = stream.readUint8();\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t\t_t_child_utype = stream.readUint8();\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t}}\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\telse\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t{{\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t\t_t_utype = stream.readUint16();\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t\t_t_child_utype = stream.readUint16();\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t}}\n");

	sourcefileBody_ += fmt::format("\t\t\t\t}}\n\n");



	sourcefileBody_ += fmt::format("\t\t\t\tProperty prop = null;\n\n");



	if (pEntityScriptDefModule->isComponentModule())

	{

		sourcefileBody_ += fmt::format("\t\t\t\tprop = pdatas[_t_child_utype];\n\n");

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\t\t\tif(_t_utype == 0)\n");

		sourcefileBody_ += fmt::format("\t\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\tprop = pdatas[_t_child_utype];\n");

		sourcefileBody_ += fmt::format("\t\t\t\t}}\n");

		sourcefileBody_ += fmt::format("\t\t\t\telse\n");

		sourcefileBody_ += fmt::format("\t\t\t\t{{\n");



		sourcefileBody_ += fmt::format("\t\t\t\t\tProperty pComponentPropertyDescription = pdatas[_t_utype];\n");



		sourcefileBody_ += fmt::format("\t\t\t\t\tswitch(pComponentPropertyDescription.properUtype)\n\t\t\t\t\t{{\n");



		ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pEntityScriptDefModule->getClientPropertyDescriptions();

		ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

		for (; propIter != clientPropertys.end(); ++propIter)

		{

			PropertyDescription* pPropertyDescription = propIter->second;



			if (pPropertyDescription->getDataType()->type() != DATA_TYPE_ENTITY_COMPONENT)

				continue;





			sourcefileBody_ += fmt::format("\t\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\t\t{}.onUpdatePropertys(_t_child_utype, stream, -1);\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tbreak;\n");

		}



		sourcefileBody_ += fmt::format("\t\t\t\t\t\tdefault:\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tbreak;\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t}}\n\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\treturn;\n");

		sourcefileBody_ += fmt::format("\t\t\t\t}}\n\n");

	}



	sourcefileBody_ += fmt::format("\t\t\t\tswitch(prop.properUtype)\n\t\t\t\t{{\n");



	ScriptDefModule::PROPERTYDESCRIPTION_MAP clientPropertys = pEntityScriptDefModule->getClientPropertyDescriptions();



	if (!pEntityScriptDefModule->isComponentModule())

	{

		clientPropertys[positionDescription.getName()] = &positionDescription;

		clientPropertys[directionDescription.getName()] = &directionDescription;

		clientPropertys[spaceDescription.getName()] = &spaceDescription;

	}



	ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator propIter = clientPropertys.begin();

	for (; propIter != clientPropertys.end(); ++propIter)

	{

		PropertyDescription* pPropertyDescription = propIter->second;



		if (pPropertyDescription->getDataType()->type() == DATA_TYPE_ENTITY_COMPONENT)

		{

			sourcefileBody_ += fmt::format("\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\t{}.createFromStream(stream);\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

			continue;

		}



		std::string typestr;



		if (std::string("position") == pPropertyDescription->getName() ||

			std::string("direction") == pPropertyDescription->getName())

		{

#ifdef CLIENT_NO_FLOAT

			typestr = "Vector3Int";

#else

			typestr = "Vector3";

#endif

		}

		else

		{

			if (std::string("spaceID") == pPropertyDescription->getName())

			{

				sourcefileBody_ += fmt::format("\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

				sourcefileBody_ += fmt::format("\t\t\t\t\t\tstream.readUint32();\n");

				sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

				continue;

			}

			else

			{

				std::string findstr = fmt::format(" {} = ", pPropertyDescription->getName());

				std::string::size_type fpos2 = sourcefileBody_.find(findstr);

				std::string::size_type fpos1 = sourcefileBody_.rfind(" ", fpos2 - 1);

				typestr.assign(sourcefileBody_.begin() + fpos1 + 1, sourcefileBody_.begin() + fpos2);

			}

		}



		sourcefileBody_ += fmt::format("\t\t\t\t\tcase {}:\n", pPropertyDescription->getUType());

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t{} oldval_{} = {};\n", typestr, pPropertyDescription->getName(), pPropertyDescription->getName());



		std::string readName = datatype2nativetype(pPropertyDescription->getDataType()->getName());

		if (readName.size() > 0)

		{

			std::transform(readName.begin(), readName.end(), readName.begin(), tolower);

			readName[0] = std::toupper(readName[0]);

		}

		else

		{

			KBE_ASSERT(false);

		}



		if (pPropertyDescription->getDataType()->type() == DATA_TYPE_FIXEDDICT)

		{

			readName = fmt::format("((DATATYPE_{})EntityDef.id2datatypes[{}]).createFromStreamEx(stream)", 

				pPropertyDescription->getDataType()->aliasName(), pPropertyDescription->getDataType()->id());

		}

		else if (pPropertyDescription->getDataType()->type() == DATA_TYPE_FIXEDARRAY)

		{

			if (strlen(pPropertyDescription->getDataType()->aliasName()) > 0)

			{

				readName = fmt::format("((DATATYPE_{})EntityDef.id2datatypes[{}]).createFromStreamEx(stream)", 

					pPropertyDescription->getDataType()->aliasName(), pPropertyDescription->getDataType()->id());

			}

			else

			{

				readName = fmt::format("((DATATYPE_AnonymousArray_{})EntityDef.id2datatypes[{}]).createFromStreamEx(stream)", 

					pPropertyDescription->getDataType()->id(), pPropertyDescription->getDataType()->id());

			}

		}

		else

		{

			readName = fmt::format("stream.read{}()", readName);

		}



		sourcefileBody_ += fmt::format("\t\t\t\t\t\t{} = {};\n", pPropertyDescription->getName(), readName);



		std::string name = pPropertyDescription->getName();

		name[0] = std::toupper(name[0]);

		sourcefileBody_ += fmt::format("\n\t\t\t\t\t\tif(prop.isBase())\n\t\t\t\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tif({}inited)\n", ownstr);

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t\t\ton{}Changed(oldval_{});\n\t\t\t\t\t\t}}\n", name, pPropertyDescription->getName());

		sourcefileBody_ += fmt::format("\t\t\t\t\t\telse\n\t\t\t\t\t\t{{\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t\tif({}inWorld)\n", ownstr);

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t\t\ton{}Changed(oldval_{});\n", name, pPropertyDescription->getName());

		sourcefileBody_ += fmt::format("\t\t\t\t\t\t}}\n\n");

		sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

	}



	sourcefileBody_ += fmt::format("\t\t\t\t\tdefault:\n");

	sourcefileBody_ += fmt::format("\t\t\t\t\t\tbreak;\n");

	sourcefileBody_ += fmt::format("\t\t\t\t}};\n");



	sourcefileBody_ += fmt::format("\t\t\t}}\n");

	sourcefileBody_ += "\t\t}\n";



	// 处理属性callPropertysSetMethods

	sourcefileBody_ += fmt::format("\n\t\tpublic override void callPropertysSetMethods()\n\t\t{{\n");

	sourcefileBody_ += fmt::format("\t\t\tScriptModule sm = EntityDef.moduledefs[\"{}\"];\n", pEntityScriptDefModule->getName());

	sourcefileBody_ += fmt::format("\t\t\tDictionary<UInt16, Property> pdatas = sm.idpropertys;\n\n");



	propIter = clientPropertys.begin();

	for (; propIter != clientPropertys.end(); ++propIter)

	{

		PropertyDescription* pPropertyDescription = propIter->second;



		std::string typestr;



		if (std::string("spaceID") == pPropertyDescription->getName())

			continue;



		if (std::string("position") == pPropertyDescription->getName() ||

			std::string("direction") == pPropertyDescription->getName())

		{

#ifdef CLIENT_NO_FLOAT

			typestr = "Vector3Int";

#else

			typestr = "Vector3";

#endif

		}

		else

		{

			std::string findstr = fmt::format(" {} = ", pPropertyDescription->getName());

			std::string::size_type fpos2 = sourcefileBody_.find(findstr);

			std::string::size_type fpos1 = sourcefileBody_.rfind(" ", fpos2 - 1);

			typestr.assign(sourcefileBody_.begin() + fpos1 + 1, sourcefileBody_.begin() + fpos2);

		}



		if (pPropertyDescription->getDataType()->type() == DATA_TYPE_ENTITY_COMPONENT)

		{

			sourcefileBody_ += fmt::format("\t\t\t{}.callPropertysSetMethods();\n\n", pPropertyDescription->getName());

		}

		else

		{

			sourcefileBody_ += fmt::format("\t\t\t{} oldval_{} = {};\n", typestr, pPropertyDescription->getName(), pPropertyDescription->getName());



			std::string name = pPropertyDescription->getName();

			name[0] = std::toupper(name[0]);



			sourcefileBody_ += fmt::format("\t\t\tProperty prop_{} = pdatas[{}];\n", pPropertyDescription->getName(), (pEntityScriptDefModule->usePropertyDescrAlias() ?

				pPropertyDescription->aliasID() : pPropertyDescription->getUType()));



			sourcefileBody_ += fmt::format("\t\t\tif(prop_{}.isBase())\n\t\t\t{{\n", pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\tif({}inited && !{}inWorld)\n", ownstr, ownstr);

			sourcefileBody_ += fmt::format("\t\t\t\t\ton{}Changed(oldval_{});\n", name, pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t}}\n\t\t\telse\n\t\t\t{{\n");

			sourcefileBody_ += fmt::format("\t\t\t\tif({}inWorld)\n\t\t\t\t{{\n", ownstr);

			sourcefileBody_ += fmt::format("\t\t\t\t\tif(prop_{}.isOwnerOnly() && !{}isPlayer())\n\t\t\t\t\t{{\n\t\t\t\t\t}}\n\t\t\t\t\telse\n\t\t\t\t\t{{\n", pPropertyDescription->getName(), ownstr);

			sourcefileBody_ += fmt::format("\t\t\t\t\t\ton{}Changed(oldval_{});\n\t\t\t\t\t}}\n", name, pPropertyDescription->getName());

			sourcefileBody_ += fmt::format("\t\t\t\t}}\n\t\t\t}}\n\n");

		}

	}



	sourcefileBody_ += "\t\t}\n";



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityPropertyComponent(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	EntityComponentType * pEntityComponentType = (EntityComponentType*)pPropertyDescription->getDataType();

	

	sourcefileBody_ += fmt::format("\t\tpublic {}{} {} = null;\n", pEntityComponentType->pScriptDefModule()->getName(), moduleSuffix, pPropertyDescription->getName(),

		pEntityComponentType->pScriptDefModule()->getName());



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_INT8(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic SByte {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(SByte oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_INT16(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int16 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Int16 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_INT32(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int32 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Int32 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_INT64(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic Int64 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Int64 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_UINT8(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic Byte {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Byte oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_UINT16(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt16 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(UInt16 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_UINT32(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt32 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(UInt32 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_UINT64(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic UInt64 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(UInt64 oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_FLOAT(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic float {} = {}f;\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(float oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_DOUBLE(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic double {} = {}d;\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "0"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(double oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_STRING(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic string {} = \"{}\";\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : ""));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(string oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_UNICODE(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic string {} = \"{}\";\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : ""));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(string oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_PYTHON(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	ERROR_MSG("ClientSDKUnity::writeEntityProperty_PYTHON(): nonsupport!\n");

	return false;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_PY_DICT(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	ERROR_MSG("ClientSDKUnity::writeEntityProperty_PY_DICT(): nonsupport!\n");

	return false;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_PY_TUPLE(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	ERROR_MSG("ClientSDKUnity::writeEntityProperty_PY_TUPLE(): nonsupport!\n");

	return false;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_PY_LIST(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	ERROR_MSG("ClientSDKUnity::writeEntityProperty_PY_LIST(): nonsupport!\n");

	return false;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_BLOB(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic byte[] {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new byte[0]"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(byte[] oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_ARRAY(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	if (std::string("ARRAY") == pPropertyDescription->getDataTypeName())

	{

		std::string s = sourcefileBody_;

		sourcefileBody_ = "";



		bool ret = writeTypeItemType_ARRAY(pPropertyDescription->getName(), pPropertyDescription->getDataType()->aliasName(), pPropertyDescription->getDataType());

		std::vector<std::string> values;

		KBEngine::strutil::kbe_splits(sourcefileBody_, " ", values);

		sourcefileBody_ = s + sourcefileBody_;



		std::string name = pPropertyDescription->getName();

		name[0] = std::toupper(name[0]);

		sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed({} oldValue) {{}}\n", name, values[1]);

		return ret;

	}

	else

	{

		sourcefileBody_ += fmt::format("\t\tpublic {} {} = new {}();\n", pPropertyDescription->getDataTypeName(), pPropertyDescription->getName(),

			pPropertyDescription->getDataTypeName());



		std::string name = pPropertyDescription->getName();

		name[0] = std::toupper(name[0]);

		sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed({} oldValue) {{}}\n", name, pPropertyDescription->getDataTypeName());

	}



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_FIXED_DICT(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic {} {} = new {}();\n", pPropertyDescription->getDataTypeName(), pPropertyDescription->getName(),

		pPropertyDescription->getDataTypeName());



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed({} oldValue) {{}}\n", name, pPropertyDescription->getDataTypeName());

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_VECTOR2(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector2Int {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector2Int(0, 0)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector2Int oldValue) {{}}\n", name);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector2 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector2(0f, 0f)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector2 oldValue) {{}}\n", name);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_VECTOR3(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector3Int {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector3Int(0, 0, 0)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector3Int oldValue) {{}}\n", name);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector3 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector3(0f, 0f, 0f)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector3 oldValue) {{}}\n", name);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_VECTOR4(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

#ifdef CLIENT_NO_FLOAT

	sourcefileBody_ += fmt::format("\t\tpublic Vector4Int {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector4Int(0, 0, 0, 0)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector4Int oldValue) {{}}\n", name);

#else

	sourcefileBody_ += fmt::format("\t\tpublic Vector4 {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new Vector4(0f, 0f, 0f, 0f)"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(Vector4 oldValue) {{}}\n", name);

#endif



	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityProperty_ENTITYCALL(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, PropertyDescription* pPropertyDescription)

{

	sourcefileBody_ += fmt::format("\t\tpublic byte[] {} = {};\n", pPropertyDescription->getName(),

		(strlen(pPropertyDescription->getDefaultValStr()) > 0 ? pPropertyDescription->getDefaultValStr() : "new byte[0]"));



	std::string name = pPropertyDescription->getName();

	name[0] = std::toupper(name[0]);

	sourcefileBody_ += fmt::format("\t\tpublic virtual void on{}Changed(byte[] oldValue) {{}}\n", name);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityMethod(ScriptDefModule* pEntityScriptDefModule,

	ScriptDefModule* pCurrScriptDefModule, MethodDescription* pMethodDescription, const char* fillString)

{

	sourcefileBody_ += fmt::format("\t\tpublic abstract void {}({}); \n", pMethodDescription->getName(), fillString);

	return true;

}



//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityMethodArgs_ARRAY(FixedArrayType* pFixedArrayType, std::string& stackArgsTypeBody, const std::string& childItemName)

{

	// 对于匿名数组需要解析,否则直接填类型名称

	if (childItemName.size() == 0 || childItemName[0] == '_')

	{

		std::string typeStr;

		getArrayType(pFixedArrayType, typeStr);

		stackArgsTypeBody += typeStr;

	}

	else

	{

		stackArgsTypeBody += childItemName;

	}



	return true;

}

 

//-------------------------------------------------------------------------------------

bool ClientSDKUnity::writeEntityMethodArgs_Const_Ref(DataType* pDataType, std::string& stackArgsTypeBody)

{

	return true;

}





//-------------------------------------------------------------------------------------

}