Skip to content

Commit c1fc934

Browse files
committed
implement saving for shortguids
1 parent efc4085 commit c1fc934

7 files changed

Lines changed: 328 additions & 209 deletions

File tree

CathodeLib/Scripts/CATHODE/Commands.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ namespace CATHODE
1414
{
1515
public class Commands : CathodeFile
1616
{
17-
public Action OnLoaded;
18-
public Action OnSaved;
17+
public Action<string> OnLoaded;
18+
public Action<string> OnSaved;
1919

2020
// This is always:
2121
// - Root Instance (the map's entry composite, usually containing entities that call mission/environment composites)
@@ -658,7 +658,7 @@ override public bool Save()
658658
writer.Write(_composites.Count);
659659

660660
writer.Close();
661-
OnSaved?.Invoke();
661+
OnSaved?.Invoke(_filepath);
662662
return true;
663663
}
664664

@@ -1100,7 +1100,7 @@ override protected bool Load()
11001100
_composites = composites.ToList<Composite>();
11011101

11021102
reader.Close();
1103-
OnLoaded?.Invoke();
1103+
OnLoaded?.Invoke(_filepath);
11041104
return true;
11051105
}
11061106
#endregion

CathodeLib/Scripts/CATHODE/CommandsPAK/Components/TypeEnums.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,4 +1132,17 @@ public enum CompositeFileData
11321132

11331133
NUMBER_OF_SCRIPT_BLOCKS, //THIS IS NOT A DATA BLOCK: merely used as an easy way of sanity checking the number of blocks in-code!
11341134
}
1135+
1136+
/* Custom tables written at the end of the PAK to store extra info */
1137+
public enum CustomEndTables
1138+
{
1139+
//NOTE: NEVER remove options from here, or re-order them.
1140+
// Doing this will cause issues with backwards compatibility.
1141+
ENTITY_NAMES,
1142+
SHORT_GUIDS,
1143+
1144+
//Add new entries here
1145+
1146+
NUMBER_OF_END_TABLES, //USED FOR COUNTING ONLY
1147+
}
11351148
}

CathodeLib/Scripts/CATHODE/CommandsPAK/Helpers/CompositeUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ static CompositeUtils()
1717
int compositeCount = reader.ReadInt32();
1818
pathLookup = new Dictionary<ShortGuid, string>(compositeCount);
1919
for (int i = 0; i < compositeCount; i++)
20-
pathLookup.Add(CathodeLib.Utilities.Consume<ShortGuid>(reader), reader.ReadString());
20+
pathLookup.Add(Utilities.Consume<ShortGuid>(reader), reader.ReadString());
2121
}
2222

2323
public static string GetFullPath(ShortGuid guid)
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
using CATHODE.Scripting;
2+
using CATHODE.Scripting.Internal;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Text;
7+
8+
namespace CathodeLib
9+
{
10+
public static class CustomTable
11+
{
12+
private static readonly byte _version = 50;
13+
14+
/* Write a CathodeLib data table to the Commands PAK */
15+
public static void WriteTable(string filepath, CustomEndTables table, Table content)
16+
{
17+
if (!File.Exists(filepath)) return;
18+
19+
Dictionary<CustomEndTables, Table> toWrite = new Dictionary<CustomEndTables, Table>();
20+
for (int i = 0; i < (int)CustomEndTables.NUMBER_OF_END_TABLES; i++)
21+
{
22+
CustomEndTables tableType = (CustomEndTables)i;
23+
if (tableType == table)
24+
toWrite.Add(tableType, content);
25+
else
26+
toWrite.Add(tableType, ReadTable(filepath, tableType));
27+
}
28+
29+
BinaryReader reader = new BinaryReader(File.OpenRead(filepath));
30+
TableExists(reader, out int endPos);
31+
reader.Close();
32+
33+
BinaryWriter writer = new BinaryWriter(File.OpenWrite(filepath));
34+
writer.BaseStream.SetLength(endPos);
35+
writer.BaseStream.Position = endPos;
36+
writer.Write(_version);
37+
38+
writer.Write((Int32)CustomEndTables.NUMBER_OF_END_TABLES);
39+
40+
int posToWriteOffsets = (int)writer.BaseStream.Position;
41+
Dictionary<CustomEndTables, int> tableOffsets = new Dictionary<CustomEndTables, int>();
42+
for (int i = 0; i < (int)CustomEndTables.NUMBER_OF_END_TABLES; i++)
43+
writer.Write((Int32)0);
44+
45+
for (int i = 0; i < (int)CustomEndTables.NUMBER_OF_END_TABLES; i++)
46+
{
47+
CustomEndTables tableType = (CustomEndTables)i;
48+
tableOffsets.Add(tableType, (int)writer.BaseStream.Position);
49+
if (toWrite[tableType] == null) writer.Write((Int32)0);
50+
else
51+
{
52+
switch (tableType)
53+
{
54+
case CustomEndTables.ENTITY_NAMES:
55+
((EntityNameTable)toWrite[tableType]).Write(writer);
56+
break;
57+
case CustomEndTables.SHORT_GUIDS:
58+
((GuidNameTable)toWrite[tableType]).Write(writer);
59+
break;
60+
}
61+
}
62+
}
63+
64+
writer.BaseStream.Position = posToWriteOffsets;
65+
for (int i = 0; i < (int)CustomEndTables.NUMBER_OF_END_TABLES; i++)
66+
writer.Write(tableOffsets[(CustomEndTables)i]);
67+
68+
writer.Close();
69+
}
70+
71+
/* Read a CathodeLib data table from the Commands PAK */
72+
public static Table ReadTable(string filepath, CustomEndTables table)
73+
{
74+
if (!File.Exists(filepath)) return null;
75+
76+
BinaryReader reader = new BinaryReader(File.OpenRead(filepath));
77+
if (!TableExists(reader, out int endPos))
78+
{
79+
reader.Close();
80+
return null;
81+
}
82+
83+
int customDbCount = reader.ReadInt32();
84+
85+
int dbOffset = -1;
86+
for (int i = 0; i < customDbCount; i++)
87+
{
88+
CustomEndTables tbl = (CustomEndTables)i;
89+
if (tbl == table)
90+
dbOffset = reader.ReadInt32();
91+
else
92+
reader.BaseStream.Position += 4;
93+
}
94+
if (dbOffset == -1) return null;
95+
96+
reader.BaseStream.Position = dbOffset;
97+
Table data = null;
98+
switch (table)
99+
{
100+
case CustomEndTables.ENTITY_NAMES:
101+
data = new EntityNameTable(reader);
102+
break;
103+
case CustomEndTables.SHORT_GUIDS:
104+
data = new GuidNameTable(reader);
105+
break;
106+
}
107+
reader.Close();
108+
return data;
109+
}
110+
111+
private static bool TableExists(BinaryReader reader, out int endPos)
112+
{
113+
reader.BaseStream.Position = 20;
114+
endPos = (reader.ReadInt32() * 4) + (reader.ReadInt32() * 4);
115+
reader.BaseStream.Position = endPos;
116+
return (int)reader.BaseStream.Length - endPos != 0 && reader.ReadByte() == _version;
117+
}
118+
119+
public class Table
120+
{
121+
public Table(BinaryReader reader)
122+
{
123+
Read(reader);
124+
}
125+
126+
public CustomEndTables type = CustomEndTables.NUMBER_OF_END_TABLES;
127+
128+
protected virtual void Read(BinaryReader reader)
129+
{
130+
131+
}
132+
133+
public virtual void Write(BinaryWriter writer)
134+
{
135+
writer.Write((Int32)0);
136+
}
137+
}
138+
}
139+
140+
public class EntityNameTable : CustomTable.Table
141+
{
142+
public EntityNameTable(BinaryReader reader = null) : base(reader)
143+
{
144+
type = CustomEndTables.ENTITY_NAMES;
145+
}
146+
147+
public Dictionary<ShortGuid, Dictionary<ShortGuid, string>> names;
148+
149+
protected override void Read(BinaryReader reader)
150+
{
151+
if (reader == null)
152+
{
153+
names = new Dictionary<ShortGuid, Dictionary<ShortGuid, string>>();
154+
return;
155+
}
156+
157+
int compositeCount = reader.ReadInt32();
158+
names = new Dictionary<ShortGuid, Dictionary<ShortGuid, string>>(compositeCount);
159+
for (int i = 0; i < compositeCount; i++)
160+
{
161+
ShortGuid compositeID = Utilities.Consume<ShortGuid>(reader);
162+
int entityCount = reader.ReadInt32();
163+
names.Add(compositeID, new Dictionary<ShortGuid, string>(entityCount));
164+
for (int x = 0; x < entityCount; x++)
165+
{
166+
ShortGuid entityID = Utilities.Consume<ShortGuid>(reader);
167+
names[compositeID].Add(entityID, reader.ReadString());
168+
}
169+
}
170+
}
171+
172+
public override void Write(BinaryWriter writer)
173+
{
174+
writer.Write(names.Count);
175+
foreach (KeyValuePair<ShortGuid, Dictionary<ShortGuid, string>> composite in names)
176+
{
177+
Utilities.Write<ShortGuid>(writer, composite.Key);
178+
writer.Write(composite.Value.Count);
179+
foreach (KeyValuePair<ShortGuid, string> entity in composite.Value)
180+
{
181+
Utilities.Write<ShortGuid>(writer, entity.Key);
182+
writer.Write(entity.Value);
183+
}
184+
}
185+
}
186+
}
187+
public class GuidNameTable : CustomTable.Table
188+
{
189+
public GuidNameTable(BinaryReader reader = null) : base(reader)
190+
{
191+
type = CustomEndTables.SHORT_GUIDS;
192+
}
193+
194+
public Dictionary<string, ShortGuid> cache;
195+
public Dictionary<ShortGuid, string> cacheReversed;
196+
197+
protected override void Read(BinaryReader reader)
198+
{
199+
if (reader == null)
200+
{
201+
cache = new Dictionary<string, ShortGuid>();
202+
cacheReversed = new Dictionary<ShortGuid, string>();
203+
return;
204+
}
205+
206+
int count = reader.ReadInt32();
207+
cache = new Dictionary<string, ShortGuid>();
208+
cacheReversed = new Dictionary<ShortGuid, string>();
209+
for (int i = 0; i < count; i++)
210+
{
211+
ShortGuid id = Utilities.Consume<ShortGuid>(reader);
212+
string str = reader.ReadString();
213+
if (!cache.ContainsKey(str))
214+
{
215+
cache.Add(str, id);
216+
cacheReversed.Add(id, str);
217+
}
218+
}
219+
}
220+
221+
public override void Write(BinaryWriter writer)
222+
{
223+
writer.Write(cache.Count);
224+
foreach (KeyValuePair<string, ShortGuid> composite in cache)
225+
{
226+
Utilities.Write<ShortGuid>(writer, composite.Value);
227+
writer.Write(composite.Key);
228+
}
229+
}
230+
}
231+
}

0 commit comments

Comments
 (0)