DataFiles.hx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package hide.comp.cdb;
  2. typedef DataProps = {
  3. var file : String;
  4. var path : String;
  5. var index : Int;
  6. var origin : String;
  7. }
  8. class DataFiles {
  9. static var changed : Bool;
  10. static var skip : Int = 0;
  11. static var watching : Map<String, Bool> = new Map();
  12. static var base(get,never) : cdb.Database;
  13. static function get_base() return Ide.inst.database;
  14. public static function load() {
  15. for( sheet in base.sheets )
  16. if( sheet.props.dataFiles != null && sheet.lines == null )
  17. loadSheet(sheet);
  18. }
  19. static function onFileChanged() {
  20. if( skip > 0 ) {
  21. skip--;
  22. return;
  23. }
  24. changed = true;
  25. haxe.Timer.delay(function() {
  26. if( !changed ) return;
  27. changed = false;
  28. reload();
  29. Editor.refreshAll(true);
  30. },0);
  31. }
  32. static function reload() {
  33. for( s in base.sheets )
  34. if( s.props.dataFiles != null ) @:privateAccess {
  35. s.sheet.lines = null;
  36. s.sheet.linesData = null;
  37. }
  38. load();
  39. }
  40. static function loadSheet( sheet : cdb.Sheet ) {
  41. var ide = Ide.inst;
  42. var lines : Array<Dynamic> = [];
  43. var linesData : Array<DataProps> = [];
  44. var separators = [];
  45. var separatorTitles = [];
  46. var sheetName = getTypeName(sheet);
  47. @:privateAccess {
  48. sheet.sheet.lines = lines;
  49. sheet.sheet.linesData = linesData;
  50. sheet.sheet.separators = separators;
  51. sheet.props.separatorTitles = separatorTitles;
  52. }
  53. function loadFile( file : String ) {
  54. var needSep = true;
  55. var levelID = file.split("/").pop().split(".").shift();
  56. levelID = levelID.charAt(0).toUpperCase()+levelID.substr(1);
  57. function loadRec( p : hrt.prefab.Prefab, parent : hrt.prefab.Prefab ) {
  58. if( p.getCdbType() == sheetName ) {
  59. var dprops : DataProps = {
  60. file : file,
  61. path : p.getAbsPath(),
  62. index : 0,
  63. origin : haxe.Json.stringify(p.props),
  64. };
  65. if( parent != null ) {
  66. for( c in parent.children ) {
  67. if( c == p ) break;
  68. if( c.name == p.name ) dprops.index++;
  69. }
  70. }
  71. if( needSep ) {
  72. separators.push(lines.length);
  73. separatorTitles.push(file);
  74. needSep = false;
  75. }
  76. if( sheet.idCol != null && Reflect.field(p.props,sheet.idCol.name) == "" )
  77. Reflect.setField(p.props,sheet.idCol.name,levelID+"_"+p.name+(dprops.index == 0 ? "" : ""+dprops.index));
  78. linesData.push(dprops);
  79. lines.push(p.props);
  80. }
  81. for( c in p ) loadRec(c,p);
  82. }
  83. var p = ide.loadPrefab(file);
  84. loadRec(p,null);
  85. if( !watching.exists(file) ) {
  86. watching.set(file, true);
  87. ide.fileWatcher.register(file, onFileChanged);
  88. }
  89. }
  90. function gatherRec( basePath : Array<String>, curPath : Array<String>, i : Int ) {
  91. var part = basePath[i++];
  92. if( part == null ) {
  93. var file = curPath.join("/");
  94. if( sys.FileSystem.exists(ide.getPath(file)) ) loadFile(file);
  95. return;
  96. }
  97. if( part.indexOf("*") < 0 ) {
  98. curPath.push(part);
  99. gatherRec(basePath,curPath,i);
  100. curPath.pop();
  101. } else {
  102. var path = curPath.join("/");
  103. var dir = ide.getPath(path);
  104. if( !sys.FileSystem.isDirectory(dir) )
  105. return;
  106. if( !watching.exists(path) ) {
  107. watching.set(path, true);
  108. ide.fileWatcher.register(path, onFileChanged, true);
  109. }
  110. var reg = new EReg("^"+part.split(".").join("\\.").split("*").join(".*")+"$","");
  111. var subs = sys.FileSystem.readDirectory(dir);
  112. subs.sort(Reflect.compare);
  113. for( f in subs ) {
  114. if( !reg.match(f) ) {
  115. if( sys.FileSystem.isDirectory(dir+"/"+f) ) {
  116. curPath.push(f);
  117. gatherRec(basePath,curPath,i-1);
  118. curPath.pop();
  119. }
  120. continue;
  121. }
  122. curPath.push(f);
  123. gatherRec(basePath,curPath,i);
  124. curPath.pop();
  125. }
  126. }
  127. }
  128. for( dir in sheet.props.dataFiles.split(";") )
  129. gatherRec(dir.split("/"),[],0);
  130. }
  131. public static function save( ?onSaveBase, ?force, ?prevSheetNames : Map<String,String> ) {
  132. var ide = Ide.inst;
  133. var temp = [];
  134. var titles = [];
  135. var prefabs = new Map();
  136. for( s in base.sheets ) {
  137. for( c in s.columns ) {
  138. var p : Editor.EditorColumnProps = c.editor;
  139. if( p != null && p.ignoreExport ) {
  140. var prev = [for( o in s.lines ) Reflect.field(o, c.name)];
  141. for( o in s.lines ) Reflect.deleteField(o, c.name);
  142. temp.push(function() {
  143. for( i in 0...prev.length ) {
  144. var v = prev[i];
  145. if( v == null ) continue;
  146. Reflect.setField(s.lines[i], c.name, v);
  147. }
  148. });
  149. }
  150. }
  151. if( s.props.dataFiles != null ) {
  152. var sheet = @:privateAccess s.sheet;
  153. var sheetName = getTypeName(s);
  154. var prevName = sheetName;
  155. if( prevSheetNames != null && prevSheetNames.exists(sheetName) )
  156. prevName = prevSheetNames.get(sheetName);
  157. var ldata = sheet.linesData;
  158. for( i in 0...s.lines.length ) {
  159. var o = s.lines[i];
  160. var p : DataProps = sheet.linesData[i];
  161. var str = haxe.Json.stringify(o);
  162. if( str != p.origin || force ) {
  163. p.origin = str;
  164. var pf : hrt.prefab.Prefab = prefabs.get(p.file);
  165. if( pf == null ) {
  166. pf = ide.loadPrefab(p.file);
  167. prefabs.set(p.file, pf);
  168. }
  169. var all = pf.getPrefabsByPath(p.path);
  170. var inst : hrt.prefab.Prefab = all[p.index];
  171. if( inst == null || inst.getCdbType() != prevName )
  172. ide.error("Can't save prefab data "+p.path);
  173. else {
  174. if( prevName != sheetName ) Reflect.setField(o,"$cdbtype", sheetName);
  175. inst.props = o;
  176. }
  177. }
  178. }
  179. var old = Reflect.copy(sheet);
  180. var oldTitles = sheet.props.separatorTitles;
  181. temp.push(function() {
  182. sheet.lines = old.lines;
  183. sheet.linesData = old.linesData;
  184. sheet.separators = old.separators;
  185. sheet.props.separatorTitles = oldTitles;
  186. });
  187. Reflect.deleteField(sheet,"lines");
  188. Reflect.deleteField(sheet,"linesData");
  189. sheet.separators = [];
  190. Reflect.deleteField(sheet.props,"separatorTitles");
  191. }
  192. }
  193. for( file => pf in prefabs ) {
  194. skip++;
  195. sys.io.File.saveContent(ide.getPath(file), ide.toJSON(pf.saveData()));
  196. }
  197. if( onSaveBase != null )
  198. onSaveBase();
  199. temp.reverse();
  200. for( t in temp )
  201. t();
  202. }
  203. // ---- TYPES Instances API -----
  204. public static function getTypeName( sheet : cdb.Sheet ) {
  205. return sheet.name.split("@").pop();
  206. }
  207. public static function getAvailableTypes() {
  208. var sheets = [];
  209. var ide = Ide.inst;
  210. for( s in ide.database.sheets )
  211. if( s.props.dataFiles != null )
  212. sheets.push(s);
  213. return sheets;
  214. }
  215. public static function resolveType( name : String ) {
  216. if( name == null )
  217. return null;
  218. for( s in getAvailableTypes() )
  219. if( getTypeName(s) == name )
  220. return s;
  221. return null;
  222. }
  223. }