All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pi-generator.0.0.13.source-code.TaskBuilderImpl.mustache Maven / Gradle / Ivy

Go to download

Internal module containing an annotation processor for generating the TaskBuilder API

The newest version!
package {{packageName}};

import java.util.List;

import javax.annotation.Generated;

import io.rouz.flo.BuilderUtils.ChainingEval;
import io.rouz.flo.TaskContext.Value;
import io.rouz.flo.TaskBuilder.*;

import static io.rouz.flo.BuilderUtils.appendToList;
import static io.rouz.flo.BuilderUtils.gated;
import static io.rouz.flo.BuilderUtils.gatedVal;
import static io.rouz.flo.BuilderUtils.lazyFlatten;
import static io.rouz.flo.BuilderUtils.lazyList;
import static io.rouz.flo.BuilderUtils.leafEvalFn;
import static io.rouz.flo.Values.toValueList;

/**
 * Package local implementation of the {@link TaskBuilder} tree.
 *
 * These classes tackle the exponential growth of paths that can be taken through the
 * {@link {{interfaceName}}} interfaces by linearizing the implementation through composing functions.
 *
 * The linearization is implemented by letting the next builder in the chain take a
 * {@link ChainingEval}. This evaluator allows the builder to chain onto the evaluation by
 * including more input tasks. The evaluator will finally be used to terminate the builder by
 * enclosing a function into an {@link EvalClosure} for a {@link Task}.
 *
 * See https://github.com/rouzwawi/flo/blob/master/doc/chain.md
 */
@Generated("io.rouz.flo.gen.ApiGeneratorProcessor")
final class {{implClassName}} {

  static  {{interfaceName}} rootBuilder(TaskId taskId, Class type) {
    return new Builder0<>(taskId, type);
  }

  private static class Builder0 extends BaseRefs implements {{interfaceName}} {

    Builder0(TaskId taskId, Class type) {
      super(taskId, type);
    }

    @Override
    public Task process(F0 code) {
      return Task.create(inputs, ops, type, gated(taskId, code::get), taskId);
    }

    @Override
    public Task processWithContext(F1> code) {
      return Task.create(inputs, ops, type, gatedVal(taskId, code::apply), taskId);
    }

    @Override
    public  TaskBuilder1 op(OpProvider opProvider) {
      return new Builder1<>(
          inputs, appendToList(ops, opProvider), taskId, type,
          leafEvalFn(tc -> {
            A aOp = opProvider.provide(tc);
            return tc.immediateValue(f1 -> {
              // call lifecycle methods on op
              Task task = tc.currentTask().get();
              opProvider.preRun(task);
              Value zValue = f1.apply(aOp);
              zValue.consume(z -> opProvider.onSuccess(task, z));
              zValue.onFail(throwable -> opProvider.onFail(task, throwable));

              return zValue;
            });
          }));
    }

    @Override
    public  {{interfaceName}}1 in(Fn> aTask) {
      Fn> aTaskSingleton = Singleton.create(aTask);
      return new Builder1<>(
          lazyFlatten(inputs, lazyList(aTaskSingleton)),
          ops, taskId, type,
          leafEvalFn(tc -> {
            Value aValue = tc.evaluate(aTaskSingleton.get());
            return aValue.map(a -> f1 -> f1.apply(a));
          }));
    }

    @Override
    public  {{interfaceName}}1, Z> ins(Fn>> aTasks) {
      Fn>> aTasksSingleton = Singleton.create(aTasks);
      return new Builder1<>(
          lazyFlatten(inputs, lazyFlatten(aTasksSingleton)),
          ops, taskId, type,
          leafEvalFn(tc -> {
            Value> aListValue = aTasksSingleton.get()
                .stream().map(tc::evaluate).collect(toValueList(tc));
            return aListValue.map(a -> f1 -> f1.apply(a));
          }));
    }
  }

{{#genBuilder}}
  // #############################################################################################
  // {{arity}}<{{typeArgs}}, Z>

  private static class Builder{{arity}}<{{typeArgs}}, Z> extends BaseRefs implements {{interfaceName}}{{arity}}<{{typeArgs}}, Z> {

    private final ChainingEval>, Z> evaluator;

    Builder{{arity}}(
        Fn>> inputs,
        List> ops,
        TaskId taskId,
        Class type,
        ChainingEval>, Z> evaluator) {
      super(inputs, ops, taskId, type);
      this.evaluator = evaluator;
    }

    @Override
    public Task process(F{{arity}}<{{typeArgs}}, Z> code) {
      // local ref to drop ref to Builder instance, b/c serialization
      TaskId taskId = this.taskId;
      ChainingEval>, Z> evaluator = this.evaluator;

      EvalClosure closure = tc -> evaluator.enclose(
          ({{arguments}}) -> tc.invokeProcessFn(taskId, () -> tc.value(() -> code.apply({{arguments}})))
      ).eval(tc);
      return Task.create(inputs, ops, type, closure, taskId);
    }

    @Override
    public Task processWithContext(F{{arityPlus}}> code) {
      // local ref to drop ref to Builder instance, b/c serialization
      TaskId taskId = this.taskId;
      ChainingEval>, Z> evaluator = this.evaluator;

      EvalClosure closure = tc -> evaluator.enclose(
          ({{arguments}}) -> tc.invokeProcessFn(taskId, () -> code.apply(tc, {{arguments}}))
      ).eval(tc);
      return Task.create(inputs, ops, type, closure, taskId);
    }

    @Override
    public <{{nextArg}}> {{interfaceName}}{{arityPlus}}<{{typeArgs}}, {{nextArg}}, Z> op(OpProvider<{{nextArg}}> opProvider) {
      return new Builder{{arityPlus}}<>(
          inputs, appendToList(ops, opProvider), taskId, type,
          evaluator.chain(tc -> {
            {{nextArg}} {{nextArgLow}}Op = opProvider.provide(tc);
            return tc.immediateValue(f{{arityPlus}} -> ({{arguments}}) -> {
              // call lifecycle methods on op
              Task task = tc.currentTask().get();
              opProvider.preRun(task);
              Value zValue = f{{arityPlus}}.apply({{arguments}}, {{nextArgLow}}Op);
              zValue.consume(z -> opProvider.onSuccess(task, z));
              zValue.onFail(throwable -> opProvider.onFail(task, throwable));

              return zValue;
            });
          }));
    }

    @Override
    public <{{nextArg}}> {{interfaceName}}{{arityPlus}}<{{typeArgs}}, {{nextArg}}, Z> in(Fn> nextTask) {
      Fn> nextTaskSingleton = Singleton.create(nextTask);
      return new Builder{{arityPlus}}<>(
          lazyFlatten(inputs, lazyList(nextTaskSingleton)),
          ops, taskId, type,
          evaluator.chain(tc -> {
            Value<{{nextArg}}> nextValue = tc.evaluate(nextTaskSingleton.get());
            return nextValue.map(next -> f{{arityPlus}} -> ({{arguments}}) -> f{{arityPlus}}.apply({{arguments}}, next));
          }));
    }

    @Override
    public <{{nextArg}}> {{interfaceName}}{{arityPlus}}<{{typeArgs}}, List<{{nextArg}}>, Z> ins(Fn>> nextTasks) {
      Fn>> nextTasksSingleton = Singleton.create(nextTasks);
      return new Builder{{arityPlus}}<>(
          lazyFlatten(inputs, lazyFlatten(nextTasksSingleton)),
          ops, taskId, type,
          evaluator.chain(tc -> {
            Value> nextValue = nextTasksSingleton.get()
                .stream().map(tc::evaluate).collect(toValueList(tc));
            return nextValue.map(next -> f{{arityPlus}} -> ({{arguments}}) -> f{{arityPlus}}.apply({{arguments}}, next));
          }));
    }
  }
{{/genBuilder}}

  private static class Builder{{lastArity}}<{{lastTypeArgs}}, Z> extends BaseRefs implements {{interfaceName}}{{lastArity}}<{{lastTypeArgs}}, Z> {

    private final ChainingEval>, Z> evaluator;

    Builder{{lastArity}}(
        Fn>> inputs,
        List> ops,
        TaskId taskId,
        Class type,
        ChainingEval>, Z> evaluator) {
      super(inputs, ops, taskId, type);
      this.evaluator = evaluator;
    }

    @Override
    public Task process(F{{lastArity}}<{{lastTypeArgs}}, Z> code) {
      // local ref to drop ref to Builder instance, b/c serialization
      TaskId taskId = this.taskId;
      ChainingEval>, Z> evaluator = this.evaluator;

      EvalClosure closure = tc -> evaluator.enclose(
          ({{lastArguments}}) -> tc.invokeProcessFn(taskId, () -> tc.immediateValue(code.apply({{lastArguments}})))
      ).eval(tc);
      return Task.create(inputs, ops, type, closure, taskId);
    }

    @Override
    public Task processWithContext(F{{lastArityPlus}}> code) {
      // local ref to drop ref to Builder instance, b/c serialization
      TaskId taskId = this.taskId;
      ChainingEval>, Z> evaluator = this.evaluator;

      EvalClosure closure = tc -> evaluator.enclose(
           ({{lastArguments}}) -> tc.invokeProcessFn(taskId, () -> code.apply(tc, {{lastArguments}}))
      ).eval(tc);
      return Task.create(inputs, ops, type, closure, taskId);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy