Skip to content

Commit

Permalink
Add experimental new version of Foreach
Browse files Browse the repository at this point in the history
Seems to... work...

Not done and probably should not be used yet.
  • Loading branch information
mcmonkey4eva committed Aug 22, 2013
1 parent 6642266 commit 8fdd9cf
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 98 deletions.
Expand Up @@ -16,7 +16,7 @@
* @author Jeremy Schroeder
*
*/
public class ScriptEntry {
public class ScriptEntry implements Cloneable{

This comment has been minimized.

Copy link
@aufdemrand

aufdemrand Aug 22, 2013

Contributor

This worries me, what's the reason to clone it? If you are cloning the scriptentry after it's been execute()ed by the CommandExecuter, tags will already be filled. That seems like it would be a problem, no?

This comment has been minimized.

Copy link
@aufdemrand

aufdemrand Aug 22, 2013

Contributor

Either way, seems like a bad idea to encourage people to clone scriptentries this way.

This comment has been minimized.

Copy link
@mcmonkey4eva

mcmonkey4eva Aug 25, 2013

Author Member

@aufdemrand - Nobody else should be cloning them. It's cloned in foreach because it needs the tags to not be filled, and this is the simplest way to accomplish that.


// The name of the command that will be executed
private String command;
Expand All @@ -37,6 +37,11 @@ public class ScriptEntry {

private Map<String, Object> objects = new HashMap<String, Object>();

@Override
public ScriptEntry clone() throws CloneNotSupportedException {
return (ScriptEntry) super.clone();
}

public ScriptEntry(String command, String[] arguments, ScriptContainer script) throws ScriptEntryCreationException {

// Must never be null
Expand Down
@@ -0,0 +1,95 @@
package net.aufdemrand.denizen.scripts.commands;

import java.util.ArrayList;
import java.util.TreeMap;

import net.aufdemrand.denizen.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.exceptions.ScriptEntryCreationException;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.utilities.debugging.dB;

public abstract class BracedCommand extends AbstractCommand {



public ArrayList<ScriptEntry> getBracedCommands(ScriptEntry scriptEntry) throws InvalidArgumentsException {
return getBracedCommands(scriptEntry, 0);
}
public final boolean hyperdebug = false;

public ArrayList<ScriptEntry> getBracedCommands(ScriptEntry scriptEntry, int extraEntries) throws InvalidArgumentsException {
TreeMap<Integer, ArrayList<String>> commandList = new TreeMap<Integer, ArrayList<String>>();
ArrayList<ScriptEntry> commands = new ArrayList<ScriptEntry>();
int bracesEntered = 0;
boolean newCommand = false;

This comment has been minimized.

Copy link
@aufdemrand

aufdemrand Aug 22, 2013

Contributor

Would be nice to have some comments in this code, though.

This comment has been minimized.

Copy link
@mcmonkey4eva

mcmonkey4eva Sep 8, 2013

Author Member

Missed this earlier somehow ---... the comments are the hyperdebug lines.

if (hyperdebug) dB.echoDebug("Starting getBracedCommands...");
scriptEntry.getResidingQueue().injectEntry(scriptEntry, 0);
if (hyperdebug) dB.echoDebug("...with queue size: " + (extraEntries > 0 ? extraEntries + 1 : 1));
if (hyperdebug) dB.echoDebug("...with first command name: " + scriptEntry.getCommandName());
if (hyperdebug) dB.echoDebug("...with first command arguments: " + scriptEntry.getArguments());
for (int x = 0; x < (extraEntries > 0 ? extraEntries + 1 : 1); x++) {
ScriptEntry entry = scriptEntry.getResidingQueue().getEntry(0);
if (hyperdebug) dB.echoDebug("Entry found: " + entry.getCommandName());
for (aH.Argument arg : aH.interpret(entry.getArguments())) {
if (hyperdebug) dB.echoDebug("Arg found: " + arg.raw_value);
if (arg.matches("{")) {
bracesEntered++;
if (hyperdebug) dB.echoDebug("Opened brace; " + bracesEntered + " now");
if (bracesEntered > 1) {
commandList.get(commandList.lastKey()).add(arg.raw_value);
}
}
else if (arg.matches("}")) {
bracesEntered--;
if (hyperdebug) dB.echoDebug("Closed brace; " + bracesEntered + " now");
if (bracesEntered > 0) {
commandList.get(commandList.lastKey()).add(arg.raw_value);
}
}
else if (newCommand && bracesEntered == 1) {
commandList.put(commandList.size(), new ArrayList<String>());
commandList.get(commandList.lastKey()).add(arg.raw_value);
newCommand = false;
if (hyperdebug) dB.echoDebug("Treating as new command");
}
else if (bracesEntered == 0) {
if (hyperdebug) dB.echoDebug("Ignoring");
// Do nothing ... for now...
}
else if (arg.matches("-") && bracesEntered == 1) {
newCommand = true;
if (hyperdebug) dB.echoDebug("Assuming following is a new command");
}
else {
commandList.get(commandList.lastKey()).add(arg.raw_value);
if (hyperdebug) dB.echoDebug("Adding to previous command");
}
}
for (ArrayList<String> command : commandList.values()) {
try {
if (command.isEmpty()) {
if (hyperdebug) dB.echoError("Empty command?");
continue;
}
String cmd = command.get(0);
if (hyperdebug) dB.echoDebug("Calculating " + cmd);
command.remove(0);
String[] args = new String[command.size()];
args = command.toArray(args);
commands.add(new ScriptEntry(cmd,
args,
scriptEntry.getScript().getContainer()));
commands.get(commands.size() - 1).setPlayer(scriptEntry.getPlayer());
commands.get(commands.size() - 1).setNPC(scriptEntry.getNPC());
if (hyperdebug) dB.echoDebug("Command added: " + cmd + ", with " + String.valueOf(args.length) + " arguments");
} catch (ScriptEntryCreationException e) {
if (hyperdebug) dB.echoError(e.getMessage());
}
}
scriptEntry.getResidingQueue().removeEntry(0);
}
return commands;
}

}
Expand Up @@ -158,7 +158,7 @@ public void registerCoreMembers() {
"FOLLOW", "follow (stop) (lead:<#.#>) (target:<entity>)", 0);

registerCoreMember(ForEachCommand.class,
"FOREACH", "foreach [location:<location>|...] [<script>]", 0);
"FOREACH", "foreach [<object>|...] [<commands>]", 1);

This comment has been minimized.

Copy link
@aufdemrand

aufdemrand Aug 22, 2013

Contributor

Should this look like:

foreach [<dList>] [<commands>] ?

This comment has been minimized.

Copy link
@mcmonkey4eva

mcmonkey4eva Sep 8, 2013

Author Member

Probably! I'm terrible at writing reasonable dCommand syntax meta.


registerCoreMember(GiveCommand.class,
"GIVE", "give [money/<item>] (qty:<#>) (engrave)", 1);
Expand Down
@@ -1,129 +1,73 @@
package net.aufdemrand.denizen.scripts.commands.core;

import java.util.ArrayList;
import java.util.UUID;

import net.aufdemrand.denizen.exceptions.CommandExecutionException;
import net.aufdemrand.denizen.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.*;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.objects.dList;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.commands.BracedCommand;
import net.aufdemrand.denizen.scripts.queues.ScriptQueue;
import net.aufdemrand.denizen.scripts.ScriptRegistry;
import net.aufdemrand.denizen.scripts.commands.AbstractCommand;
import net.aufdemrand.denizen.scripts.containers.core.TaskScriptContainer;
import net.aufdemrand.denizen.scripts.queues.core.InstantQueue;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.debugging.dB.Messages;

import java.util.HashMap;
import java.util.Map;

/**
* @author aufdemrand
*
*/
public class ForEachCommand extends AbstractCommand {

// - foreach location:0,0,0,world|3,3,3,world 'fill_it'
public class ForEachCommand extends BracedCommand {

enum Type {LOCATION, LIST_ITEM}
// - foreach li@p@Vegeta|p@MuhammedAli|n@123 {
// - inventory move origin:<%value%.inventory> destination:in@location[123,70,321]
// }

@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {

for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {

if (!scriptEntry.hasObject("iterable")
&& arg.matchesArgumentType(dLocation.class))
scriptEntry.addObject("iterable", arg.asType(dLocation.class));

else if (!scriptEntry.hasObject("iterable")
if (!scriptEntry.hasObject("list")
&& arg.matchesArgumentType(dList.class))
scriptEntry.addObject("iterable", arg.asType(dList.class));



}

Type type = null;
dScript script = null;
dLocation location_1 = null;
dLocation location_2 = null;
scriptEntry.addObject("list", arg.asType(dList.class));

// Parse Arguments
for (String arg : scriptEntry.getArguments()) {

if (aH.matchesValueArg("LOCATION, ITEM_IN_LIST", arg, aH.ArgumentType.Custom)) {
type = Type.valueOf(arg.split(":")[0].toUpperCase());

if (type == Type.LOCATION) {
location_1 = dLocation.valueOf(aH.getStringFrom(arg).split("\\|")[0]);
location_2 = dLocation.valueOf(aH.getStringFrom(arg).split("\\|")[1]);
}
}

else {
if (ScriptRegistry.containsScript(aH.getStringFrom(arg), TaskScriptContainer.class))
script = aH.getScriptFrom(arg);
else dB.echoError("'" + aH.getStringFrom(arg) + "' is not valid! Must specify a TASK-type script.");
}
}

if (type == null) throw new InvalidArgumentsException("Must specify a 'foreach' type!");

if (type == Type.LOCATION && (location_1 == null || location_2 == null))
throw new InvalidArgumentsException("Invalid locations have been specified!");
if (!scriptEntry.hasObject("list"))
throw new InvalidArgumentsException(Messages.ERROR_MISSING_OTHER, "LIST");

scriptEntry.addObject("loc_1", location_1)
.addObject("loc_2", location_2)
.addObject("type", type)
.addObject("script", script);
scriptEntry.addObject("entries", getBracedCommands(scriptEntry));

}

@SuppressWarnings("unchecked")
@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {

// Get objects
Type type = (Type) scriptEntry.getObject("type");
dLocation loc_1 = (dLocation) scriptEntry.getObject("loc_1");
dLocation loc_2 = (dLocation) scriptEntry.getObject("loc_2");
dScript script = (dScript) scriptEntry.getObject("script");
dList list = (dList) scriptEntry.getObject("list");
ArrayList<ScriptEntry> entries = (ArrayList<ScriptEntry>) scriptEntry.getObject("entries");

// Report to dB
dB.report(getName(),
aH.debugObj("Type", type.toString())
+ (type == Type.LOCATION ? loc_1.debug() + loc_2.debug() : "")
+ script.debug());

if (type == Type.LOCATION) {

int x_inc = -1;
int y_inc = -1;
int z_inc = -1;

if (loc_1.getBlockX() <= loc_2.getBlockX()) x_inc = 1;
if (loc_1.getBlockY() <= loc_2.getBlockY()) y_inc = 1;
if (loc_1.getBlockZ() <= loc_2.getBlockZ()) z_inc = 1;

int x_amt = Math.abs(loc_1.getBlockX() - loc_2.getBlockX());
int y_amt = Math.abs(loc_1.getBlockY() - loc_2.getBlockY());
int z_amt = Math.abs(loc_1.getBlockZ() - loc_2.getBlockZ());

for (int x = 0; x != x_amt + 1; x++) {
for (int y = 0; y != y_amt + 1; y++) {
for (int z = 0; z != z_amt + 1; z++) {
dLocation loc = new dLocation(loc_1.clone().add((double) x * x_inc, (double) y * y_inc, (double) z * z_inc));

dB.echoDebug("location: " + loc.identify());

Map<String, String> context = new HashMap<String, String>();
context.put("1", loc.identify());

((TaskScriptContainer) script.getContainer()).setSpeed(Duration.valueOf("0"))
.runTaskScript(ScriptQueue._getNextId(),
scriptEntry.getPlayer(),
scriptEntry.getNPC(),
context);
}
dB.report(getName(), list.debug() );

for (String value : list) {
ArrayList<ScriptEntry> newEntries = (ArrayList<ScriptEntry>) new ArrayList<ScriptEntry>();
for (ScriptEntry entr: entries) {
try {
ScriptEntry toadd = entr.clone();
toadd.getObjects().clear();
newEntries.add(toadd);
}
catch (Throwable e) {
e.printStackTrace();
}
}
ScriptQueue queue = new InstantQueue(UUID.randomUUID().toString());
scriptEntry.getResidingQueue().addContext("value", value);
queue.addContext("value", value);
queue.addEntries(newEntries);
queue.start();
}

}

}
}
Expand Up @@ -56,6 +56,8 @@ else if ((arg.matchesPrefix("target") || arg.matchesPrefix("targets"))) {
else {
if (!scriptEntry.hasObject("text"))
scriptEntry.addObject("text", arg.asElement());
else
dB.echoError("Unknown argument " + arg.raw_value);
}
}

Expand Down
Expand Up @@ -242,7 +242,7 @@ public void clear() {
* delayTime.
*
* @param delayTime the time to start the queue, in
* System.currentTimeMilis() format.
* System.currentTimeMillis() format.
*/
public void delayUntil(long delayTime) {
this.delay_time = delayTime;
Expand Down

5 comments on commit 8fdd9cf

@mcmonkey4eva
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Morph started it... I made it, you know, actually work. BracedCommand needs to be upgraded to additionally work with the IF command.

@aufdemrand
Copy link
Contributor

@aufdemrand aufdemrand commented on 8fdd9cf Aug 22, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aufdemrand
Copy link
Contributor

@aufdemrand aufdemrand commented on 8fdd9cf Aug 22, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Morphan1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aufdemrand I had a semi-working version at like.. 3am when I gave it to him and went to bed, so I don't know what works and what doesn't in his version. I'll try to push its limits though

@mcmonkey4eva
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aufdemrand I know you can use a foreach within a foreach, it should permit IF within a foreach...

Please sign in to comment.