From 8f33ebb3c0f0aac76c83a4c60801adde5417edfc Mon Sep 17 00:00:00 2001 From: Alex 'mcmonkey' Goodwin Date: Sat, 23 Oct 2021 03:47:11 -0700 Subject: [PATCH] additional perf tweaks --- .../denizencore/scripts/ScriptEntry.java | 76 ++++++++++--------- .../scripts/commands/BracedCommand.java | 56 ++++---------- .../scripts/commands/CommandExecutor.java | 4 - .../denizencore/tags/TagManager.java | 41 +++++----- .../denizencore/tags/core/QueueTagBase.java | 60 +++++---------- 5 files changed, 99 insertions(+), 138 deletions(-) diff --git a/src/main/java/com/denizenscript/denizencore/scripts/ScriptEntry.java b/src/main/java/com/denizenscript/denizencore/scripts/ScriptEntry.java index 346650f7..16fb44c1 100644 --- a/src/main/java/com/denizenscript/denizencore/scripts/ScriptEntry.java +++ b/src/main/java/com/denizenscript/denizencore/scripts/ScriptEntry.java @@ -24,7 +24,7 @@ * ScriptEntry contain information about a single entry from a dScript. It is used * by the CommandExecutor, among other parts of Denizen. */ -public class ScriptEntry implements Cloneable, Debuggable { +public class ScriptEntry implements Cloneable, Debuggable, Iterable { public static class ScriptEntryInternal { @@ -48,8 +48,6 @@ public static class ScriptEntryInternal { public boolean hasTags = false; - public int[] processArgs = null; - public List preprocArgs = null; public Object specialProcessedData = null; @@ -61,6 +59,8 @@ public static class ScriptEntryInternal { public boolean brokenArgs = false; public HashMap argPrefixMap = null; + + public ArgumentIterator argumentIterator = null; } public static class InternalArgument { @@ -71,6 +71,8 @@ public static class InternalArgument { public Argument aHArg = null; + public boolean shouldProcess = false; + public InternalArgument duplicate() { InternalArgument newArg = new InternalArgument(); newArg.prefix = prefix == null ? null : prefix.duplicate(); @@ -80,21 +82,44 @@ public InternalArgument duplicate() { } } - public List getProcessedArgs() { - for (Argument arg : aHArgs) { - arg.scriptEntry = this; - if (arg.object instanceof ElementTag && ((ElementTag) arg.object).isRawInput && arg.prefix == null) { - arg.fillStr(arg.object.toString()); - } - else { - arg.unsetValue(); + public static class ArgumentIterator implements Iterator { + + public ArgumentIterator(ScriptEntry entry) { + this.entry = entry; + } + + public ScriptEntry entry; + + public int index = 0; + + @Override + public boolean hasNext() { + return index < entry.internal.args_ref.size(); + } + + @Override + public Argument next() { + InternalArgument internalArg = entry.internal.args_ref.get(index++); + Argument arg = internalArg.aHArg; + arg.scriptEntry = entry; + if (internalArg.shouldProcess) { + TagManager.fillArgumentObjects(internalArg, arg, entry.context); + if (arg.object instanceof ElementTag && ((ElementTag) arg.object).isRawInput && arg.prefix == null) { + arg.fillStr(arg.object.toString()); + } + arg.canBeElement = arg.object instanceof ElementTag; } - arg.canBeElement = arg.object instanceof ElementTag; + return arg; } - return aHArgs; } - public List aHArgs; + @Override + public ArgumentIterator iterator() { + // NOTE: This relies strongly on the assumption of non-async execution for performance benefit. + internal.argumentIterator.index = 0; + internal.argumentIterator.entry = this; + return internal.argumentIterator; + } public ScriptEntryData entryData; @@ -133,14 +158,6 @@ public void setBracedSet(List set) { NULL_INTERNAL_ARGUMENT.value = TagManager.DEFAULT_PARSEABLE_EMPTY; } - public void generateAHArgs() { - for (int i : internal.processArgs) { - Argument aHArg = internal.args_ref.get(i).aHArg.clone(); - aHArg.scriptEntry = this; - aHArgs.set(i, aHArg); - } - } - @Override public ScriptEntry clone() { try { @@ -148,7 +165,6 @@ public ScriptEntry clone() { se.objects = new HashMap<>(8); se.entryData = entryData.clone(); se.entryData.scriptEntry = se; - se.aHArgs = new ArrayList<>(aHArgs); se.updateContext(); return se; } @@ -281,8 +297,6 @@ else if (internal.actualCommand != null) { nested_depth = 0; TagContext refContext = DenizenCore.getImplementation().getTagContext(this); internal.args_ref = new ArrayList<>(internal.pre_tagged_args.size()); - List tempProcessArgs = new ArrayList<>(internal.pre_tagged_args.size()); - aHArgs = new ArrayList<>(internal.pre_tagged_args.size()); for (int i = 0; i < internal.pre_tagged_args.size(); i++) { String arg = internal.pre_tagged_args.get(i); if (arg.equals("{")) { @@ -316,23 +330,16 @@ else if (internal.actualCommand != null) { } } crunchInto(argVal, arg, refContext); - if (argVal.value.hasTag || argVal.prefix != null) { - tempProcessArgs.add(aHArgs.size()); + if ((argVal.value.hasTag || argVal.prefix != null) && (internal.actualCommand == null || internal.actualCommand.shouldPreParse())) { + argVal.shouldProcess = true; } - aHArgs.add(argVal.aHArg); - } - internal.processArgs = new int[tempProcessArgs.size()]; - for (int i = 0; i < tempProcessArgs.size(); i++) { - internal.processArgs[i] = tempProcessArgs.get(i); } } else { internal.pre_tagged_args = new ArrayList<>(); internal.preprocArgs = new ArrayList<>(); internal.pre_tagged_args = new ArrayList<>(); - internal.processArgs = new int[0]; internal.args_ref = new ArrayList<>(); - aHArgs = new ArrayList<>(); } if (internal.actualCommand != null) { int argCount = getOriginalArguments().size(); @@ -347,6 +354,7 @@ else if (internal.actualCommand != null) { else { internal.actualCommand = CommandRegistry.debugInvalidCommand; } + internal.argumentIterator = new ArgumentIterator(this); } /** diff --git a/src/main/java/com/denizenscript/denizencore/scripts/commands/BracedCommand.java b/src/main/java/com/denizenscript/denizencore/scripts/commands/BracedCommand.java index a1af881c..8d7a2470 100644 --- a/src/main/java/com/denizenscript/denizencore/scripts/commands/BracedCommand.java +++ b/src/main/java/com/denizenscript/denizencore/scripts/commands/BracedCommand.java @@ -45,23 +45,16 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea if (scriptEntry == null) { return null; } - - boolean hyperdebug = Debug.verbose; - - // And a place to store all the final braces... List bracedSections; - List entryBracedSet = scriptEntry.getBracedSet(); if (entryBracedSet != null) { if (!duplicate) { return entryBracedSet; } - List res = new ArrayList<>(entryBracedSet); + List res = new ArrayList<>(entryBracedSet.size()); try { - for (int i = 0; i < res.size(); i++) { + for (BracedData bd : entryBracedSet) { BracedData newbd = new BracedData(); - BracedData bd = res.get(i); - res.set(i, newbd); newbd.key = bd.key; newbd.value = new ArrayList<>(bd.value.size()); for (ScriptEntry sEntry : bd.value) { @@ -74,6 +67,7 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea Debug.echoDebug(scriptEntry, "Wrangling braced command args: " + bd.key); } newbd.args = bd.args; + res.add(newbd); } } catch (Exception e) { @@ -81,7 +75,6 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea } return res; } - if (scriptEntry.getInsideList() != null) { List contents = scriptEntry.getInsideList(); List entries = ScriptBuilder.buildScriptEntries(contents, @@ -96,42 +89,26 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea return getBracedCommands(scriptEntry); } bracedSections = new ArrayList<>(); - // We need a place to store the commands being built at... TreeMap> commandList = new TreeMap<>(); - int bracesEntered = 0; boolean newCommand = true; boolean waitingForDash = false; - // Inject the scriptEntry into the front of the queue, otherwise it doesn't exist //scriptEntry.getResidingQueue().injectEntry(scriptEntry, 0); // Send info to debug - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Starting getBracedCommands..."); - } - - // If the specified amount of possible entries is less than the queue size, print that instead - //if (hyperdebug) dB.echoDebug(scriptEntry, "...with queue size: " + scriptEntry.getResidingQueue().getQueueSize()); - if (hyperdebug) { Debug.echoDebug(scriptEntry, "...with first command name: " + scriptEntry.getCommandName()); - } - if (hyperdebug) { Debug.echoDebug(scriptEntry, "...with first command arguments: " + scriptEntry.getOriginalArguments()); - } - - if (hyperdebug) { Debug.echoDebug(scriptEntry, "Entry found: " + scriptEntry.getCommandName()); } - // Loop through the arguments of each entry List argList = scriptEntry.getOriginalArguments(); - // Set the variable to use for naming braced command lists; the first should be the command name String bracesName = scriptEntry.getCommandName().toUpperCase(); ArrayList bracesArgs = new ArrayList<>(); bracesArgs.add(bracesName); - int startArg = -1; for (int i = 0; i < argList.size(); i++) { String arg = argList.get(i); @@ -140,24 +117,19 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea break; } } - if (startArg == -1) { return null; } - if (scriptEntry.getScript() != null) { // Ex command is temporarily allowed to bypass, to avoid annoying user testing Deprecations.oldBraceSyntax.warn(scriptEntry); } - int tStart = -1; int tEnd = -1; - for (int i = startArg; i < argList.size(); i++) { String arg = argList.get(i); - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Arg found: " + arg); } - // Listen for opened braces if (arg.equals("{")) { bracesEntered++; @@ -169,7 +141,7 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea } newCommand = false; waitingForDash = bracesEntered == 1; - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Opened brace; " + bracesEntered + " now"); } if (bracesEntered > 1) { @@ -181,7 +153,7 @@ public static List getBracedCommands(ScriptEntry scriptEntry, boolea else if (arg.equals("}")) { bracesEntered--; newCommand = false; - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Closed brace; " + bracesEntered + " now"); } if (bracesEntered > 0) { @@ -197,13 +169,13 @@ else if (arg.equals("}")) { ArrayList bracesSection = new ArrayList<>(); for (ArrayList command : commandList.values()) { if (command.isEmpty()) { - if (hyperdebug) { + if (Debug.verbose) { Debug.echoError(scriptEntry.getResidingQueue(), "Empty command?"); } continue; } String cmd = command.get(0); - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Calculating " + cmd); } command.remove(0); @@ -220,11 +192,11 @@ else if (arg.equals("}")) { newEntry.internal.originalLine = newEntry.toString(); bracesSection.add(newEntry); bracesSection.get(bracesSection.size() - 1).entryData.transferDataFrom(scriptEntry.entryData); - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Command added: " + cmd + ", with " + args.length + " arguments"); } } - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Adding section " + bracesName + " with " + tStart + " to " + tEnd); } bd.args = bracesArgs; @@ -245,7 +217,7 @@ else if (newCommand && bracesEntered == 1) { commandList.put(commandList.size(), new ArrayList<>()); commandList.get(commandList.lastKey()).add(arg); newCommand = false; - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Treating as new command"); } } @@ -254,7 +226,7 @@ else if (newCommand && bracesEntered == 1) { else if (arg.equals("-") && bracesEntered == 1) { newCommand = true; waitingForDash = false; - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Assuming following is a new command"); } } @@ -273,7 +245,7 @@ else if (bracesEntered == 0) { } newCommand = false; commandList.get(commandList.lastKey()).add(arg); - if (hyperdebug) { + if (Debug.verbose) { Debug.echoDebug(scriptEntry, "Adding to the command"); } } diff --git a/src/main/java/com/denizenscript/denizencore/scripts/commands/CommandExecutor.java b/src/main/java/com/denizenscript/denizencore/scripts/commands/CommandExecutor.java index 477180ff..a42ba161 100644 --- a/src/main/java/com/denizenscript/denizencore/scripts/commands/CommandExecutor.java +++ b/src/main/java/com/denizenscript/denizencore/scripts/commands/CommandExecutor.java @@ -88,7 +88,6 @@ public boolean execute(ScriptEntry scriptEntry) { } String saveName = null; try { - scriptEntry.generateAHArgs(); TagContext context = scriptEntry.getContext(); for (Argument arg : scriptEntry.internal.preprocArgs) { if (DenizenCore.getImplementation().handleCustomArgs(scriptEntry, arg, false)) { @@ -113,9 +112,6 @@ else if (arg.matchesPrefix("save")) { } } } - if (scriptEntry.internal.actualCommand.shouldPreParse()) { - TagManager.fillArgumentsObjects(scriptEntry.internal.args_ref, scriptEntry.aHArgs, context, scriptEntry.internal.processArgs); - } command.parseArgs(scriptEntry); command.execute(scriptEntry); if (saveName != null) { diff --git a/src/main/java/com/denizenscript/denizencore/tags/TagManager.java b/src/main/java/com/denizenscript/denizencore/tags/TagManager.java index 1bf4046e..737591b2 100644 --- a/src/main/java/com/denizenscript/denizencore/tags/TagManager.java +++ b/src/main/java/com/denizenscript/denizencore/tags/TagManager.java @@ -237,12 +237,17 @@ public static class ParseableTag { public List pieces; + public ParseableTagPiece singleTag; + public boolean hasTag; public final ObjectTag parse(TagContext context) { if (rawElement != null) { return rawElement; } + else if (singleTag != null) { + return readSingleTagObject(singleTag, context); + } return parseChainObject(pieces, context); } @@ -391,6 +396,9 @@ public static ParseableTag parseTextToTag(String arg, TagContext context) { ParseableTag result = new ParseableTag(); result.pieces = pieces; result.hasTag = true; + if (pieces.size() == 1 && pieces.get(0).isTag) { + result.singleTag = pieces.get(0); + } return result; } @@ -426,27 +434,22 @@ else if (arg.charAt(i) == '>') { holder[0] = -1; } - public static void fillArgumentsObjects(List pieceHelp, List aHArgs, TagContext context, int[] targets) { - if (Debug.verbose) { - Debug.log("Fill argument objects: " + aHArgs + ", " + targets.length + "..."); - } - for (int argId : targets) { - Argument aharg = aHArgs.get(argId); - ScriptEntry.InternalArgument piece = pieceHelp.get(argId); - if (piece.prefix != null) { - if (piece.prefix.value.hasTag) { - aharg.prefix = piece.prefix.value.parse(context).toString(); - aharg.lower_prefix = CoreUtilities.toLowerCase(aharg.prefix); - } - if (piece.value.hasTag) { - aharg.object = piece.value.parse(context); - } + public static void fillArgumentObjects(ScriptEntry.InternalArgument arg, Argument ahArg, TagContext context) { + ahArg.lower_value = null; + ahArg.unsetValue(); + if (arg.prefix != null) { + if (arg.prefix.value.hasTag) { + ahArg.prefix = arg.prefix.value.parse(context).toString(); + ahArg.lower_prefix = CoreUtilities.toLowerCase(ahArg.prefix); } - else { - aharg.object = piece.value.parse(context); - aharg.prefix = null; - aharg.lower_prefix = null; + if (arg.value.hasTag) { + ahArg.object = arg.value.parse(context); } } + else { + ahArg.object = arg.value.parse(context); + ahArg.prefix = null; + ahArg.lower_prefix = null; + } } } diff --git a/src/main/java/com/denizenscript/denizencore/tags/core/QueueTagBase.java b/src/main/java/com/denizenscript/denizencore/tags/core/QueueTagBase.java index 0ea26c9c..21bcb8fd 100644 --- a/src/main/java/com/denizenscript/denizencore/tags/core/QueueTagBase.java +++ b/src/main/java/com/denizenscript/denizencore/tags/core/QueueTagBase.java @@ -31,64 +31,46 @@ public void run(ReplaceableTagEvent event) { }, "queue"); } - ////////// - // ReplaceableTagEvent handler - //////// - public void queueTag(ReplaceableTagEvent event) { - if (!event.matches("queue")) { return; } - - // Handle tags - Attribute attribute = event.getAttributes(); - - if (attribute.hasContext(1)) { - QueueTag queue = attribute.contextAsType(1, QueueTag.class); - if (queue == null) { - return; - } - event.setReplacedObject(CoreUtilities.autoAttrib(queue, event.getAttributes().fulfill(1))); - return; - } - - attribute = attribute.fulfill(1); - - // Otherwise, try to use queue in a static manner. - - if (attribute.startsWith("exists") + // Historical queue.xxx tags: + if (attribute.startsWith("exists", 2) && attribute.hasContext(1)) { Deprecations.queueExists.warn(attribute.context); - event.setReplacedObject(CoreUtilities.autoAttrib(new ElementTag(ScriptQueue.queueExists(attribute.getContext(1))), - attribute.fulfill(1))); + event.setReplacedObject(CoreUtilities.autoAttrib(new ElementTag(ScriptQueue.queueExists(attribute.getContext(2))), attribute.fulfill(2))); return; } - - if (attribute.startsWith("stats")) { + if (attribute.startsWith("stats", 2)) { Deprecations.queueStats.warn(attribute.context); - event.setReplacedObject(CoreUtilities.autoAttrib(new ElementTag(ScriptQueue.getStats()), - attribute.fulfill(1))); + event.setReplacedObject(CoreUtilities.autoAttrib(new ElementTag(ScriptQueue.getStats()), attribute.fulfill(2))); return; } - - if (attribute.startsWith("list")) { + if (attribute.startsWith("list", 2)) { Deprecations.queueStats.warn(attribute.context); ListTag list = new ListTag(); for (ScriptQueue queue : ScriptQueue.getQueues()) { list.addObject(new QueueTag(queue)); } - event.setReplacedObject(CoreUtilities.autoAttrib(list, - attribute.fulfill(1))); + event.setReplacedObject(CoreUtilities.autoAttrib(list, attribute.fulfill(2))); return; } - - // Else, - // Use current queue - - event.setReplacedObject(CoreUtilities.autoAttrib(new QueueTag(event.getScriptEntry().getResidingQueue()), - attribute)); + // Modern tag: + if (attribute.hasContext(1)) { + QueueTag queue = attribute.contextAsType(1, QueueTag.class); + if (queue == null) { + return; + } + event.setReplacedObject(CoreUtilities.autoAttrib(queue, event.getAttributes().fulfill(1))); + return; + } + ScriptQueue queue = event.getScriptEntry().getResidingQueue(); + if (queue == null) { + return; + } + event.setReplacedObject(CoreUtilities.autoAttrib(new QueueTag(event.getScriptEntry().getResidingQueue()), attribute.fulfill(1))); } }