Skip to content

Commit 882b346

Browse files
committed
WIP: multi-stage adaptations
1 parent b26ce65 commit 882b346

1 file changed

Lines changed: 68 additions & 23 deletions

File tree

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

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@ public AdaptedOp adaptOp(String opName, OpRef ref) throws OpMatchingException {
316316
List<OpInfo> adaptors = opCache.get("adapt");
317317

318318
// create a priority queue to store suitable transformations.
319-
Comparator<OpCandidate> comp = (OpCandidate i1,
320-
OpCandidate i2) -> i1.opInfo().priority() < i2.opInfo().priority() ? -1
321-
: i1.opInfo().priority() == i2.opInfo().priority() ? 0 : 1;
322-
Queue<OpCandidate> suitableAdaptors = new PriorityQueue<>(comp);
319+
Comparator<OpAdaptor> comp = (OpAdaptor i1,
320+
OpAdaptor i2) -> i1.adaptorInfo().priority() < i2.adaptorInfo().priority() ? -1
321+
: i1.adaptorInfo().priority() == i2.adaptorInfo().priority() ? 0 : 1;
322+
Queue<OpAdaptor> suitableAdaptors = new PriorityQueue<>(comp);
323323

324324
// create an OpCandidate list of suitable adaptors
325325
for (OpInfo adaptor : adaptors) {
@@ -340,33 +340,27 @@ else if (!Types.isAssignable(opType, adaptTo, map)) {
340340
log.debug(adaptor + " is an illegal adaptor Op: must be a Function");
341341
continue;
342342
}
343-
// build the type of fromOp (we know there must be one input because the adaptor
344-
// is a Function)
345-
Type adaptFrom = adaptor.inputs().get(0).getType();
346-
Type refAdaptTo = Types.substituteTypeVariables(adaptTo, map);
347-
Type refAdaptFrom = Types.substituteTypeVariables(adaptFrom, map);
348-
349-
// build the OpRef of the adaptor.
350-
Type refType = Types.parameterize(Function.class, new Type[] { refAdaptFrom, refAdaptTo });
351-
OpRef adaptorRef = new OpRef("adapt", new Type[] { refType }, refAdaptTo, new Type[] { refAdaptFrom });
352-
353343
// make an OpCandidate
354-
suitableAdaptors.add(new OpCandidate(this, log, adaptorRef, adaptor, map));
344+
suitableAdaptors.add(new OpAdaptor(ref, adaptor, map, this, log));
355345
}
356346

357347
while (suitableAdaptors.size() > 0) {
358-
OpCandidate adaptor = suitableAdaptors.remove();
348+
OpAdaptor adaptor = suitableAdaptors.remove();
349+
Object adaptorOp;
350+
// attempt to construct the adaptor
351+
// (N.B. we fail here if, for example, the adaptor cannot resolve its OpDependencies).
352+
try {
353+
adaptorOp = adaptor.constructAdaptor();
354+
} catch (OpMatchingException e) {
355+
continue;
356+
}
359357
try {
360-
// resolve adaptor dependencies and get the adaptor (as a function) //TODO
361-
final List<Object> dependencies = resolveOpDependencies(adaptor);
362-
// adaptor.setStatus(StatusCode.MATCH);
363-
Object adaptorOp = adaptor.opInfo().createOpInstance(dependencies).object();
364358

365359
// grab the first type parameter (from the OpCandidate?) and search for an Op
366360
// that will then be adapted (this will be the first (only) type in the args of
367361
// the adaptor)
368-
Type adaptFrom = adaptor.paddedArgs()[0];
369-
final OpRef inferredRef = inferOpRef(adaptFrom, opName, adaptor.typeVarAssigns());
362+
Type adaptFrom = adaptor.adaptorCandidate().paddedArgs()[0];
363+
final OpRef inferredRef = inferOpRef(adaptFrom, opName, adaptor.adaptorCandidate().typeVarAssigns());
370364
// TODO: export this to another function (also done in findOpInstance).
371365
// We need this here because we need to grab the OpInfo.
372366
// TODO: is there a better way to do this?
@@ -378,8 +372,9 @@ else if (!Types.isAssignable(opType, adaptTo, map)) {
378372
// TODO: can we make this safer?
379373
@SuppressWarnings("unchecked")
380374
Object toOp = ((Function<Object, Object>) adaptorOp).apply(fromOp);
381-
return new AdaptedOp(toOp, srcCandidate.opInfo(), adaptor.opInfo());
375+
return new AdaptedOp(toOp, srcCandidate.opInfo(), adaptor.adaptorCandidate().opInfo());
382376
} catch (OpMatchingException e1) {
377+
// TODO: chain adaptations
383378
continue;
384379
}
385380

@@ -813,4 +808,54 @@ public String toString() {
813808
return nodeToString(root, "root", new StringBuilder(), 0);
814809
}
815810
}
811+
812+
private class OpAdaptor {
813+
814+
//TODO: do we actually need all of these things?
815+
private Object adaptor;
816+
private OpInfo adaptorInfo;
817+
private OpCandidate adaptorCandidate;
818+
private OpRef adaptorRef;
819+
private OpRef srcRef;
820+
private OpRef targetRef;
821+
private OpRef child;
822+
private Map<TypeVariable<?>, Type> typeVarAssigns;
823+
824+
public OpAdaptor(OpRef targetRef, OpInfo adaptorInfo, Map<TypeVariable<?>, Type> typeVarAssgins, OpService ops, LogService log) {
825+
this.targetRef = targetRef;
826+
this.adaptorInfo = adaptorInfo;
827+
this.typeVarAssigns = typeVarAssgins;
828+
Type adaptTo = adaptorInfo.output().getType();
829+
// build the type of fromOp (we know there must be one input because the adaptor
830+
// is a Function)
831+
Type adaptFrom = adaptorInfo.inputs().get(0).getType();
832+
Type refAdaptTo = Types.substituteTypeVariables(adaptTo, typeVarAssigns);
833+
Type refAdaptFrom = Types.substituteTypeVariables(adaptFrom, typeVarAssigns);
834+
835+
// build the OpRef of the adaptor.
836+
Type refType = Types.parameterize(Function.class, new Type[] { refAdaptFrom, refAdaptTo });
837+
OpRef adaptorRef = new OpRef("adapt", new Type[] { refType }, refAdaptTo, new Type[] { refAdaptFrom });
838+
839+
adaptorCandidate = new OpCandidate(ops, log, adaptorRef, adaptorInfo, typeVarAssigns);
840+
}
841+
842+
public Object constructAdaptor() throws OpMatchingException {
843+
// resolve adaptor dependencies and get the adaptor (as a function) //TODO
844+
final List<Object> dependencies = resolveOpDependencies(adaptorCandidate);
845+
// adaptor.setStatus(StatusCode.MATCH);
846+
adaptor= adaptorInfo.createOpInstance(dependencies).object();
847+
return adaptor;
848+
}
849+
850+
public OpInfo adaptorInfo() {return adaptorInfo; }
851+
852+
public OpCandidate adaptorCandidate() {return adaptorCandidate; }
853+
854+
public Object executeAdaptation(Object fromOp) {
855+
Object toOp = ((Function<Object, Object>) adaptor).apply(fromOp);
856+
// TODO: child adaptor support.
857+
return toOp;
858+
}
859+
860+
}
816861
}

0 commit comments

Comments
 (0)