DEADSOFTWARE

xdynrec: some code cleanup
[d2df-sdl.git] / src / shared / xdynrec.pas
index b65ab8a4af7b13fb8eb25f445f01442175050ca4..37c37aa1cf00f19b57c4912c4e72a9a56e005c53 100644 (file)
@@ -21,7 +21,7 @@ interface
 
 uses
   SysUtils, Variants, Classes,
-  xparser, xstreams, utils, hashtable;
+  xparser, xstreams, utils, hashtable, mempool;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
@@ -54,7 +54,7 @@ type
   TDynEBSList = specialize TSimpleList<TDynEBS>;
 
   // this is base type for all scalars (and arrays)
-  TDynField = class
+  TDynField = class(TPoolObject)
   public
     type
       TType = (TBool, TChar, TByte, TUByte, TShort, TUShort, TInt, TUInt, TString, TPoint, TSize, TColor, TList, TTrigData);
@@ -238,7 +238,7 @@ type
 
 
   // record, either with actual values, or with type definitions
-  TDynRecord = class
+  TDynRecord = class(TPoolObject)
   private
     mOwner: TDynMapDef;
     mId: AnsiString;
@@ -375,7 +375,7 @@ type
 
 
   // bitset/enum definition
-  TDynEBS = class
+  TDynEBS = class(TPoolObject)
   private
     mOwner: TDynMapDef;
     mIsEnum: Boolean;
@@ -412,7 +412,7 @@ type
     property typeName: AnsiString read mTypeName; // enum/bitset type name
     property isEnum: Boolean read mIsEnum; // is this enum? `false` means "bitset"
     property has[const aname: AnsiString]: Boolean read hasByName;
-    property field[const aname: AnsiString]: Integer read getFieldByName;
+    property field[const aname: AnsiString]: Integer read getFieldByName; default;
 
     property tip: AnsiString read mTip;
     property help: AnsiString read mHelp;
@@ -420,7 +420,7 @@ type
 
 
   // parsed "mapdef.txt"
-  TDynMapDef = class
+  TDynMapDef = class(TPoolObject)
   public
     recTypes: TDynRecList; // [0] is always header
     trigTypes: TDynRecList; // trigdata
@@ -974,6 +974,7 @@ begin
     try
       stp := TStrTextParser.Create(mDefUnparsed+';');
       parseValue(stp);
+      //if (mType = TType.TColor) then writeln('4=[', mIVal4, ']');
       mDefSVal := mSVal;
       mDefIVal := mIVal;
       mDefIVal2 := mIVal2;
@@ -1009,6 +1010,7 @@ begin
   mIVal2 := mDefIVal2;
   mIVal3 := mDefIVal3;
   mIVal4 := mDefIVal4;
+  //if (mType = TType.TColor) then writeln('4=[', mDefIVal4, ']');
   mDefined := true;
 end;
 
@@ -2740,7 +2742,7 @@ var
     end;
     for fld in rec.mFields do
     begin
-      //writeln('  ', fld.mName);
+      //if (fld.mName = 'ambient_color') then writeln('****', fld.mName);
       fld.fixDefaultValue(); // just in case
     end;
   end;
@@ -2830,6 +2832,12 @@ begin
       //writeln('parsing ''', mName, '.', fld.mName, '''...');
       fld.parseBinValue(mst);
     end;
+    // fix default values
+    for fld in mFields do
+    begin
+      if (fld.mType = TDynField.TType.TList) then continue;
+      fld.fixDefaultValue();
+    end;
   finally
     mst.Free();
     if (buf <> nil) then FreeMem(buf);
@@ -3058,14 +3066,19 @@ var
   procedure linkNames (rec: TDynRecord);
   var
     fld: TDynField;
-    rt: TDynRecord;
+    rt, rvc: TDynRecord;
   begin
+    if (rec = nil) then exit;
     //writeln('*** rec: ', rec.mName, '.', rec.mId, ' (', rec.mFields.count, ')');
     for fld in rec.mFields do
     begin
+      if (fld.mType = TDynField.TType.TList) then
+      begin
+        for rvc in fld.mRVal do linkNames(rvc);
+      end;
       if (fld.mType = TDynField.TType.TTrigData) then
       begin
-        if (fld.mRecRef <> nil) then linkNames(fld.mRecRef);
+        //if (fld.mRecRef <> nil) then linkNames(fld.mRecRef);
         continue;
       end;
       if (Length(fld.mRecRefId) = 0) then continue;
@@ -3084,14 +3097,14 @@ var
     for fld in rec.mFields do
     begin
       //writeln('  ', fld.mName);
-      fld.fixDefaultValue(); // just in case
+      fld.fixDefaultValue();
     end;
   end;
 
 begin
   if (mOwner = nil) then raise TDynParseException.CreateFmt(pr, 'can''t parse record ''%s'' value without owner', [mTypeName]);
 
-  {$IF DEFINED(D2D_DYNREC_PROFILER)}stall := curTimeMicro();{$ENDIF}
+  {$IF DEFINED(D2D_DYNREC_PROFILER)}stall := getTimeMicro();{$ENDIF}
 
   // not a header?
   if not mHeader then
@@ -3115,31 +3128,31 @@ begin
     if mHeader then
     begin
       // add records with this type (if any)
-      {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
+      {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := getTimeMicro();{$ENDIF}
       trc := mOwner.recType[pr.tokStr];
-      {$IF DEFINED(D2D_DYNREC_PROFILER)}profFindRecType := curTimeMicro()-stt;{$ENDIF}
+      {$IF DEFINED(D2D_DYNREC_PROFILER)}profFindRecType := getTimeMicro()-stt;{$ENDIF}
       if (trc <> nil) then
       begin
-        {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
+        {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := getTimeMicro();{$ENDIF}
         rec := trc.clone(mHeaderRec);
-        {$IF DEFINED(D2D_DYNREC_PROFILER)}profCloneRec := curTimeMicro()-stt;{$ENDIF}
+        {$IF DEFINED(D2D_DYNREC_PROFILER)}profCloneRec := getTimeMicro()-stt;{$ENDIF}
         rec.mHeaderRec := mHeaderRec;
         // on error, it will be freed by memowner
         pr.skipToken();
         rec.parseValue(pr);
-        {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
+        {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := getTimeMicro();{$ENDIF}
         addRecordByType(rec.mTypeName, rec);
-        {$IF DEFINED(D2D_DYNREC_PROFILER)}profAddRecByType := curTimeMicro()-stt;{$ENDIF}
+        {$IF DEFINED(D2D_DYNREC_PROFILER)}profAddRecByType := getTimeMicro()-stt;{$ENDIF}
         continue;
       end;
     end;
 
     // fields
-    {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
+    {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := getTimeMicro();{$ENDIF}
     //writeln('0: <', mName, '.', pr.tokStr, '>');
     fld := field[pr.tokStr];
     //writeln('1: <', mName, '.', pr.tokStr, '>');
-    {$IF DEFINED(D2D_DYNREC_PROFILER)}profFieldSearching := curTimeMicro()-stt;{$ENDIF}
+    {$IF DEFINED(D2D_DYNREC_PROFILER)}profFieldSearching := getTimeMicro()-stt;{$ENDIF}
     if (fld <> nil) then
     begin
       //writeln('2: <', mName, '.', pr.tokStr, '>');
@@ -3147,9 +3160,9 @@ begin
       if fld.internal then raise TDynParseException.CreateFmt(pr, 'internal field ''%s'' in record ''%s''', [fld.mName, mTypeName]);
       pr.skipToken(); // skip field name
       //writeln('3: <', mName, '.', pr.tokStr, '>:', pr.tokType);
-      {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
+      {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := getTimeMicro();{$ENDIF}
       fld.parseValue(pr);
-      {$IF DEFINED(D2D_DYNREC_PROFILER)}profFieldValParsing := curTimeMicro()-stt;{$ENDIF}
+      {$IF DEFINED(D2D_DYNREC_PROFILER)}profFieldValParsing := getTimeMicro()-stt;{$ENDIF}
       continue;
     end;
 
@@ -3161,20 +3174,12 @@ begin
   if mHeader then
   begin
     // link fields
-    for fld in mFields do
-    begin
-      if (fld.mType <> TDynField.TType.TList) then continue;
-      for rec in fld.mRVal do linkNames(rec);
-    end;
+    linkNames(self);
+    for rec in mRec2Free do if (rec <> nil) then linkNames(rec);
   end;
-
-  // fix field defaults
-  {$IF DEFINED(D2D_DYNREC_PROFILER)}stt := curTimeMicro();{$ENDIF}
-  for fld in mFields do fld.fixDefaultValue();
-  {$IF DEFINED(D2D_DYNREC_PROFILER)}profFixDefaults := curTimeMicro()-stt;{$ENDIF}
   //writeln('done parsing record <', mName, '>');
-  //{$IF DEFINED(D2D_DYNREC_PROFILER)}writeln('stall: ', curTimeMicro()-stall);{$ENDIF}
-  {$IF DEFINED(D2D_DYNREC_PROFILER)}profRecValParse := curTimeMicro()-stall;{$ENDIF}
+  //{$IF DEFINED(D2D_DYNREC_PROFILER)}writeln('stall: ', getTimeMicro()-stall);{$ENDIF}
+  {$IF DEFINED(D2D_DYNREC_PROFILER)}profRecValParse := getTimeMicro()-stall;{$ENDIF}
 end;