001package conexp.fx.core.util;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2023 Francesco Kriegel
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025import java.util.function.BinaryOperator;
026import java.util.function.Function;
027import java.util.function.Supplier;
028
029import conexp.fx.core.math.Math3;
030
031public class Meter<T> {
032
033  public static final Meter<Long> newNanoStopWatch() {
034    return new Meter<Long>(System::nanoTime, (x, y) -> x - y, Math3::formatNanos);
035  }
036
037  public static final Meter<Long> newMilliStopWatch() {
038    return new Meter<Long>(System::currentTimeMillis, (x, y) -> x - y, Math3::formatMillis);
039  }
040
041  private final Supplier<T>         supplier;
042  private final BinaryOperator<T>   operator;
043  private final Function<T, String> formatter;
044  private T                         origin;
045
046  private Meter(final Supplier<T> supplier, final BinaryOperator<T> operator, final Function<T, String> formatter) {
047    super();
048    this.supplier = supplier;
049    this.operator = operator;
050    this.formatter = formatter;
051    this.origin = supplier.get();
052  }
053
054  public final T measure() {
055    return operator.apply(supplier.get(), origin);
056  }
057
058  public final String measureAndFormat() {
059    return formatter.apply(measure());
060  }
061
062  public final void reset() {
063    this.origin = supplier.get();
064  }
065
066//  public static final class ObservableMeter<T> extends Meter<T> {
067//
068//    private ObservableMeter(final Supplier<T> supplier, final BinaryOperator<T> operator) {
069//      super(supplier, operator);
070//    }
071//  }
072
073}