@@ -1405,6 +1405,7 @@ class ts_EventHandler : StaticEventHandler
14051405
14061406 Array<string> disabledClasses;
14071407 mDisabledViewsCvar.getString().split(disabledClasses, ",", TOK_SkipEmpty);
1408+ applyConfiguration("tsView_", disabledClasses);
14081409 int disabledClassesSize = disabledClasses.size();
14091410
14101411 int viewsCount = mViews.size();
@@ -1447,6 +1448,7 @@ class ts_EventHandler : StaticEventHandler
14471448 {
14481449 Array<string> disabledClasses;
14491450 mDisabledFindersCvar.getString().split(disabledClasses, ",", TOK_SkipEmpty);
1451+ applyConfiguration("tsFinder_", disabledClasses);
14501452 int disabledClassesSize = disabledClasses.size();
14511453
14521454 int findersCount = mFinders.size();
@@ -1468,6 +1470,7 @@ class ts_EventHandler : StaticEventHandler
14681470
14691471 Array<string> disabledClasses;
14701472 mDisabledFiltersCvar.getString().split(disabledClasses, ",", TOK_SkipEmpty);
1473+ applyConfiguration("tsFilter_", disabledClasses);
14711474 int disabledClassesSize = disabledClasses.size();
14721475
14731476 for (int targetIndex = 0; targetIndex < targetsCount; ++targetIndex)
@@ -1524,6 +1527,7 @@ class ts_EventHandler : StaticEventHandler
15241527
15251528 Array<string> disabledClasses;
15261529 mDisabledGettersCvar.getString().split(disabledClasses, ",", TOK_SkipEmpty);
1530+ applyConfiguration("tsGetter_", disabledClasses);
15271531 int disabledClassesSize = disabledClasses.size();
15281532
15291533 int gettersCount = mGetters.size();
@@ -2338,10 +2342,13 @@ class ts_ClassToggles : OptionMenu
23382342 string classPrefix,
23392343 string disabledClassesCvarName)
23402344 {
2345+ let eventHandler = ts_EventHandler.getInstance();
2346+
23412347 mDesc.mItems.clear();
23422348 int classesCount = classes.size();
23432349 for (int i = 0; i < classesCount; ++i)
23442350 {
2351+ if (eventHandler.isInConfig(classPrefix .. classes[i])) continue;
23452352 let toggle = new("ts_ClassToggle");
23462353 toggle.initialize(classes[i], classPrefix, disabledClassesCvarName);
23472354 mDesc.mItems.push(toggle);
@@ -2565,6 +2572,112 @@ class ts_GettersOrderElement : OptionMenuItemCommand
25652572}
25662573#+end_src
25672574
2575+ *** Configuration
2576+
2577+ Configuration is a way to customize how TargetSpy processes finders, filters, getters
2578+ and views. By default these classes are enabled or disabled by user choice.
2579+ Configuration can force them to be on or off. If a class is forced on, it is always
2580+ active and hidden from option menus. If a class is forced off, it is always disabled
2581+ and hidden from option menus.
2582+
2583+ Several configurations may be loaded at once. If more than one configuration
2584+ configures a class, the last loaded configuration wins.
2585+
2586+ Configuration is in JSON object format. Key is full class name, value is "off", "on",
2587+ or "user". "user" can be used to override previous configuration.
2588+
2589+ Example:
2590+
2591+ #+begin_src c :noweb-ref zscript-test
2592+
2593+ class tsFilter_Abc : Actor
2594+ {
2595+ static bool isAllowed(Actor anActor)
2596+ {
2597+ return true;
2598+ }
2599+ }
2600+
2601+ class tsGetter_Def : Actor
2602+ {
2603+ static int, string, int, int makeInformation(Actor anActor)
2604+ {
2605+ return ts_Kind.PlainText, "Def", 0, 0;
2606+ }
2607+ }
2608+ #+end_src
2609+
2610+ #+begin_src js :tangle ../build/TargetSpyTest/ts_config.json
2611+ {
2612+ "tsFilter_Abc": "on",
2613+ "tsGetter_Def": "off",
2614+ "tsGetter_Health": "user"
2615+ }
2616+ #+end_src
2617+
2618+ **** Implementation
2619+
2620+ #+begin_src c :noweb-ref ts_EventHandler.onRegister
2621+
2622+ collectConfigurations();
2623+ #+end_src
2624+
2625+ #+begin_src c :noweb-ref ts_EventHandler.extensions
2626+
2627+ clearscope bool isInConfig(string className)
2628+ {
2629+ return mConfiguration.checkKey(className);
2630+ }
2631+
2632+ private void collectConfigurations()
2633+ {
2634+ string lumpName = "ts_config";
2635+
2636+ for (int i = Wads.findLump(lumpName);
2637+ i != -1;
2638+ i = Wads.findLump(lumpName, i + 1))
2639+ {
2640+ let configuration = Dictionary.fromString(Wads.readLump(i));
2641+ let iterator = DictionaryIterator.create(configuration);
2642+
2643+ while (iterator.next())
2644+ {
2645+ string key = iterator.key();
2646+ string value = iterator.value().makeLower();
2647+
2648+ if (value == "on") mConfiguration.insert(key, 1);
2649+ else if (value == "off") mConfiguration.insert(key, 0);
2650+ else if (value == "user") mConfiguration.remove(key);
2651+ }
2652+ }
2653+ }
2654+
2655+ private clearscope void applyConfiguration(string prefix,
2656+ out Array<string> disabledClasses)
2657+ {
2658+ foreach (className, isEnabled : mConfiguration)
2659+ {
2660+ if (className.left(prefix.length()) != prefix) continue;
2661+
2662+ string shortClassName = ts_Classes.shorten(className);
2663+ int index = disabledClasses.find(shortClassName);
2664+
2665+ if (isEnabled)
2666+ {
2667+ if (index != disabledClasses.size())
2668+ disabledClasses.delete(index);
2669+ }
2670+ else
2671+ {
2672+ if (index == disabledClasses.size())
2673+ disabledClasses.push(shortClassName);
2674+ }
2675+ }
2676+ }
2677+
2678+ private Map<string, int> mConfiguration;
2679+ #+end_src
2680+
25682681* Project setup
25692682
25702683#+begin_src c :tangle ../build/TargetSpy/mapinfo.txt
@@ -2586,6 +2699,13 @@ version 4.14.3
25862699#include "zscript/ts_libeye.zs"
25872700#+end_src
25882701
2702+ #+begin_src c :tangle ../build/TargetSpyTest/zscript.zs
2703+
2704+ version 4.14.3
2705+
2706+ <<zscript-test>>
2707+ #+end_src
2708+
25892709[[file:../modules/PlainTranslator.org][PlainTranslator]]
25902710
25912711Translatable strings:
0 commit comments