diff --git a/src/com/characterforming/jrte/engine/Model.java b/src/com/characterforming/jrte/engine/Model.java index c94fd8a..731b8eb 100644 --- a/src/com/characterforming/jrte/engine/Model.java +++ b/src/com/characterforming/jrte/engine/Model.java @@ -98,6 +98,7 @@ public record Argument(int transducerOrdinal, BytesArray tokens) {} protected File modelPath; private ArrayList> effectorParametersMaps; + private Transductor proxyTransductor; /** Proxy compiler model for effector parameter compilation */ public Model() { @@ -173,8 +174,8 @@ protected void initializeProxyEffectors() throws ModelException { try { if (this.targetClass.getDeclaredConstructor().newInstance() instanceof ITarget proxyTarget) { this.targetName = proxyTarget.getName(); - Transductor proxyTransductor = new Transductor(); - proxyTransductor.setModel(this); + this.proxyTransductor = new Transductor(); + this.proxyTransductor.setModel(this); IEffector[] trexFx = proxyTransductor.getEffectors(); IEffector[] targetFx = proxyTarget.getEffectors(); this.proxyEffectors = new IEffector[trexFx.length + targetFx.length]; @@ -186,7 +187,6 @@ protected void initializeProxyEffectors() throws ModelException { this.effectorOrdinalMap.put(this.proxyEffectors[effectorOrdinal].getName(), effectorOrdinal); this.effectorParametersMaps.add(null); } - assert proxyTransductor == (Transductor)this.proxyEffectors[0].getTarget(); } else throw new ModelException(String.format( "Class '%s' from model file %s does not implement the ITarget interface.", this.targetClass.getName(), this.modelPath.toPath().toString())); @@ -344,6 +344,7 @@ protected Model load() throws ModelException, CharacterCodingException { this.proxyEffectors[effectorOrdinal].passivate(); } } + this.proxyTransductor = null; if (!errors.isEmpty()) { for (String error : errors) { this.rtcLogger.log(Level.SEVERE, error); @@ -461,10 +462,9 @@ protected boolean checkTargetEffectors(ITarget target, IEffector[] boundFx) { protected Argument[][] compileModelParameters(List errors) throws EffectorException { Argument[][] effectorArguments = new Argument[this.proxyEffectors.length][]; final Map effectorMap = this.getEffectorOrdinalMap(); - Transductor proxyTransductor = (Transductor)this.proxyEffectors[0].getTarget(); for (int effectorOrdinal = 0; effectorOrdinal < this.proxyEffectors.length; effectorOrdinal++) { HashMap parametersMap = this.effectorParametersMaps.get(effectorOrdinal); - this.proxyEffectors[effectorOrdinal].setOutput(proxyTransductor); + this.proxyEffectors[effectorOrdinal].setOutput(this.proxyTransductor); if (this.proxyEffectors[effectorOrdinal] instanceof BaseParameterizedEffector parameterizedEffector) { if (parametersMap != null) { assert parametersMap != null: String.format("Effector parameters map is null for %1$s effector", diff --git a/src/com/characterforming/jrte/engine/Transductor.java b/src/com/characterforming/jrte/engine/Transductor.java index 7c5e47b..c799adf 100644 --- a/src/com/characterforming/jrte/engine/Transductor.java +++ b/src/com/characterforming/jrte/engine/Transductor.java @@ -768,7 +768,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - for (IToken t : super.getParameter(parameterIndex)) { + for (IToken t : super.parameters[parameterIndex]) { if (t instanceof Token token) { if (token.getType() == IToken.Type.FIELD) { Value field = transducerStack.value(token.getOrdinal()); @@ -802,7 +802,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - selected = super.getParameter(parameterIndex); + selected = super.parameters[parameterIndex]; value = transducerStack.value(selected); assert selected != Model.ALL_FIELDS_ORDINAL; if (selected != Model.ALL_FIELDS_ORDINAL) { @@ -825,7 +825,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - int fieldOrdinal = super.getParameter(parameterIndex); + int fieldOrdinal = super.parameters[parameterIndex]; assert fieldOrdinal != Model.ALL_FIELDS_ORDINAL; value.paste(transducerStack.value(fieldOrdinal)); return IEffector.RTX_NONE; @@ -844,7 +844,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - int fieldOrdinal = super.getParameter(parameterIndex); + int fieldOrdinal = super.parameters[parameterIndex]; assert fieldOrdinal != Model.ALL_FIELDS_ORDINAL; value.paste(transducerStack.value(fieldOrdinal)); transducerStack.value(fieldOrdinal).clear(); @@ -865,7 +865,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - final int nameIndex = super.getParameter(parameterIndex); + final int nameIndex = super.parameters[parameterIndex]; int index = (nameIndex >= 0) ? nameIndex : selected; assert index >= -1; if (index != Model.ALL_FIELDS_ORDINAL) { @@ -889,7 +889,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - return signal(super.getParameter(parameterIndex)); + return signal(super.parameters[parameterIndex]); } @Override // @see com.characterforming.ribose.IParameterizedEffector#allocateParameters(int) @@ -940,7 +940,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { - IToken[] parameters = super.getParameter(parameterIndex); + IToken[] parameters = super.parameters[parameterIndex]; byte[][] tokens = new byte[parameters.length][]; for (int i = 0; i < parameters.length; i++) { if (parameters[i].getType() == IToken.Type.FIELD) { @@ -969,7 +969,7 @@ public int invoke() throws EffectorException { @Override public int invoke(final int parameterIndex) throws EffectorException { if (outputStream != null) { - for (final IToken token : super.getParameter(parameterIndex)) { + for (final IToken token : super.parameters[parameterIndex]) { try { if (token.getType() == IToken.Type.FIELD) { Value field = transducerStack.value(token.getOrdinal()); @@ -1008,7 +1008,7 @@ public int[][] allocateParameters(int parameterCount) { @Override public int invoke(final int parameterIndex) throws EffectorException { assert (transducer == transducerStack.peek()) || (transducer == transducerStack.get(transducerStack.tos()-1)); - int[] parameter = super.getParameter(parameterIndex); + int[] parameter = super.parameters[parameterIndex]; transducer.countdown = parameter[0]; transducer.signal = parameter[1]; if (transducer.countdown < 0) { @@ -1021,7 +1021,7 @@ public int invoke(final int parameterIndex) throws EffectorException { public int[] compileParameter(final IToken[] parameterList) throws TargetBindingException { if (parameterList.length != 2) { throw new TargetBindingException(String.format("%1$S.%2$S: effector requires two parameters", - super.getTarget().getName(), super.getName())); + super.target.getName(), super.getName())); } int count = -1; if (parameterList[0].getType() == IToken.Type.FIELD) { @@ -1031,7 +1031,7 @@ public int[] compileParameter(final IToken[] parameterList) throws TargetBinding count = Base.decodeInt(v, v.length); } else { throw new TargetBindingException(String.format("%1$s.%2$s[]: invalid field|counter for count effector", - super.getTarget().getName(), super.getName())); + super.target.getName(), super.getName())); } if (parameterList[1].getType() == IToken.Type.SIGNAL) { int signalOrdinal = parameterList[1].getOrdinal(); @@ -1039,7 +1039,7 @@ public int[] compileParameter(final IToken[] parameterList) throws TargetBinding return new int[] { count, signalOrdinal }; } else { throw new TargetBindingException(String.format("%1$s.%2$s[]: invalid signal '%3$%s' for count effector", - super.getTarget().getName(), super.getName(), parameterList[1].asString())); + super.target.getName(), super.getName(), parameterList[1].asString())); } } } @@ -1073,7 +1073,7 @@ public Integer compileParameter(final IToken[] parameterTokens) throws TargetBin @Override public int invoke(final int parameterIndex) throws EffectorException { - int transducerOrdinal = super.getParameter(parameterIndex); + int transducerOrdinal = super.parameters[parameterIndex]; try { transducerStack.push(loader.loadTransducer(transducerOrdinal)); transducerStack.peek().selected = Model.ANONYMOUS_FIELD_ORDINAL; @@ -1117,7 +1117,7 @@ public long[][] allocateParameters(int parameterCount) { public int invoke(final int parameterIndex) throws EffectorException { if (matchMode == MATCH_NONE) { matchMode = MATCH_SUM; - matchSum = super.getParameter(parameterIndex); + matchSum = super.parameters[parameterIndex]; } else { throw new EffectorException(String.format("Illegal attempt to override match mode %d with MSUM=%d", matchMode, MATCH_SUM)); @@ -1140,7 +1140,7 @@ public long[] compileParameter(final IToken[] parameterList) throws TargetBindin @Override public String showParameterTokens(int parameterIndex) { - long[] sum = super.getParameter(parameterIndex); + long[] sum = super.parameters[parameterIndex]; StringBuilder sb = new StringBuilder(); int endBit = 0, startBit = -1; for (int j = 0; j < sum.length; j++) { @@ -1191,7 +1191,7 @@ public int invoke() throws EffectorException { public int invoke(final int parameterIndex) throws EffectorException { if (matchMode == MATCH_NONE) { matchMode = MATCH_PRODUCT; - matchProduct = super.getParameter(parameterIndex); + matchProduct = super.parameters[parameterIndex]; matchPosition = 0; } else { throw new EffectorException(String.format("Illegal attempt to override match mode %d with MPRODUCT=%d", @@ -1216,7 +1216,7 @@ public byte[] compileParameter(final IToken[] parameterList) throws TargetBindin @Override public String showParameterTokens(int parameterIndex) { - byte[] product = super.getParameter(parameterIndex); + byte[] product = super.parameters[parameterIndex]; StringBuilder sb = new StringBuilder(); for (int j = 0; j < product.length; j++) { sb.append(32 < product[j] && 127 > product[j] @@ -1241,7 +1241,7 @@ public int invoke() throws EffectorException { public int invoke(final int parameterIndex) throws EffectorException { if (matchMode == MATCH_NONE) { matchMode = MATCH_SCAN; - matchByte = super.getParameter(parameterIndex); + matchByte = super.parameters[parameterIndex]; } else { throw new EffectorException(String.format("Illegal attempt to override match mode %d with MSCAN=%d", matchMode, MATCH_SCAN)); @@ -1264,7 +1264,7 @@ public Integer compileParameter(final IToken[] parameterList) throws TargetBindi @Override public String showParameterTokens(int parameterIndex) { - int scanbyte = super.getParameter(parameterIndex); + int scanbyte = super.parameters[parameterIndex]; return 32 < scanbyte && 127 > scanbyte ? String.format(" %c", (char)scanbyte) : String.format(" #%x", scanbyte); diff --git a/src/com/characterforming/ribose/IEffector.java b/src/com/characterforming/ribose/IEffector.java index 81104fa..c2737f5 100644 --- a/src/com/characterforming/ribose/IEffector.java +++ b/src/com/characterforming/ribose/IEffector.java @@ -35,7 +35,7 @@ * are typically implemented as inner classes within a specialized {@link ITarget} * mplementation class. Conversion between Java/Unicode char and UTF-8 byte are * supported by static {@link Codec} methods backed by thread local encoder and - * decoder bound instances. Ribose and ginr currently support only UTF-8 character + * decoder instances. Ribose and ginr currently support only UTF-8 character * encodings. *

* Proxy simple effectors, instantiated in model compilation and loding contexts, @@ -44,11 +44,12 @@ * receive {@link #passivate()} and lose access to their {@link ITarget} and {@link * IOutput} instances. Live simple effectors instantiated in runtime contexts * receive {@link #setOutput(IOutput)} followed by 0 or more {@link #invoke()}. Live - * effectors are never passivated and may use {@link #getTarget()} in their {@link - * #invoke()} methods. Simple effectors that must access transducer fields may override - * {@link #setOutput(IOutput)} to look up localized field indexes using {@link - * IOutput#getLocalizedFieldIndex(String, String)} and retain these for subsequent - * use with the {@link IOutput} data transfer methods in {@link #invoke()}. + * effectors are never passivated and may access {@code super.target} and {@code + * super.output} in their {@link #invoke()} methods. Effectors access transducer + * fields by overriding {@link #setOutput(IOutput)} and use {@link + * IOutput#getLocalizedFieldIndex(String, String)} to obtain stable field indexes for + * subsequent use with the {@link IOutput} data transfer methods. See {@link IOutput} + * for more information regarding field binding in effectors. *

* All {@link #invoke()} implementations return an integer RTX * code, which is a bit map of special conditions. RTX bits are additive and @@ -101,14 +102,6 @@ public interface IEffector { */ Bytes getName(); - /** - * Returns the target that expresses the effector. Effector implementations may - * access {@link BaseEffector#target} directly. - * - * @return the target that expresses the effector - */ - T getTarget(); - /** * Receive an {@link IOutput} view of the transductor that the effector target * is bound to. Effectors retain their IOutput view to look up field ordinals diff --git a/src/com/characterforming/ribose/IParameterizedEffector.java b/src/com/characterforming/ribose/IParameterizedEffector.java index 2b227ff..57a9189 100644 --- a/src/com/characterforming/ribose/IParameterizedEffector.java +++ b/src/com/characterforming/ribose/IParameterizedEffector.java @@ -20,7 +20,6 @@ package com.characterforming.ribose; -import com.characterforming.ribose.base.BaseEffector; import com.characterforming.ribose.base.BaseParameterizedEffector; import com.characterforming.ribose.base.EffectorException; import com.characterforming.ribose.base.TargetBindingException; @@ -81,7 +80,7 @@ * } * ... // in live effector * int invoke(int index) { - * SimpleDateFormat formatter = super.getParameter(index); + * SimpleDateFormat formatter = super.parameters[index]; * // get some field contents and format as date * return RTX_NONE; * } @@ -139,15 +138,6 @@ int invoke(int parameterIndex) P compileParameter(IToken[] parameterTokens) throws TargetBindingException; - /** - * Get an indexed parameter from the parameters array. Effector implementations - * may access {@link BaseEffector#target} directly. - * - * @param parameterIndex the parameter index in the array - * @return the parameter instance - */ - P getParameter(int parameterIndex); - /** * Return the type of the effector's parameter object, to support decompilation * (generic parameter type is difficult to obtain by reflection). diff --git a/src/com/characterforming/ribose/base/BaseEffector.java b/src/com/characterforming/ribose/base/BaseEffector.java index 48352af..56d6f4f 100644 --- a/src/com/characterforming/ribose/base/BaseEffector.java +++ b/src/com/characterforming/ribose/base/BaseEffector.java @@ -38,6 +38,7 @@ public abstract class BaseEffector implements IEffector { /** Effector access to the target that it is bound to */ protected T target; + /** Effector view of Transductor loggers, UTF-8 codecs and fields. */ protected IOutput output; @@ -71,11 +72,6 @@ public final Bytes getName() { return this.name; } - @Override // @see com.characterforming.ribose.IEffector#getTarget() - public final T getTarget() { - return this.target; - } - @Override // @see java.lang.Object#toString() public String toString() { return this.name.asString(); diff --git a/src/com/characterforming/ribose/base/BaseParameterizedEffector.java b/src/com/characterforming/ribose/base/BaseParameterizedEffector.java index f17cd41..4018383 100644 --- a/src/com/characterforming/ribose/base/BaseParameterizedEffector.java +++ b/src/com/characterforming/ribose/base/BaseParameterizedEffector.java @@ -38,7 +38,7 @@ *
  • {@link IParameterizedEffector#compileParameter(IToken[])}
  • * * Subclasses may access indexed compiled parameter objects in their {@link #invoke(int)} - * implementations using {@link #getParameter(int)}. Default {@link showParameterType()} + * implementations directly as {@code super.parameters[int]}. Default {@link showParameterType()} * and {@link showParameterTokens(int)} methods are implemented here but subclasses * may override these if desired. Otherwise, public methods not exposed in the * {@link IParameterizedEffector} interface are for internal use only. These methods @@ -77,11 +77,6 @@ protected BaseParameterizedEffector(final T target, final String name) @Override // @see com.characterforming.ribose.base.IParameterizedEffector#compileParameter(IToken[]) public abstract P compileParameter(IToken[] parameterTokens) throws TargetBindingException; -@Override - public P getParameter(int parameterIndex) { - return this.parameters[parameterIndex]; - } - @Override public String showParameterType() { return this.parameters != null && this.parameters.length > 0 @@ -145,7 +140,7 @@ public final boolean compileParameters(IToken[][] parameterTokens, List fail = true; } catch (Exception e) { parameterErrors.add(String.format("%1$s.%2$s[]: %3$%s", - super.getTarget().getName(), super.getName(), e.getMessage())); + super.target.getName(), super.getName(), e.getMessage())); fail = true; } }