package net.sourceforge.pain.logic.fn; import net.sourceforge.pain.*; import net.sourceforge.pain.logic.fn.util.*; import net.sourceforge.pain.console.*; import net.sourceforge.pain.data.*; import net.sourceforge.pain.data.type.*; import java.util.*; /** MessageOutFn template definition: $$ - means '$' ascii character, this is not parameter. $X - means parameter all paramter look for values in args[] array so we haave invariant: args.length = number of parameters X: lowercase: first param UPPERCASE: second param t,T - (text)argiment is a java.lang.String d,D - (Interactive.desc) This parameters will get clarified in one of the next versions: e,E - Result is 'he', 'she', or 'it', depending on the sex/gender of arg (LogicalObject). (default he) e,M - Result is 'him', 'her', or 'it', depending on the sex/gender of arg (LogicalObject).(default his) s,S - Result is 'his', 'her', or 'its', depending on the sex/gender of arg (LogicalObject).(default his) TO_ONE: = to messageRecipient only TO_SPACE: = to every receptive object in this space except messageRecipient WARN: single thread model!!! */ public final class MessageOutFn { private static final Map preparedTemplates = new HashMap(); public static void outSpace(LogicalObject actor, String template, Object arg1) { _outSpace(actor, null, template, arg1, null, Receptive.SEE); } public static void outSpace(LogicalObject actor, String template, Object arg1, Object arg2) { _outSpace(actor, null, template, arg1, arg2, Receptive.SEE); } public static void outSpace(LogicalObject actor, String template, Object arg1, Object arg2, int receptionType) { _outSpace(actor, null, template, arg1, arg2, receptionType); } public static void outSpaceNoVictim(LogicalObject actor, Interactive victim, String template) { _outSpace(actor, victim, template, null, null, Receptive.SEE); } public static void outSpaceNoVictim(LogicalObject actor, Interactive victim, String template, Object arg1) { _outSpace(actor, victim, template, arg1, null, Receptive.SEE); } public static void outSpaceNoVictim(LogicalObject actor, Interactive victim, String template, Object arg1, Object arg2) { _outSpace(actor, victim, template, arg1, arg2, Receptive.SEE); } public static void outOne(LogicalObject recipient, String template, Object arg1) { _outOne(recipient, prepareTemplate(template), arg1, null, Receptive.SEE); } public static void outOne(LogicalObject recipient, String template, Object arg1, Object arg2) { _outOne(recipient, prepareTemplate(template), arg1, arg2, Receptive.SEE); } private static void _outOne(LogicalObject obj, OutTemplate template, Object arg1, Object arg2, int receptionType) { Receptive rObj = (Receptive) obj.getRole(Receptive.class); if (rObj == null || !rObj.has(receptionType)) { return; } //today the only reception output is console, in next version reception outputs will be expanded (virtual consoles or something like that) Console console = ConsoleFn.getConsole(obj); if (console == null) { return; } String[] tokens = template.tokens; char[] params = template.params; console.out(tokens[0]); for (int i = 0; i < params.length; i++) { final String value; switch (params[i]) { case 't': case 'd': value = (String) arg1; break; case 'T': case 'D': value = (String) arg2; break; case 'n': case 'p': Interactive inter1 = (Interactive) ((LogicalObject) arg1).getRole(Interactive.class); if (inter1 == null) { throw new RuntimeException("arg1 has not Interactive role!"); } value = inter1.getName(); break; case 'N': case 'P': Interactive inter2 = (Interactive) ((LogicalObject) arg2).getRole(Interactive.class); if (inter2 == null) { throw new RuntimeException("arg2 has not Interactive role!"); } value = inter2.getName(); break; case 'e': value = LangUtil.he((LogicalObject) arg1); break; case 'E': value = LangUtil.he((LogicalObject) arg2); break; case 'm': value = LangUtil.him((LogicalObject) arg1); break; case 'M': value = LangUtil.him((LogicalObject) arg2); break; case 's': value = LangUtil.his((LogicalObject) arg1); break; case 'S': value = LangUtil.his((LogicalObject) arg2); break; default: throw new RuntimeException("Not supported type:" + params[i]); } // Log.debug("OUT:value'"+value+"'"); console.out(value); // Log.debug("OUT:token'"+template.tokens[i + 1]+"'"); console.out(template.tokens[i + 1]); } console.out("\n"); } private static void _outSpace(LogicalObject actor, LogicalObject victim, String template, Object arg1, Object arg2, int receptionType) { final Located actorL = (Located) actor.getRole(Located.class); final Located victimL = victim == null ? null : (Located) victim.getRole(Located.class); final OutTemplate t = prepareTemplate(template); Space space = actorL.getLocation(); for (Located obj = space.getFirstInSpace(); obj != null; obj = obj.getNextInSpace()) { if (obj != actorL && obj != victimL) { _outOne(obj, t, arg1, arg2, receptionType); } } } private static OutTemplate prepareTemplate(String templateStr) { OutTemplate template = (OutTemplate) preparedTemplates.get(templateStr); if (template == null) { template = new OutTemplate(templateStr); preparedTemplates.put(templateStr, template); } return template; } protected static final class OutTemplate { public String[] tokens; // simple text between arguments public char[] params; // $, parameters public OutTemplate(String templateStr) { int nParams = countParams(templateStr); params = new char[nParams]; tokens = new String[nParams + 1]; // we always have N parameters and N+1 tokens // example: templateStr = '$n tells $T' ->""+n+" tells "+T+"" StringBuffer buff = new StringBuffer(); int index = 0; for (int i = 0; i < templateStr.length(); i++) { char c = templateStr.charAt(i); if (c == '$') { i++; c = templateStr.charAt(i); if (c == '$') { buff.append(c); } else { tokens[index] = (buff.length() == 0 ? "" : buff.toString()); buff.delete(0, buff.length()); params[index] = c; index++; } } else { buff.append(c); } } tokens[tokens.length - 1] = (buff.length() == 0 ? "" : buff.toString()); } private int countParams(String str) { int result = 0; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c == '$') { i++; c = str.charAt(i); if (c != '$') { result++; } } } return result; } } public static final void out(Console outConsole, String text) { if (outConsole != null) { outConsole.out(text); } } public static final void outln(Console outConsole, String text) { if (outConsole != null) { outConsole.out(text); outConsole.out("\n"); } } /** * any reception type! * @param obj * @param message */ public static void outln(LogicalObject obj, String message) { Console c = ConsoleFn.getConsole(obj); if (c == null) { return; } outln(c, message); } public static void outln(LogicalObject obj, String message, int receptionType) { Receptive r = (Receptive) obj.getRole(Receptive.class); if (r == null || !r.has(receptionType)) { return; } Console c = ConsoleFn.getConsole(obj); if (c == null) { return; } outln(c, message); } public static void outSpace(Space space, String message) { for (Located obj = space.getFirstInSpace(); obj != null; obj = obj.getNextInSpace()) { outln(obj, message, Receptive.FEEL); } } }