void OnFocus() { if (mSettingsList == null) { mSettingsList = ConfigSettings.ReadXmlSheetGroupSettings(); mSelectedGroupId = -1; if (mSettingsList.Count > 0) { mCurGroup = mSettingsList[0]; mSelectedGroupId = 1; } InitGroupOptions(); } mInvalidFiles.Clear(); if (mCurGroup != null) { for (int i = 0, imax = mCurGroup.sheetFiles.Length; i < imax; i++) { XmlSheetGroupSettings.XmlSheetFile[] files = mCurGroup.sheetFiles[i].files; for (int j = 0, jmax = files.Length; j < jmax; j++) { XmlSheetGroupSettings.XmlSheetFile file = files[j]; if (file == null) { continue; } string xmlFile = file.filePath; if (!File.Exists(xmlFile)) { mInvalidFiles.Add(xmlFile); } } } } }
/// <summary> /// 将一个组中所有的sheet加到数据库中,运行时将读取原始数据 /// </summary> /// <param name="group">该组的所有信息</param> /// <param name="addedSheets">从组中加到数据库中的所有sheet名称</param> /// <returns>组名称,若添加失败或该组已存在,则返回null</returns> public string AddToDatabase(XmlSheetGroupSettings group, IList <string> addedSheets) { if (group == null) { return(null); } if (mGroupSheets.ContainsKey(group.group)) { return(null); } int sheetCount = group.sheetFiles.Length; string[] sheets = new string[sheetCount]; for (int i = 0; i < sheetCount; i++) { XmlSheetGroupSettings.XmlSheetData sheetData = group.sheetFiles[i]; List <string> files = new List <string>(); List <Type> types = new List <Type>(); if (mRawSheets.ContainsKey(sheetData.sheetName)) { Debug.LogError(string.Format("Sheet '{0}' is already existed !", sheetData.sheetName)); continue; } sheets[i] = sheetData.sheetName; for (int j = 0, jmax = sheetData.files.Length; j < jmax; j++) { XmlSheetGroupSettings.XmlSheetFile file = sheetData.files[j]; Type type = Type.GetType(string.Format("{0},Assembly-CSharp", file.typeName)); if (type == null) { type = Type.GetType(string.Format("{0},Assembly-CSharp-Editor", file.typeName)); if (type == null) { throw new Exception(string.Format("Type '{0}' not found !", file.typeName)); } } files.Add(file.filePath); types.Add(type); if (addedSheets != null) { addedSheets.Add(sheetData.sheetName); } } mRawSheets.Add(sheetData.sheetName, new SheetDatas(files, types)); } mGroupSheets.Add(group.group, sheets); return(group.group); }
//[MenuItem("FunPlus/Configs/Serialize All XmlSheets", false, 4)] static void SerializeAllXmls() { List <XmlSheetGroupSettings> groups = ConfigSettings.ReadXmlSheetGroupSettings(); try { List <string> gs = new List <string>(); for (int i = 0, imax = groups.Count; i < imax; i++) { XmlSheetGroupSettings group = groups[i]; XmlSheetSerializer.GenerateGroupBinaryFile(group); gs.Add(group.group); } AssetDatabase.Refresh(); EditorUtility.DisplayDialog("XmlSheet Serializer", "Xmls Serializer !\n" + string.Join("\n", gs.ToArray()), "OK"); } catch (Exception e) { Debug.LogException(e); EditorUtility.DisplayDialog("XmlSheet Serialize Failed !", "See console for more details.\n\n" + e.Message, "OK"); } }
void OnGUI() { EditorGUI.BeginDisabledGroup(EditorApplication.isCompiling); Color cachedBgColor; bool dirty = false; bool isValid = true; GUILayout.Space(12f); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("XmlSheet Group", GUILayout.Width(100f)); int selectedGroupId = EditorGUILayout.Popup(mSelectedGroupId, mGroupNames); if (selectedGroupId == 0) { string groupName = EditorUtilityFix.SaveFilePanel("Set Binary Data Path", ".", "new_xmlsheet_group", "dat"); if (!string.IsNullOrEmpty(groupName)) { if (IsGroupNameValid(groupName)) { mCurGroup = new XmlSheetGroupSettings(); mCurGroup.group = groupName; mCurGroup.comments = groupName; mSettingsList.Add(mCurGroup); mSelectedGroupId = InitGroupOptions(); dirty = true; } else { EditorUtility.DisplayDialog("Create New Xmls Group Failed", "A binary file with the same filename has already been set here!", "Got it"); } } } else if (selectedGroupId > 0) { mSelectedGroupId = selectedGroupId; mCurGroup = mSettingsList[mSelectedGroupId - 1]; } EditorGUI.BeginDisabledGroup(mSelectedGroupId <= 0); cachedBgColor = GUI.backgroundColor; GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete", GUILayout.Width(60f))) { mSelectedGroupId = DeleteGroup(mSelectedGroupId); mCurGroup = mSelectedGroupId > 0 ? mSettingsList[mSelectedGroupId - 1] : null; dirty = true; } GUI.backgroundColor = cachedBgColor; EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); if (mCurGroup != null) { GUILayout.Space(8f); EditorGUILayout.BeginHorizontal(GUILayout.Height(20f)); GUILayout.Space(4f); EditorGUILayout.LabelField("Comment", GUILayout.Width(100f)); EditorGUI.BeginChangeCheck(); mCurGroup.comments = EditorGUILayout.TextField(mCurGroup.comments); if (EditorGUI.EndChangeCheck()) { dirty = true; } GUILayout.Space(68f); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.Height(20f)); GUILayout.Space(4f); EditorGUILayout.LabelField("Binary File Path", GUILayout.Width(100f)); EditorGUILayout.LabelField(mCurGroup.group, (GUIStyle)"AS TextArea", GUILayout.Height(20f)); if (GUILayout.Button("Browse", GUILayout.Width(60f))) { string groupPath = EditorUtilityFix.SaveFilePanel("Change Binary Data Path", Path.GetDirectoryName(mCurGroup.group), Path.GetFileNameWithoutExtension(mCurGroup.group), Path.GetExtension(mCurGroup.group).Replace(".", "")); if (!string.IsNullOrEmpty(groupPath) && groupPath != mCurGroup.group) { if (IsGroupNameValid(groupPath)) { if (mCurGroup.comments == mCurGroup.group) { mCurGroup.comments = groupPath; } mCurGroup.group = groupPath; dirty = true; InitGroupOptions(); } else { EditorUtility.DisplayDialog("Change Binary File Path Failed", "A binary file with the same filename has already been set here!", "Got it"); } } } GUILayout.Space(4f); EditorGUILayout.EndHorizontal(); GUILayout.Space(2f); mScrollPos = EditorGUILayout.BeginScrollView(mScrollPos, false, false); EditorGUILayout.LabelField("Xml Sheets:"); int removeAt = -1; for (int i = 0, imax = mCurGroup.sheetFiles.Length; i < imax; i++) { XmlSheetGroupSettings.XmlSheetData xmlSheetData = mCurGroup.sheetFiles[i]; EditorGUILayout.BeginHorizontal(GUILayout.MinHeight(20f)); GUILayout.Space(12f); //start content cachedBgColor = GUI.backgroundColor; GUI.backgroundColor = (i & 1) == 0 ? new Color(0.6f, 0.6f, 0.7f) : new Color(0.8f, 0.8f, 0.8f); EditorGUILayout.BeginVertical((GUIStyle)"AS TextArea", GUILayout.MinHeight(20f)); GUI.backgroundColor = cachedBgColor; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Sheet Name", GUILayout.Width(76f)); string sheetName = EditorGUILayout.TextField(xmlSheetData.sheetName); if (sheetName != xmlSheetData.sheetName) { xmlSheetData.sheetName = sheetName; dirty = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Comments", GUILayout.Width(76f)); string comments = EditorGUILayout.TextField(xmlSheetData.comments); if (comments != xmlSheetData.comments) { xmlSheetData.comments = comments; dirty = true; } EditorGUILayout.EndHorizontal(); int removeXmlAt = -1; for (int j = 0, jmax = xmlSheetData.files.Length; j < jmax; j++) { XmlSheetGroupSettings.XmlSheetFile sheetFile = xmlSheetData.files[j]; if (sheetFile == null) { continue; } GUILayout.Space(4f); EditorGUILayout.BeginHorizontal(); GUILayout.Space(10f); EditorGUILayout.LabelField(string.Format("Xml File {0} : ", (j + 1))); cachedBgColor = GUI.backgroundColor; GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete", GUILayout.Width(64f))) { removeXmlAt = j; } GUI.backgroundColor = cachedBgColor; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.MinHeight(20f)); GUILayout.Space(20f); EditorGUILayout.LabelField("Path", GUILayout.Width(40f)); GUILayout.Space(2f); bool invalid = mInvalidFiles.Contains(sheetFile.filePath); cachedBgColor = GUI.backgroundColor; if (invalid) { GUI.backgroundColor = Color.red; } EditorGUILayout.LabelField(new GUIContent(sheetFile.filePath, invalid ? "File Not Found" : null), (GUIStyle)"AS TextArea", GUILayout.Height(20f)); GUI.backgroundColor = cachedBgColor; if (GUILayout.Button("Browse", GUILayout.Width(64))) { string xmlPath = browseXmlFile("Fail to Change Xml File", sheetFile); if (!string.IsNullOrEmpty(xmlPath)) { sheetFile.filePath = xmlPath; dirty = true; } } GUILayout.Space(2f); EditorGUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.LabelField("Type", GUILayout.Width(40f)); GUILayout.Space(2f); sheetFile.typeName = EditorGUILayout.TextField(sheetFile.typeName); if (GUILayout.Button("ProtoGen", GUILayout.Width(64))) { string codePath; string dir = string.IsNullOrEmpty(sheetFile.codePath) ? null : Path.GetDirectoryName(sheetFile.codePath); string typeName = ProtoGen.GenerateProto(dir, out codePath); if (!string.IsNullOrEmpty(typeName)) { sheetFile.typeName = typeName; sheetFile.codePath = codePath; dirty = true; AssetDatabase.Refresh(); } } EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { dirty = true; } } if (removeXmlAt >= 0) { if (xmlSheetData.files.Length == 1) { EditorUtility.DisplayDialog("Delete Xml File in Sheet", "Cannot delete xml file because a sheet should contains at least one xml file !", "OK"); } else { XmlSheetGroupSettings.XmlSheetFile[] newSheetFiles = new XmlSheetGroupSettings.XmlSheetFile[xmlSheetData.files.Length - 1]; Array.Copy(xmlSheetData.files, 0, newSheetFiles, 0, removeXmlAt); Array.Copy(xmlSheetData.files, removeXmlAt + 1, newSheetFiles, removeXmlAt, newSheetFiles.Length - removeXmlAt); xmlSheetData.files = newSheetFiles; dirty = true; } } if (GUILayout.Button("Add Xml File")) { string xmlPath = browseXmlFile("Fail to Add Xml File", null); if (!string.IsNullOrEmpty(xmlPath)) { XmlSheetGroupSettings.XmlSheetFile[] newSheetFiles = new XmlSheetGroupSettings.XmlSheetFile[xmlSheetData.files.Length + 1]; Array.Copy(xmlSheetData.files, 0, newSheetFiles, 0, xmlSheetData.files.Length); XmlSheetGroupSettings.XmlSheetFile newFile = new XmlSheetGroupSettings.XmlSheetFile(); newFile.filePath = xmlPath; newSheetFiles[xmlSheetData.files.Length] = newFile; xmlSheetData.files = newSheetFiles; dirty = true; } } //end content EditorGUILayout.EndVertical(); cachedBgColor = GUI.backgroundColor; GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete", GUILayout.Width(60f))) { removeAt = i; } GUI.backgroundColor = cachedBgColor; GUILayout.Space(4f); EditorGUILayout.EndHorizontal(); GUILayout.Space(2f); } GUILayout.BeginHorizontal(); GUILayout.Space(12f); cachedBgColor = GUI.backgroundColor; GUI.backgroundColor = Color.green; if (GUILayout.Button("Add New Sheet")) { XmlSheetGroupSettings.XmlSheetData[] xmlFiles = new XmlSheetGroupSettings.XmlSheetData[mCurGroup.sheetFiles.Length + 1]; Array.Copy(mCurGroup.sheetFiles, 0, xmlFiles, 0, mCurGroup.sheetFiles.Length); XmlSheetGroupSettings.XmlSheetData newXml = new XmlSheetGroupSettings.XmlSheetData(); newXml.sheetName = "new_sheet"; newXml.comments = "new_sheet"; newXml.files = new XmlSheetGroupSettings.XmlSheetFile[] { new XmlSheetGroupSettings.XmlSheetFile() }; xmlFiles[mCurGroup.sheetFiles.Length] = newXml; mCurGroup.sheetFiles = xmlFiles; dirty = true; } GUILayout.EndHorizontal(); if (removeAt >= 0) { XmlSheetGroupSettings.XmlSheetData[] xmlFiles = new XmlSheetGroupSettings.XmlSheetData[mCurGroup.sheetFiles.Length - 1]; Array.Copy(mCurGroup.sheetFiles, 0, xmlFiles, 0, removeAt); Array.Copy(mCurGroup.sheetFiles, removeAt + 1, xmlFiles, removeAt, xmlFiles.Length - removeAt); mCurGroup.sheetFiles = xmlFiles; dirty = true; } GUI.backgroundColor = cachedBgColor; EditorGUILayout.EndScrollView(); GUILayout.Space(8f); EditorGUI.BeginDisabledGroup(!isValid); if (GUILayout.Button("Generate Binary File", GUILayout.Height(32f))) { Generate(); } EditorGUI.EndDisabledGroup(); } GUILayout.Space(4f); if (dirty) { ConfigSettings.WriteXmlSheetGroupSettings(mSettingsList); } EditorGUI.EndDisabledGroup(); }
/// <summary> /// 将一个组中所有的sheet加到数据库中,运行时将读取原始数据 /// </summary> /// <param name="group">该组的所有信息</param> /// <returns>组名称,若添加失败或该组已存在,则返回null</returns> public string AddToDatabase(XmlSheetGroupSettings group) { return(AddToDatabase(group, null)); }
/// <summary> /// 将指定的XmlSheetGroup数据序列化并生成二进制文件 /// </summary> /// <param name="group">该组的所有信息</param> public static void GenerateGroupBinaryFile(XmlSheetGroupSettings group) { Exception exception = null; int num = group.sheetFiles.Length; byte[] bytesLen, bytesContent; MemoryStream tmpStream = new MemoryStream(); FileStream stream = File.OpenWrite(group.group); try { //二进制文件的最前面是sheet组的名字; bytesContent = Encoding.UTF8.GetBytes(group.group); bytesLen = BitConverter.GetBytes((ushort)bytesContent.Length); stream.Write(bytesLen, 0, bytesLen.Length); stream.Write(bytesContent, 0, bytesContent.Length); //sheet的数量(ushort, 最多65535个); bytesLen = BitConverter.GetBytes((ushort)num); stream.Write(bytesLen, 0, bytesLen.Length); long offsetPos = stream.Position; long headPos = 4L * num + offsetPos; List <SheetDataIndex> indices = new List <SheetDataIndex>(); List <long> allIndicesPos = new List <long>(); List <SheetDataIndex> allIndices = new List <SheetDataIndex>(); Dictionary <string, int> allTypes = new Dictionary <string, int>(); for (int i = 0; i < num; i++) { XmlSheetGroupSettings.XmlSheetData sheet = group.sheetFiles[i]; if (sheet == null) { continue; } stream.Position = offsetPos; bytesLen = BitConverter.GetBytes((uint)headPos); stream.Write(bytesLen, 0, bytesLen.Length); offsetPos += 4L; stream.Position = headPos; //写入头部信息。只有当生成数据之后才能得到头部信息; //头部信息的起始是sheet名; string sheetName = sheet.sheetName; //Debug.LogError("sheet name : " + sheetName); bytesContent = Encoding.UTF8.GetBytes(sheetName); bytesLen = BitConverter.GetBytes((ushort)bytesContent.Length); stream.Write(bytesLen, 0, bytesLen.Length); stream.Write(bytesContent, 0, bytesContent.Length); List <string> filePaths = new List <string>(); List <string> typeNames = new List <string>(); for (int j = 0, jmax = sheet.files.Length; j < jmax; j++) { filePaths.Add(sheet.files[j].filePath); typeNames.Add(sheet.files[j].typeName); } bool strKey; SerializeXmlSheet(filePaths.ToArray(), typeNames.ToArray(), indices, tmpStream, allTypes, out strKey); //头部条目数量。首位表示键的类型是否为字符串(1:字符串,0:整型); uint count = (uint)indices.Count; if (strKey) { count = 0x80000000 | count; } bytesLen = BitConverter.GetBytes(count); stream.Write(bytesLen, 0, bytesLen.Length); for (int j = 0, jmax = indices.Count; j < jmax; j++) { SheetDataIndex idx = indices[j]; allIndicesPos.Add(stream.Position); allIndices.Add(idx); idx.Write(stream, 0L); } headPos = stream.Position; indices.Clear(); } string[] allTypeNames = new string[allTypes.Count]; foreach (KeyValuePair <string, int> kv in allTypes) { allTypeNames[kv.Value] = kv.Key; } bytesLen = BitConverter.GetBytes((ushort)allTypeNames.Length); stream.Write(bytesLen, 0, bytesLen.Length); for (int i = 0, imax = allTypeNames.Length; i < imax; i++) { bytesContent = Encoding.UTF8.GetBytes(allTypeNames[i]); if (bytesContent.Length > 255) { throw new Exception(string.Format("Type Name '{0}' is too long !", allTypeNames[i])); } stream.WriteByte((byte)bytesContent.Length); stream.Write(bytesContent, 0, bytesContent.Length); } headPos = stream.Position; for (int i = 0, imax = allIndicesPos.Count; i < imax; i++) { stream.Position = allIndicesPos[i]; allIndices[i].Write(stream, headPos); } stream.Position = headPos; byte[] buffer = new byte[4096]; tmpStream.SetLength(tmpStream.Position); tmpStream.Position = 0; while (true) { int len = tmpStream.Read(buffer, 0, buffer.Length); if (len <= 0) { break; } stream.Write(buffer, 0, len); } tmpStream.Close(); } catch (Exception e) { exception = e; } stream.SetLength(stream.Position); stream.Flush(); stream.Close(); if (exception != null) { throw exception; } }