Skip to content

Commit 8ce0454

Browse files
Treiblesschorlectrueden
authored andcommitted
Add population of secondary args
1 parent 89d35d5 commit 8ce0454

8 files changed

Lines changed: 106 additions & 84 deletions

File tree

src/main/java/org/scijava/ops/base/OpService.java

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@
3131
import java.lang.reflect.Type;
3232
import java.util.ArrayList;
3333
import java.util.Collection;
34-
import java.util.List;
34+
import java.util.Optional;
3535

3636
import org.scijava.InstantiableException;
3737
import org.scijava.log.LogService;
3838
import org.scijava.ops.Op;
39+
import org.scijava.ops.util.Inject;
3940
import org.scijava.plugin.Parameter;
4041
import org.scijava.plugin.Plugin;
4142
import org.scijava.plugin.PluginInfo;
@@ -63,11 +64,6 @@ public class OpService extends AbstractService implements SciJavaService, OpEnvi
6364
@Parameter
6465
private LogService log;
6566

66-
public StructInstance<?> op(OpRef ref) {
67-
final MatchingResult match = matcher.findMatch(this, ref);
68-
return match.singleMatch().createOp();
69-
}
70-
7167
@Override
7268
public Collection<OpInfo> infos() {
7369
// TODO: Consider maintaining an efficient OpInfo data structure.
@@ -83,33 +79,49 @@ public Collection<OpInfo> infos() {
8379
return infos;
8480
}
8581

86-
public <T> StructInstance<T> findOpInstance(final Class<? extends Op> opClass, final Nil<T> specialType, final Type[] inTypes,
87-
final Type outType) {
82+
public <T> StructInstance<T> findOpInstance(final Class<? extends Op> opClass, final Nil<T> specialType,
83+
final Type[] inTypes, final Type outType, final Object... secondaryArgs) {
8884
// FIXME - multiple output types? We will need to generalize this.
89-
final OpRef ref = OpRef.fromTypes(merge(opClass, specialType == null ? null : specialType.getType()), outType, inTypes);
85+
final OpRef ref = OpRef.fromTypes(merge(opClass, specialType == null ? null : specialType.getType()), outType,
86+
inTypes);
87+
88+
// Find single match which matches the specified types
9089
@SuppressWarnings("unchecked")
91-
final StructInstance<T> op = (StructInstance<T>) op(ref);
90+
final StructInstance<T> op = (StructInstance<T>) findTypeMatch(ref).createOp();
91+
92+
// Inject the secondary args if there are any
93+
if (Inject.Structs.isInjectable(op)) {
94+
if (secondaryArgs.length != 0) {
95+
Inject.Structs.inputs(op, secondaryArgs);
96+
} else {
97+
log.warn(
98+
"Specified Op has secondary args however no secondary args are given. Op execution may lead to errors.");
99+
}
100+
} else if (secondaryArgs.length > 0) {
101+
log.warn(
102+
"Specified Op has no secondary args however secondary args are given. The specified args will not be injected.");
103+
}
92104
return op;
93105
}
94-
95-
public <O extends Op> StructInstance<O> findOpInstance(final Class<O> opClass, final Type[] inTypes, final Type outType) {
96-
return findOpInstance(opClass, null, inTypes, outType);
97-
}
98-
106+
99107
public <T> T findOp(final Class<? extends Op> opClass, final Nil<T> specialType, final Type[] inTypes,
100-
final Type outType) {
101-
return findOpInstance(opClass, specialType, inTypes, outType).object();
108+
final Type outType, final Object... secondaryArgs) {
109+
return findOpInstance(opClass, specialType, inTypes, outType, secondaryArgs).object();
102110
}
103-
104-
public <O extends Op> O findOp(final Class<O> opClass, final Type[] inTypes, final Type outType) {
105-
return findOpInstance(opClass, inTypes, outType).object();
111+
112+
public MatchingResult findTypeMatches(final OpRef ref) {
113+
return matcher.findMatch(this, ref);
106114
}
107-
115+
116+
public OpCandidate findTypeMatch(final OpRef ref) {
117+
return findTypeMatches(ref).singleMatch();
118+
}
119+
108120
private Type[] merge(Type in1, Type... ins) {
109121
Type[] merged = new Type[ins.length + 1];
110122
merged[0] = in1;
111123
for (int i = 0; i < ins.length; i++) {
112-
merged[i+1] = ins[i];
124+
merged[i + 1] = ins[i];
113125
}
114126
return merged;
115127
}

src/main/java/org/scijava/ops/util/Adapt.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ public static <I1, I2, O> BiComputer<I1, I2, O> asBiComputer(final BiFunction<I1
4040
};
4141
}
4242

43-
public static <I, O> OneToOneCommand<I, O> asCommand(final Function<I, O> function) {
44-
return new OneToOneCommand<I, O>() {
43+
public static <I, O> OneToOneCommand<I, O> asCommand(final Function<I, O> function, I input) {
44+
OneToOneCommand<I, O> command = new OneToOneCommand<I, O>() {
4545
@Override
4646
public void run() {
4747
output = function.apply(input);
4848
}
4949
};
50+
// Populate the input member of the function command
51+
Inject.Commands.inputs(command, input);
52+
return command;
5053
}
5154
}
5255

@@ -92,13 +95,16 @@ public static <I1, I2, O> BiFunction<I1, I2, O> asBiFunction(final BiComputer<I1
9295
};
9396
}
9497

95-
public static <I, O> OneToOneCommand<I, O> asCommand(final Computer<I, O> computer) {
96-
return new OneToOneCommand<I, O>() {
98+
public static <I, O> OneToOneCommand<I, O> asCommand(final Computer<I, O> computer, I input, O output) {
99+
OneToOneCommand<I, O> command = new OneToOneCommand<I, O>() {
97100
@Override
98101
public void run() {
99102
computer.compute(input, output);
100103
}
101104
};
105+
// Populate the input and output member of the computer command
106+
Inject.Commands.all(command, input, output);
107+
return command;
102108
}
103109
}
104110
}

src/main/java/org/scijava/ops/util/Computers.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,24 @@ private Computers() {
1818
}
1919

2020
public static <I, O> Computer<I, O> unary(final OpService ops, final Class<? extends Op> opClass,
21-
final Class<I> inputType, final Class<O> outputType) {
21+
final Class<I> inputType, final Class<O> outputType, final Object... secondaryArgs) {
2222
return ops.findOp( //
2323
opClass, //
2424
new Nil<Computer<I, O>>() {
2525
}, //
2626
new Type[] { inputType, outputType }, //
27-
outputType);
27+
outputType, secondaryArgs);
2828
}
2929

3030
public static <I1, I2, O> BiComputer<I1, I2, O> binary(final OpService ops, final Class<? extends Op> opClass,
31-
final Class<I1> input1Type, final Class<I2> input2Type, final Class<O> outputType) {
31+
final Class<I1> input1Type, final Class<I2> input2Type, final Class<O> outputType,
32+
final Object... secondaryArgs) {
3233
return ops.findOp( //
3334
opClass, //
3435
new Nil<BiComputer<I1, I2, O>>() {
3536
}, //
3637
new Type[] { input1Type, input2Type, outputType }, //
37-
outputType);
38+
outputType, secondaryArgs);
3839
}
3940

4041
}

src/main/java/org/scijava/ops/util/Functions.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,26 @@ private Functions() {
1818
}
1919

2020
public static <I, O> Function<I, O> unary(final OpService ops, final Class<? extends Op> opClass,
21-
final Class<I> inputType, final Class<O> outputType) {
21+
final Class<I> inputType, final Class<O> outputType, final Object... secondaryArgs) {
2222
return ops.findOp( //
23-
opClass,
23+
opClass, //
2424
new Nil<Function<I, O>>() {
2525
}, //
2626
new Type[] { inputType }, //
27-
outputType);
27+
outputType, //
28+
secondaryArgs);
2829
}
2930

3031
public static <I1, I2, O> BiFunction<I1, I2, O> binary(final OpService ops, final Class<? extends Op> opClass,
31-
final Class<I1> input1Type, final Class<I2> input2Type, final Class<O> outputType) {
32+
final Class<I1> input1Type, final Class<I2> input2Type, final Class<O> outputType,
33+
final Object... secondaryArgs) {
3234
return ops.findOp( //
33-
opClass,
35+
opClass, //
3436
new Nil<BiFunction<I1, I2, O>>() {
3537
}, //
3638
new Type[] { input1Type, input2Type }, //
37-
outputType);
39+
outputType, //
40+
secondaryArgs);
3841
}
3942

4043
}

src/main/java/org/scijava/ops/util/Inject.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ private Inject() {
2121
public static class Structs {
2222
private Structs() {
2323
}
24-
24+
25+
public static boolean isInjectable(final StructInstance<?> instance) {
26+
return !getAccessibles(instance).isEmpty();
27+
}
28+
2529
public static void inputs(StructInstance<?> instance, Object... objs) {
2630
unsafe(filterAccessibles(getAccessibles(instance), m -> {
2731
ItemIO ioType = m.member().getIOType();
@@ -88,7 +92,7 @@ public static void all(Command command, Object... objs) {
8892
Structs.all(commandToStructInstance(command), objs);
8993
}
9094

91-
private static StructInstance<Command> commandToStructInstance(Command command) {
95+
public static StructInstance<Command> commandToStructInstance(Command command) {
9296
try {
9397
return ParameterStructs.create(command);
9498
} catch (ValidityException e) {

src/main/java/org/scijava/ops/util/Inplaces.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,25 @@ private Inplaces() {
1818
}
1919

2020
public static <IO> Inplace<IO> unary(final OpService ops, final Class<? extends Op> opClass,
21-
final Class<IO> inputOutputType) {
21+
final Class<IO> inputOutputType, final Object... secondaryArgs) {
2222
return ops.findOp( //
23-
opClass,
23+
opClass, //
2424
new Nil<Inplace<IO>>() {
2525
}, //
2626
new Type[] { inputOutputType }, //
27-
inputOutputType);
27+
inputOutputType, //
28+
secondaryArgs);
2829
}
2930

3031
public static <IO, I2> BiInplace1<IO, I2> binary1(final OpService ops, final Class<? extends Op> opClass,
31-
final Class<IO> inputOutputType, final Class<I2> input2Type) {
32+
final Class<IO> inputOutputType, final Class<I2> input2Type, final Object... secondaryArgs) {
3233
return ops.findOp( //
33-
opClass,
34+
opClass, //
3435
new Nil<BiInplace1<IO, I2>>() {
3536
}, //
36-
new Type[] { inputOutputType, input2Type}, //
37-
inputOutputType);
37+
new Type[] { inputOutputType, input2Type }, //
38+
inputOutputType, //
39+
secondaryArgs);
3840
}
3941

4042
}

src/test/java/org/scijava/ops/AdaptersTest.java

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,59 +38,54 @@
3838
import org.scijava.ops.math.Sqrt.MathSqrtOp;
3939
import org.scijava.ops.types.Nil;
4040
import org.scijava.ops.util.Adapt;
41-
import org.scijava.ops.util.Inject;
4241

4342
public class AdaptersTest extends AbstractTestEnvironment {
4443

4544
@Test
4645
public void testFunctionAsCommand() {
4746
Class<Double> c = Double.class;
4847
Function<Double, Double> sqrtFunction = ops().findOp( //
49-
MathSqrtOp.class,
50-
new Nil<Function<Double, Double>>() {
48+
MathSqrtOp.class, new Nil<Function<Double, Double>>() {
5149
}, //
5250
new Type[] { c }, //
5351
c//
5452
);
55-
56-
OneToOneCommand<Double, Double> sqrtCommand = Adapt.Functions.asCommand(sqrtFunction);
57-
Inject.Commands.inputs(sqrtCommand, 25.0);
53+
54+
OneToOneCommand<Double, Double> sqrtCommand = Adapt.Functions.asCommand(sqrtFunction, 25.0);
5855
sqrtCommand.run();
5956
assert sqrtCommand.get().equals(5.0);
6057
}
61-
58+
6259
@Test
6360
public void testComputerAsCommand() {
6461
Class<double[]> cArray = double[].class;
6562
Computer<double[], double[]> sqrtComputer = ops().findOp( //
66-
MathSqrtOp.class,
67-
new Nil<Computer<double[], double[]>>() {
63+
MathSqrtOp.class, new Nil<Computer<double[], double[]>>() {
6864
}, //
6965
new Type[] { cArray, cArray }, //
7066
cArray//
7167
);
72-
73-
OneToOneCommand<double[], double[]> sqrtCommand = Adapt.Computers.asCommand(sqrtComputer);
74-
Inject.Commands.inputs(sqrtCommand, new double[] {25, 100, 4});
75-
Inject.Commands.outputs(sqrtCommand, new double[3]);
68+
69+
OneToOneCommand<double[], double[]> sqrtCommand = Adapt.Computers.asCommand(sqrtComputer,
70+
new double[] { 25, 100, 4 }, new double[3]);
7671
sqrtCommand.run();
77-
assert arrayEquals(sqrtCommand.get(), 5.0, 10.0, 2.0);
72+
assert arrayEquals(sqrtCommand.get(), 5.0, 10.0, 2.0);
7873
}
79-
74+
8075
@Test
8176
public void testComputerAsFunction() {
8277
Class<double[]> cArray = double[].class;
8378
final BiComputer<double[], double[], double[]> computer = ops().findOp( //
84-
MathAddOp.class,
85-
new Nil<BiComputer<double[], double[], double[]>>() {
79+
MathAddOp.class, new Nil<BiComputer<double[], double[], double[]>>() {
8680
}, //
8781
new Type[] { cArray, cArray, cArray }, //
8882
cArray//
8983
);
9084

91-
BiFunction<double[], double[], double[]> computerAsFunction = Adapt.Computers.asBiFunction(computer, (arr1, arr2) -> {
92-
return new double[arr1.length];
93-
});
85+
BiFunction<double[], double[], double[]> computerAsFunction = Adapt.Computers.asBiFunction(computer,
86+
(arr1, arr2) -> {
87+
return new double[arr1.length];
88+
});
9489

9590
final double[] a1 = { 3, 5, 7 };
9691
final double[] a2 = { 2, 4, 9 };
@@ -103,18 +98,18 @@ public void testFunctionAsComputer() {
10398
Class<double[]> c = double[].class;
10499
// look up a function: Double result = math.add(Double v1, Double v2)
105100
BiFunction<double[], double[], double[]> function = ops().findOp( //
106-
MathAddOp.class,
107-
new Nil<BiFunction<double[], double[], double[]>>() {
101+
MathAddOp.class, new Nil<BiFunction<double[], double[], double[]>>() {
108102
}, //
109103
new Type[] { c, c }, //
110104
c//
111105
);
112106

113-
BiComputer<double[], double[], double[]> functionAsComputer = Adapt.Functions.asBiComputer(function, (from, to) -> {
114-
for (int i = 0; i < from.length; i++) {
115-
to[i] = from[i];
116-
}
117-
});
107+
BiComputer<double[], double[], double[]> functionAsComputer = Adapt.Functions.asBiComputer(function,
108+
(from, to) -> {
109+
for (int i = 0; i < from.length; i++) {
110+
to[i] = from[i];
111+
}
112+
});
118113

119114
final double[] a1 = { 3, 5, 7 };
120115
final double[] a2 = { 2, 4, 9 };

0 commit comments

Comments
 (0)