From edd1359010ce32d5ff6a3b77fcb6bbe7e21b5703 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Sun, 13 Feb 2022 21:13:36 +0100 Subject: Update to map based DTMenu --- System.c4g/DTArrays.c | 3 +- System.c4g/DTCallback.c | 35 +++++++---- System.c4g/DTScopedVars.c | 7 +++ System.c4g/DTUtility.c | 157 +++++++++++++++++++++++++++++++++------------- 4 files changed, 146 insertions(+), 56 deletions(-) (limited to 'System.c4g') diff --git a/System.c4g/DTArrays.c b/System.c4g/DTArrays.c index 0b78ef4..82fe51d 100644 --- a/System.c4g/DTArrays.c +++ b/System.c4g/DTArrays.c @@ -36,9 +36,10 @@ global func ArrayInsert(array& arr, int index, value) arr[index] = value; } +// only here for backwards compatibility; use arr[] = value directly global func ArrayAppend(array& arr, value) { - arr[GetLength(arr)] = value; + arr[] = value; } global func ArrayAppendArray(array& arr, array append) diff --git a/System.c4g/DTCallback.c b/System.c4g/DTCallback.c index 91730d2..58f6403 100644 --- a/System.c4g/DTCallback.c +++ b/System.c4g/DTCallback.c @@ -1,5 +1,5 @@ /*-- Extensible callback system --*/ -#strict 2 +#strict 3 static const CallbackTarget_Bind = -1; static const CallbackTarget_Global = -2; @@ -9,9 +9,9 @@ static const CallbackTarget_Scenario = -3; global func GlobalCallback(string name) { return [CallbackTarget_Global, name]; } global func ScenarioCallback(string name) { return [CallbackTarget_Scenario, name]; } -global func ObjectCallback(string name, bool fast, object target) { return [target || this || FatalError("ObjectCallback without target object"), name, fast]; } -global func DefinitionCallback(string name, bool fast, id target) { return [target || GetID() || FatalError("DefinitionCallback without target definition"), name, fast]; } -global func Callback(string name, target) { return [target || this || GetID() || CallbackTarget_Global, name]; } +global func ObjectCallback(string name, bool fast, object target) { return [target ?? this ?? FatalError("ObjectCallback without target object"), name, fast]; } +global func DefinitionCallback(string name, bool fast, id target) { return [target ?? GetID() ?? FatalError("DefinitionCallback without target definition"), name, fast]; } +global func Callback(string name, target) { return [target ?? this ?? GetID() ?? CallbackTarget_Global, name]; } global func BindCallback(callback, array binding) { return [CallbackTarget_Bind, callback, binding]; } static const BindCallback_Bind_Value = -1; @@ -58,13 +58,24 @@ global func CallA(callback, args, bool safe, array refs) return _inherited(callback, args, ...); } + args ??= []; + var i = GetLength(args) - 1; + for (; i >= 0; --i) + { + if (args[i] != nil) + { + break; + } + } + SetLength(args, i + 1); + var target = callback[0], function = callback[1]; if((GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID) && GetLength(callback) == 3 && callback[2] && (!refs || refs == []) && GetLength(args) <= 8) // fast callback { if(GetType(target) == C4V_C4Object) { - return ObjectCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); + return PrivateCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); } else if(GetType(target) == C4V_C4ID) { @@ -95,15 +106,15 @@ global func CallA(callback, args, bool safe, array refs) { if(pos > 0) { - argsStr = Format("%s, ", argsStr); + argsStr ..= ", "; } if(refs[pos]) { - argsStr = Format("%sScopedVar(%s)", argsStr, Serialize(arg)); + argsStr ..= Format("ScopedVar(%s)", Serialize(arg)); } else { - argsStr = Format("%s%s", argsStr, Serialize(arg)); + argsStr ..= Serialize(arg); } ++pos; } @@ -147,7 +158,7 @@ global func BindArgs_ArgumentArrayPart(array binding, array args, bool safe) } else { - return 0; + return nil; } } return ret; @@ -223,9 +234,9 @@ global func BindArgs(array binding, array args, bool safe, array& refs) global func GlobalEval(string code) { - var effect = AddEffect("IntGlobalEval", 0, 1); - var ret = EffectCall(0, effect, "Eval", code); - RemoveEffect(0, 0, effect); + var effect = AddEffect("IntGlobalEval", nil, 1); + var ret = EffectCall(nil, effect, "Eval", code); + RemoveEffect(nil, nil, effect); return ret; } diff --git a/System.c4g/DTScopedVars.c b/System.c4g/DTScopedVars.c index 0cde670..3165553 100644 --- a/System.c4g/DTScopedVars.c +++ b/System.c4g/DTScopedVars.c @@ -4,10 +4,12 @@ static const ScopedVar_Global = 1; static const ScopedVar_Local = 2; static const ScopedVar_ArrayIndex = 3; +static const ScopedVar_MapIndex = 4; global func GlobalVar(name) { return [ScopedVar_Global, name]; } global func LocalVar(name, object target) { return [ScopedVar_Local, name, target || this]; } global func ArrayVar(index, array scopedVar) { return [ScopedVar_ArrayIndex, scopedVar, index]; } +global func MapVar(index, array scopedVar) { return [ScopedVar_MapIndex, scopedVar, index]; } global func &ScopedVar(array variable) { @@ -46,6 +48,11 @@ global func &ScopedVar(array variable) } return ScopedVar(variable[1])[index]; } + else if(variable[0] == ScopedVar_MapIndex) + { + var index = variable[2]; + return ScopedVar(variable[1])[index]; + } else { if(this) diff --git a/System.c4g/DTUtility.c b/System.c4g/DTUtility.c index d491567..752000b 100644 --- a/System.c4g/DTUtility.c +++ b/System.c4g/DTUtility.c @@ -1,4 +1,4 @@ -#strict 2 +#strict 3 global func Isolate(object obj) // Puts the object in its own layer to prevent interaction { @@ -19,7 +19,47 @@ global func GetIndexOf2(val, array arr) // Because GetIndexOf doesn't find Forma global func Serialize(value) { - if(GetType(value) == C4V_Array) + if(value == nil) return "nil"; + if(GetType(value) == C4V_Map) + { + var nonIdentifierKeyInits = []; + var ret = "{"; + + var first = true; + for(var k, v in value) + { + if(GetType(k) == C4V_String) + { + if(first) + { + first = false; + } + else + { + ret ..= ","; + } + ret ..= Serialize(k) .. "=" .. Serialize(v); + } + else + { + nonIdentifierKeyInits[] = k; + nonIdentifierKeyInits[] = v; + } + } + + ret ..= "}"; + + if(GetLength(nonIdentifierKeyInits) > 0) + { + if(first) + { + return "InitMap(" .. Serialize(nonIdentifierKeyInits) .. ")"; + } + return "Extend(" .. ret .. ",InitMap(" .. Serialize(nonIdentifierKeyInits) .. "))"; + } + return ret; + } + else if(GetType(value) == C4V_Array) { var first = true; var ret = "["; @@ -31,16 +71,16 @@ global func Serialize(value) } else { - ret = Format("%s,", ret); + ret ..= ","; } - ret = Format("%s%s", ret, Serialize(val)); + ret ..= Serialize(val); } - return Format("%s]", ret); + return ret .. "]"; } else if(GetType(value) == C4V_Bool) if(value) return "true"; else return "false"; else if(GetType(value) == C4V_C4ID) return Format("%i", value); else if(GetType(value) == C4V_C4Object) return Format("Object(%d)", ObjectNumber(value)); - else if(GetType(value) == C4V_Int || GetType(value) == C4V_Any) return Format("%d", value); + else if(GetType(value) == C4V_Int) return Format("%d", value); else if(GetType(value) == C4V_String) return Format("\"%s\"", EscapeString(value)); } @@ -49,18 +89,18 @@ global func EscapeString(string value) var ret = ""; for(var i = 0; i < GetLength(value); ++i) { - var c = GetChar(value, i); - if(c == 34) // " + var c = value[i]; + if(c == "\"") { - ret = Format("%s\\\"", ret); + ret ..= "\\\""; } - else if(c == 92) // \ + else if(c == "\\") { - ret = Format("%s\\\\", ret); + ret ..= "\\\\"; } else { - ret = Format("%s%c", ret, c); + ret ..= c; } } return ret; @@ -73,7 +113,7 @@ global func CreateEnum(string prefix, array enum) for(var i = 0; i < GetLength(enum); ++i) { - log = Format("%s%cstatic const %s%s = %d;", log, 10, prefix, enum[i], i); + log ..= Format("%cstatic const %s%s = %d;", 10, prefix, enum[i], i); if(switch == "") { @@ -81,7 +121,7 @@ global func CreateEnum(string prefix, array enum) } else { - switch = Format("%selse if(switchval == %s%s)%c{%c%c}%c", switch, prefix, enum[i], 10, 10, 10, 10); + switch ..= Format("else if(switchval == %s%s)%c{%c%c}%c", prefix, enum[i], 10, 10, 10, 10); } } @@ -100,16 +140,13 @@ global func CreateBitField(string prefix, array flags) for(var i = 0, j = 1; i < GetLength(flags); ++i) { - log = Format("%s%cstatic const %s%s = %d;", log, 10, prefix, flags[i], j); + log ..= Format("%cstatic const %s%s = %d;", 10, prefix, flags[i], j); j = j << 1; } Log("%s%c%c", log, 10, 10); } -// pos >= 0 => begin at pos | pos < 0 => begin at GetLength(string) - pos -// count = 0 => replace all | count > 0 replace a maximum of count occurences from starting from pos - global func Lowercase(int c) { if((c >= 65 && c <= 90) || (c >= 192 && c <= 214) || (c >= 216 && c <= 221)) return c + 32; @@ -131,7 +168,7 @@ global func MultiStringLowercase(array strings) var ret = []; for(var string in strings) { - ret[GetLength(ret)] = StringLowercase(string); + ret[] = StringLowercase(string); } return ret; } @@ -148,12 +185,14 @@ global func StringConcatenate(array strings) for(var i = 1; i < GetLength(strings); ++i) { - ret = Format("%s%s", ret, strings[i]); + ret ..= strings[i]; } return ret; } +// pos >= 0 => begin at pos | pos < 0 => begin at GetLength(string) - pos +// count = 0 => replace all | count > 0 replace a maximum of count occurences starting from pos global func MultiStringReplace(find, strings, replace, bool caseInsensitive, int count, int pos, int maxpos) { var returnString = false; @@ -195,7 +234,7 @@ global func StringReplace(string find, string string, string replace, bool caseI for(var i = 0; i < pos; ++i) { - ret = Format("%s%c", ret, GetChar(string, i)); + ret ..= string[i]; } var match = 0; @@ -204,12 +243,11 @@ global func StringReplace(string find, string string, string replace, bool caseI for(i = pos; i + GetLength(find) - match - 1 < maxpos && count != 0; ++i) { - var c = GetChar(string, i); - if(CaseInsensitive(c, !caseInsensitive) == CaseInsensitive(GetChar(find, match), !caseInsensitive)) + if(CaseInsensitive(GetChar(string, i), !caseInsensitive) == CaseInsensitive(GetChar(find, match), !caseInsensitive)) { if(++match == GetLength(find)) { - ret = StringConcatenate([ret, replace]); + ret ..= replace; match = 0; --count; } @@ -220,17 +258,17 @@ global func StringReplace(string find, string string, string replace, bool caseI { for(var j = i - match; j < i; ++j) { - ret = Format("%s%c", ret, GetChar(string, j)); + ret ..= string[j]; } } match = 0; - ret = Format("%s%c", ret, GetChar(string, i)); + ret ..= string[i]; } } for(i -= match; i < GetLength(string); ++i) { - ret = Format("%s%c", ret, GetChar(string, i)); + ret ..= string[i]; } return ret; @@ -241,7 +279,7 @@ global func StringReplaceMulti(string find, string string, array replace) var ret = []; for(var rep in replace) { - ret[GetLength(ret)] = StringReplace(find, string, rep); + ret[] = StringReplace(find, string, rep); } return ret; } @@ -289,7 +327,7 @@ global func GetIDsByName(string name, int category) // WARNING: desyncs between { if(GetName(0, id) == name) { - ret[GetLength(ret)] = id; + ret[] = id; } } return ret; @@ -300,10 +338,7 @@ global func ArrayConcatenate(array arrays) var ret = []; for(var arr in arrays) { - for(var val in arr) - { - ret[GetLength(ret)] = val; - } + ArrayAppendArray(ret, arr); } return ret; } @@ -318,7 +353,7 @@ global func SetPlrExtraDataString(int plr, string name, string data) if((i % 4) == 0 && i != 0) { - SetPlrExtraData(plr, Format("%s%d", name, i/4 - 1), part); + SetPlrExtraData(plr, name .. i/4 - 1, part); part = 0; } @@ -327,13 +362,13 @@ global func SetPlrExtraDataString(int plr, string name, string data) if(part != 0) { - SetPlrExtraData(plr, Format("%s%d", name, i/4), part); + SetPlrExtraData(plr, name .. i/4, part); } i = i/4 + 1; - while(GetPlrExtraData(plr, Format("%s%d", name, i))) + while(GetPlrExtraData(plr, name .. i)) { - SetPlrExtraData(plr, Format("%s%d", name, i++), 0); + SetPlrExtraData(plr, name .. i++, 0); } } @@ -343,7 +378,7 @@ global func GetPlrExtraDataString(int plr, string name) var part = true; for(var i = 0; part != 0; ++i) { - part = CastInt(GetPlrExtraData(plr, Format("%s%d", name, i))); + part = CastInt(GetPlrExtraData(plr, name .. i)); for(var j = 0; j < 4; ++j) { var c = (part >> (j * 8)) & 0xFF; @@ -377,7 +412,7 @@ global func GetPlrExtraDataArray(int plr, string name) global func SetPlrExtraDataIntArray(int plr, string name, array arr) { - var lengthName = Format("%sL", name); + var lengthName = name .. "L"; var oldLength = CastInt(GetPlrExtraData(plr, lengthName)); @@ -385,7 +420,7 @@ global func SetPlrExtraDataIntArray(int plr, string name, array arr) for(var i = 0; i < length; ++i) { - var partName = Format("%s%d", name, i); + var partName = name .. i; if(arr[i] != 0) { SetPlrExtraData(plr, partName, arr[i]); @@ -400,7 +435,7 @@ global func SetPlrExtraDataIntArray(int plr, string name, array arr) for(var i = length; i < oldLength; ++i) { - var partName = Format("%s%d", name, i); + var partName = name .. i; if(GetPlrExtraData(plr, partName) != 0) { SetPlrExtraData(plr, partName, 0); @@ -410,13 +445,13 @@ global func SetPlrExtraDataIntArray(int plr, string name, array arr) global func GetPlrExtraDataIntArray(int plr, string name) { - var length = CastInt(GetPlrExtraData(plr, Format("%sL", name))); + var length = CastInt(GetPlrExtraData(plr, name .. "L")); var ret = CreateArray(length); for(var i = 0; i < length; ++i) { - ret[i] = CastInt(GetPlrExtraData(plr, Format("%s%d", name, i))); + ret[i] = CastInt(GetPlrExtraData(plr, name .. i)); } return ret; @@ -815,3 +850,39 @@ global func GetPlayerByID(int id) return NO_OWNER; } + +global func Extend(map base, map extension, bool recursive) +{ + if(recursive) + { + for(var key, value in extension) + { + if(GetType(base[key]) == C4V_Map && GetType(value) == C4V_Map) + { + base[key] = Extend(base[key], value, true); + } + else + { + base[key] = value; + } + } + } + else + { + for(var key, value in extension) + { + base[key] = value; + } + } + return base; +} + +global func InitMap(array init) +{ + var ret = {}; + for(var i = 0; i < GetLength(init); i += 2) + { + ret[init[i]] = init[i + 1]; + } + return ret; +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf