diff --git a/src/shared/xdynrec.pas b/src/shared/xdynrec.pas
index 37c37aa1cf00f19b57c4912c4e72a9a56e005c53..511c82dd0fd2ba8aeafa406cc5ef26e714318148 100644 (file)
--- a/src/shared/xdynrec.pas
+++ b/src/shared/xdynrec.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
uses
SysUtils, Variants, Classes,
- xparser, xstreams, utils, hashtable, mempool;
+ {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
+ xparser, xstreams, utils, hashtable;
// ////////////////////////////////////////////////////////////////////////// //
TDynEBSList = specialize TSimpleList<TDynEBS>;
// this is base type for all scalars (and arrays)
- TDynField = class(TPoolObject)
+ TDynField = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
public
type
TType = (TBool, TChar, TByte, TUByte, TShort, TUShort, TInt, TUInt, TString, TPoint, TSize, TColor, TList, TTrigData);
// record, either with actual values, or with type definitions
- TDynRecord = class(TPoolObject)
+ TDynRecord = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
mOwner: TDynMapDef;
mId: AnsiString;
// bitset/enum definition
- TDynEBS = class(TPoolObject)
+ TDynEBS = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
mOwner: TDynMapDef;
mIsEnum: Boolean;
// parsed "mapdef.txt"
- TDynMapDef = class(TPoolObject)
+ TDynMapDef = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
public
recTypes: TDynRecList; // [0] is always header
trigTypes: TDynRecList; // trigdata
procedure xdynDumpProfiles ();
{$ENDIF}
+var
+ DynWarningCB: procedure (const msg: AnsiString; line, col: Integer) = nil;
implementation
+{$IF DEFINED(D2D_DYNREC_PROFILER)}
uses
- e_log
- {$IF DEFINED(D2D_DYNREC_PROFILER)},xprofiler{$ENDIF};
+ xprofiler;
+{$ENDIF}
// ////////////////////////////////////////////////////////////////////////// //
if (mType = TType.TList) then
begin
mRVal := TDynRecList.Create();
- mRHash := hashNewStrInt();
+ mRHash := THashStrInt.Create();
end;
end;
if (mRVal <> nil) then
begin
if (result.mRVal = nil) then result.mRVal := TDynRecList.Create(mRVal.count);
- if (result.mRHash = nil) then result.mRHash := hashNewStrInt();
+ if (result.mRHash = nil) then result.mRHash := THashStrInt.Create();
for rec in mRVal do result.addListItem(rec.clone(registerIn));
end;
result.mRecRef := mRecRef;
ahelp := '';
// field name
- fldname := pr.expectStrOrId();
+ fldname := pr.expectIdOrStr();
- while (pr.tokType <> pr.TTSemi) do
+ while (not pr.isDelim(';')) do
begin
if pr.eatId('type') then
begin
lebs := TDynField.TEBS.TRec;
end;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
// create field
mName := fldname;
edim: AnsiChar;
begin
if (pr.tokType = pr.TTEOF) then raise TDynParseException.Create(pr, 'field value expected');
- if (pr.tokType = pr.TTSemi) then raise TDynParseException.Create(pr, 'extra semicolon');
+ if (pr.isDelim(';')) then raise TDynParseException.Create(pr, 'extra semicolon');
// if this field should contain struct, convert type and parse struct
case mEBS of
TEBS.TNone: begin end;
// ugly hack. sorry.
if (mType = TType.TTrigData) then
begin
- pr.expectTT(pr.TTBegin);
- if (pr.tokType = pr.TTEnd) then
+ pr.expectDelim('{');
+ if (pr.eatDelim('}')) then
begin
// '{}'
mRecRef := nil;
- pr.expectTT(pr.TTEnd);
end
else
begin
mRecRef := rc;
end;
mDefined := true;
- pr.eatTT(pr.TTSemi); // hack: allow (but don't require) semicolon after inline records
+ pr.eatDelim(';'); // hack: allow (but don't require) semicolon after inline records
exit;
end;
// other record types
pr.expectId();
end;
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end
- else if (pr.tokType = pr.TTBegin) then
+ else if (pr.isDelim('{')) then
begin
//rec := mOwner.mOwner.recType[mEBSTypeName]; // find in mapdef
rec := nil;
begin
raise TDynParseException.CreateFmt(pr, 'duplicate record with id ''%s'' for field ''%s'' in record ''%s''', [rc.mId, mName, mOwner.mTypeName]);
end;
- pr.eatTT(pr.TTSemi); // hack: allow (but don't require) semicolon after inline records
+ pr.eatDelim(';'); // hack: allow (but don't require) semicolon after inline records
exit;
end;
- pr.expectTT(pr.TTBegin);
+ pr.expectDelim('{');
end;
TEBS.TEnum:
begin
mSVal := tk;
//writeln('ENUM ', mEBSName, '; element <', mSVal, '> with value ', mIVal);
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TEBS.TBitSet:
pr.skipToken(); // plus or pipe
end;
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
else raise TDynParseException.Create(pr, 'ketmar forgot to handle some EBS type');
else if pr.eatId('false') or pr.eatId('ona') or pr.eatId('no') then mIVal := 0
else raise TDynParseException.CreateFmt(pr, 'invalid bool value for field ''%s''', [mName]);
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TChar:
if (Length(mSVal) > mMaxDim) then raise TDynParseException.CreateFmt(pr, 'invalid string size for field ''%s''', [mName]);
end;
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TByte:
begin
parseInt(-128, 127);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TUByte:
begin
parseInt(0, 255);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TShort:
begin
parseInt(-32768, 32768);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TUShort:
begin
parseInt(0, 65535);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TInt:
begin
parseInt(Integer($80000000), $7fffffff);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TUInt:
begin
parseInt(0, $7fffffff); //FIXME
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TString:
begin
mSVal := pr.expectStr(true);
mDefined := true;
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TPoint,
end;
mDefined := true;
pr.expectDelim(edim);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TColor:
end;
mDefined := true;
pr.expectDelim(edim);
- pr.expectTT(pr.TTSemi);
+ pr.expectDelim(';');
exit;
end;
TType.TList:
if (fld.mRVal = nil) then
begin
fld.mRVal := TDynRecList.Create();
- fld.mRHash := hashNewStrInt();
+ fld.mRHash := THashStrInt.Create();
end;
result := fld.addListItem(rc);
end;
begin
while true do
begin
- while pr.eatTT(pr.TTComma) do begin end;
+ while (pr.eatDelim(',')) do begin end;
if pr.eatDelim(')') then break;
tdn := pr.expectId();
if isForTrig[tdn] then raise TDynParseException.CreateFmt(pr, 'duplicate trigdata ''%s'' trigtype ''%s''', [mTypeName, tdn]);
end
else
begin
- mTypeName := pr.expectStrOrId();
- while (pr.tokType <> pr.TTBegin) do
+ mTypeName := pr.expectIdOrStr();
+ while (not pr.isDelim('{')) do
begin
if pr.eatId('header') then begin mHeader := true; continue; end;
if pr.eatId('size') then
end;
end;
- pr.expectTT(pr.TTBegin);
+ pr.expectDelim('{');
// load fields
- while (pr.tokType <> pr.TTEnd) do
+ while (not pr.isDelim('}')) do
begin
fld := TDynField.Create(pr);
// append
end;
// done with field
end;
- pr.expectTT(pr.TTEnd);
+ pr.expectDelim('}');
end;
rt := findRecordByTypeId(fld.mEBSTypeName, fld.mRecRefId);
if (rt = nil) then
begin
- e_LogWritefln('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%s''', [rec.mTypeName, rec.mId, fld.mEBSTypeName, fld.mRecRefId], MSG_WARNING);
+ if assigned(DynWarningCB) then
+ begin
+ DynWarningCB(formatstrf('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%s''', [rec.mTypeName, rec.mId, fld.mEBSTypeName, fld.mRecRefId]), -1, -1);
+ end;
//raise TDynRecException.CreateFmt('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%s''', [rec.mName, rec.mId, fld.mEBSTypeName, fld.mRecRefId]);
end;
//writeln(' ', rec.mName, '.', rec.mId, ':', fld.mName, ' -> ', rt.mName, '.', rt.mId, ' (', fld.mEBSTypeName, '.', fld.mRecRefId, ')');
end;
//writeln('parsing record <', mName, '>');
- if not beginEaten then pr.expectTT(pr.TTBegin);
- while (pr.tokType <> pr.TTEnd) do
+ if not beginEaten then pr.expectDelim('{');
+ while (not pr.isDelim('}')) do
begin
if (pr.tokType <> pr.TTId) then raise TDynParseException.Create(pr, 'identifier expected');
//writeln('<', mName, '.', pr.tokStr, '>');
// something is wrong
raise TDynParseException.CreateFmt(pr, 'unknown field ''%s'' in record ''%s''', [pr.tokStr, mTypeName]);
end;
- pr.expectTT(pr.TTEnd);
+ pr.expectDelim('}');
if mHeader then
begin
mTypeName := pr.expectId();
mMaxVal := Integer($80000000);
if mIsEnum then cv := 0 else cv := 1;
- while (pr.tokType <> pr.TTBegin) do
+ while (not pr.isDelim('{')) do
begin
if pr.eatId('tip') then
begin
end;
break;
end;
- pr.expectTT(pr.TTBegin);
- while (pr.tokType <> pr.TTEnd) do
+ pr.expectDelim('{');
+ while (not pr.isDelim('}')) do
begin
idname := pr.expectId();
for f := 0 to High(mIds) do
if mIsEnum then Inc(cv) else cv := cv shl 1;
end;
end;
- if (pr.tokType = pr.TTEnd) then break;
- pr.expectTT(pr.TTComma);
- while pr.eatTT(pr.TTComma) do begin end;
+ if (pr.isDelim('}')) then break;
+ pr.expectDelim(',');
+ while (pr.eatDelim(',')) do begin end;
end;
- pr.expectTT(pr.TTEnd);
+ pr.expectDelim('}');
// add max field
if (Length(mMaxName) > 0) then
begin