public static <A, B, C> PromiseWithoutUpdates<C> lift(
      final Lambda2<A, B, C> f, PromiseWithoutUpdates<A> pa, PromiseWithoutUpdates<B> pb) {
    return Transaction.run(
        () -> {
          class Tuple {
            Tuple(Optional<A> oa, Optional<B> ob) {
              this.oa = oa;
              this.ob = ob;
            }

            Optional<A> oa;
            Optional<B> ob;
          };
          Lambda2<Tuple, Tuple, Tuple> combine =
              (l, r) -> new Tuple(l.oa.isPresent() ? l.oa : r.oa, l.ob.isPresent() ? l.ob : r.ob);
          Lambda1<Tuple, Optional<C>> result =
              t ->
                  t.oa.isPresent() && t.ob.isPresent()
                      ? Optional.of(f.apply(t.oa.get(), t.ob.get()))
                      : Optional.empty();
          Stream<Tuple> sA = pa.sDeliver.map(a -> new Tuple(Optional.of(a), Optional.empty()));
          Cell<Tuple> vA = pa.oValue.map(oa -> new Tuple(oa, Optional.empty()));
          Stream<Tuple> sB = pb.sDeliver.map(b -> new Tuple(Optional.empty(), Optional.of(b)));
          Cell<Tuple> vB = pb.oValue.map(ob -> new Tuple(Optional.empty(), ob));
          Stream<Tuple> sAArrives = sA.snapshot(vB, combine);
          Stream<Tuple> sBArrives = sB.snapshot(vA, combine);
          Stream<Tuple> sSimultaneous = sA.merge(sB, combine);
          Stream<C> sDeliver =
              Stream.filterOptional(sAArrives.orElse(sBArrives).orElse(sSimultaneous).map(result))
                  .once();
          Cell<Optional<C>> oValue = Cell.lift(combine, vA, vB).map(result);
          return new PromiseWithoutUpdates<C>(sDeliver, oValue);
        });
  }
Beispiel #2
0
 void close() {
   while (true) {
     checkRegen();
     if (prioritizedQ.isEmpty()) break;
     Entry e = prioritizedQ.remove();
     entries.remove(e);
     e.action.run(this);
   }
   for (Runnable action : lastQ) action.run();
   lastQ.clear();
   if (postQ != null) {
     while (!postQ.isEmpty()) {
       Iterator<Map.Entry<Integer, Handler<Transaction>>> iter = postQ.entrySet().iterator();
       if (iter.hasNext()) {
         Map.Entry<Integer, Handler<Transaction>> e = iter.next();
         int ix = e.getKey();
         Handler<Transaction> h = e.getValue();
         iter.remove();
         Transaction parent = currentTransaction;
         try {
           if (ix >= 0) {
             Transaction trans = new Transaction();
             currentTransaction = trans;
             try {
               h.run(trans);
             } finally {
               trans.close();
             }
           } else {
             currentTransaction = null;
             h.run(null);
           }
         } finally {
           currentTransaction = parent;
         }
       }
     }
   }
 }
Beispiel #3
0
 /**
  * Run the specified code inside a single transaction, with the contained code returning a value
  * of the parameter type A.
  *
  * <p>In most cases this is not needed, because the primitives always create their own transaction
  * automatically, but it is needed in some circumstances.
  */
 public static <A> A run(Lambda0<A> code) {
   synchronized (transactionLock) {
     // If we are already inside a transaction (which must be on the same
     // thread otherwise we wouldn't have acquired transactionLock), then
     // keep using that same transaction.
     Transaction transWas = currentTransaction;
     try {
       startIfNecessary();
       return code.apply();
     } finally {
       if (transWas == null) currentTransaction.close();
       currentTransaction = transWas;
     }
   }
 }
Beispiel #4
0
 static void run(Handler<Transaction> code) {
   synchronized (transactionLock) {
     // If we are already inside a transaction (which must be on the same
     // thread otherwise we wouldn't have acquired transactionLock), then
     // keep using that same transaction.
     Transaction transWas = currentTransaction;
     try {
       startIfNecessary();
       code.run(currentTransaction);
     } finally {
       if (transWas == null) currentTransaction.close();
       currentTransaction = transWas;
     }
   }
 }
Beispiel #5
0
 /**
  * Execute the specified code after the current transaction is closed, or immediately if there is
  * no current transaction.
  */
 public static void post(final Runnable action) {
   Transaction.run(
       new Handler<Transaction>() {
         public void run(Transaction trans) {
           // -1 will mean it runs before anything split/deferred, and will run
           // outside a transaction context.
           trans.post_(
               -1,
               new Handler<Transaction>() {
                 public void run(Transaction trans) {
                   action.run();
                 }
               });
         }
       });
 }
Beispiel #6
0
  public static void main(String[] args) {
    JFrame frame = new JFrame("form");
    Listener l =
        Transaction.run(
            () -> {
              frame.setLayout(new FlowLayout());
              SButton newClient = new SButton("Open new client");
              frame.add(newClient);
              BackEnd be = new BackEnd();
              Value<String> vName = be.allocate("name", "Joe Bloggs");
              Value<Date> vBirthDate = be.allocate("birthDate", new Date(1980, 5, 1));

              Value<Integer> vYear = vBirthDate.lens(d -> d.year, (dt, y) -> dt.setYear(y));
              Value<Integer> vMonth = vBirthDate.lens(d -> d.month, (dt, y) -> dt.setMonth(y));
              Value<Integer> vDay = vBirthDate.lens(d -> d.day, (dt, y) -> dt.setDay(y));
              Bijection<Integer, String> toString =
                  new Bijection<>(
                      i -> Integer.toString(i),
                      s -> {
                        try {
                          return Integer.parseInt(s);
                        } catch (NumberFormatException e) {
                          return 0;
                        }
                      });
              Value<String> vYearStr = vYear.map(toString);
              Value<String> vMonthStr = vMonth.map(toString);
              Value<String> vDayStr = vDay.map(toString);

              frame.setSize(500, 250);
              frame.setVisible(true);
              return newClient.sClicked.listen(
                  u -> {
                    SwingUtilities.invokeLater(
                        () -> {
                          JFrame client = new JFrame("form client");
                          GridBagLayout gridbag = new GridBagLayout();
                          client.setLayout(gridbag);
                          GridBagConstraints c = new GridBagConstraints();
                          c.fill = GridBagConstraints.HORIZONTAL;
                          c.weighty = 0.0;
                          c.weightx = 1.0;
                          c.gridwidth = 1;
                          c.gridheight = 1;
                          c.gridx = 0;
                          c.gridy = 0;
                          Transaction.runVoid(
                              () -> {
                                c.gridx = 0;
                                client.add(new JLabel("Name"), c);
                                c.gridx = 1;
                                c.gridwidth = 3;
                                client.add(new VTextField(vName, 15), c);
                                c.gridwidth = 1;

                                c.gridy = 1;
                                c.gridx = 0;
                                client.add(new JLabel("Birth date"), c);
                                c.gridx = 1;
                                client.add(new VTextField(vYearStr, 4), c);
                                c.gridx = 2;
                                client.add(new VTextField(vMonthStr, 2), c);
                                c.gridx = 3;
                                client.add(new VTextField(vDayStr, 2), c);

                                client.setSize(300, 100);
                                client.setVisible(true);
                              });
                          client.addWindowListener(
                              new WindowAdapter() {
                                public void windowClosing(WindowEvent e) {
                                  client.dispose();
                                }
                              });
                        });
                  });
            });
    frame.addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            l.unlisten();
            System.exit(0);
          }
        });
    while (true) {
      Runtime.getRuntime().gc();
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
      }
    }
  }
 public final void thenDo(Handler<A> h) {
   Transaction.runVoid(() -> then().listenOnce(h));
 }