Improved the code of the graphic engine

This commit is contained in:
Andrea Cavalli 2018-09-02 03:47:24 +02:00
parent 97422ba06a
commit 67db9cc195
41 changed files with 1203 additions and 140 deletions

View File

@ -1,6 +1,9 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter

38
pom.xml
View File

@ -5,7 +5,7 @@
<groupId>org.warp.picalculator</groupId> <groupId>org.warp.picalculator</groupId>
<artifactId>warppi-calculator</artifactId> <artifactId>warppi-calculator</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>0.7-SNAPSHOT</version> <version>0.8-SNAPSHOT</version>
<name>WarpPI Calculator</name> <name>WarpPI Calculator</name>
<url>http://warp.ovh</url> <url>http://warp.ovh</url>
<properties> <properties>
@ -40,14 +40,14 @@
</repository> </repository>
</repositories> </repositories>
<pluginRepositories> <pluginRepositories>
<pluginRepository> <pluginRepository>
<id>1_teavm-dev</id> <id>1_teavm-dev</id>
<url>https://dl.bintray.com/konsoletyper/teavm</url> <url>https://dl.bintray.com/konsoletyper/teavm</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>
<layout>default</layout> <layout>default</layout>
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
<profiles> <profiles>
<profile> <profile>
@ -100,6 +100,13 @@
<artifactId>ecj</artifactId> <artifactId>ecj</artifactId>
<version>4.6.1</version> <version>4.6.1</version>
</dependency> </dependency>
<!--
<dependency>
<groupId>net.sourceforge.streamsupport</groupId>
<artifactId>android-retroflow</artifactId>
<version>1.6.3</version>
</dependency>
-->
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
@ -109,8 +116,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version> <version>2.3.2</version>
<configuration> <configuration>
<source>1.8</source> <source>${maven.compiler.source}</source>
<target>1.8</target> <target>${maven.compiler.target}</target>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
<excludes> <excludes>
<exclude>${buildprops.exclude1}</exclude> <exclude>${buildprops.exclude1}</exclude>
@ -170,8 +177,8 @@
<exclude>org/warp/picalculator/gui/graphicengine/headless8/*</exclude> <exclude>org/warp/picalculator/gui/graphicengine/headless8/*</exclude>
<exclude>org/warp/picalculator/gui/graphicengine/framebuffer/*</exclude> <exclude>org/warp/picalculator/gui/graphicengine/framebuffer/*</exclude>
</excludes> </excludes>
<source>1.8</source> <source>${maven.compiler.source}</source>
<target>1.8</target> <target>${maven.compiler.target}</target>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
</configuration> </configuration>
</plugin> </plugin>
@ -230,11 +237,6 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>3.8</version> <version>3.8</version>
</dependency> </dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.2.1</version>
</dependency>
<!-- <dependency> <groupId>ar.com.hjg</groupId> <artifactId>pngj</artifactId> <!-- <dependency> <groupId>ar.com.hjg</groupId> <artifactId>pngj</artifactId>
<version>2.1.0</version> </dependency> --> <version>2.1.0</version> </dependency> -->
</dependencies> </dependencies>

View File

@ -43,7 +43,7 @@ public class ConsoleUtils {
} }
} }
public void println(int level, String str) { public void println(int level, Object str) {
if (StaticVars.outputLevel >= level) { if (StaticVars.outputLevel >= level) {
final String time = getTimeString(); final String time = getTimeString();
if (StaticVars.outputLevel == 0) { if (StaticVars.outputLevel == 0) {
@ -64,7 +64,7 @@ public class ConsoleUtils {
} }
} }
public void println(int level, String prefix, String str) { public void println(int level, Object prefix, Object str) {
if (StaticVars.outputLevel >= level) { if (StaticVars.outputLevel >= level) {
final String time = getTimeString(); final String time = getTimeString();
if (StaticVars.outputLevel == 0) { if (StaticVars.outputLevel == 0) {
@ -75,7 +75,7 @@ public class ConsoleUtils {
} }
} }
public void println(int level, String... parts) { public void println(int level, Object... parts) {
if (StaticVars.outputLevel >= level) { if (StaticVars.outputLevel >= level) {
final String time = getTimeString(); final String time = getTimeString();
String output = ""; String output = "";

View File

@ -36,7 +36,6 @@
package org.warp.picalculator.deps; package org.warp.picalculator.deps;
import java.util.function.IntUnaryOperator; import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator; import java.util.function.IntBinaryOperator;
import sun.misc.Unsafe;
/** /**
* An {@code int} value that may be updated atomically. See the * An {@code int} value that may be updated atomically. See the

View File

@ -24,6 +24,8 @@ import org.warp.picalculator.Utils;
import org.warp.picalculator.deps.DSemaphore; import org.warp.picalculator.deps.DSemaphore;
import org.warp.picalculator.deps.StorageUtils; import org.warp.picalculator.deps.StorageUtils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.flow.BehaviorSubject;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
@ -43,6 +45,7 @@ public class HtmlEngine implements GraphicEngine {
private HtmlRenderer renderer; private HtmlRenderer renderer;
private int width = -1, height = -1; private int width = -1, height = -1;
private final int frameTime = (int) (1000d/10d); private final int frameTime = (int) (1000d/10d);
private final BehaviorSubject<Integer[]> onResize = BehaviorSubject.create();
@Override @Override
public int[] getSize() { public int[] getSize() {
@ -194,11 +197,6 @@ public class HtmlEngine implements GraphicEngine {
} }
} }
@Override
public boolean wasResized() {
return false;
}
@Override @Override
public int getWidth() { public int getWidth() {
if (width == -1) { if (width == -1) {
@ -293,4 +291,9 @@ public class HtmlEngine implements GraphicEngine {
return true; return true;
} }
@Override
public Observable<Integer[]> onResize() {
return onResize;
}
} }

View File

@ -1,13 +1,10 @@
package org.warp.picalculator; package org.warp.picalculator;
import java.util.Iterator; import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import org.warp.picalculator.boot.StartupArguments; import org.warp.picalculator.boot.StartupArguments;
import org.warp.picalculator.flow.Observable;
import io.reactivex.Maybe; import org.warp.picalculator.flow.BehaviorSubject;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;
public class StaticVars { public class StaticVars {
public static final boolean enableVBO = true; public static final boolean enableVBO = true;
@ -17,19 +14,19 @@ public class StaticVars {
public static boolean haxMode = true; public static boolean haxMode = true;
public static final boolean zoomed = true; public static final boolean zoomed = true;
public static int[] screenPos = new int[] { 0, 0 }; public static int[] screenPos = new int[] { 0, 0 };
public static final int[] screenSize = new int[] { 480, 320 }; public static final int[] screenSize = new int[] {480, 320};
public static boolean debugOn; public static boolean debugOn;
public static int outputLevel = 0; public static int outputLevel = 0;
public static boolean debugWindow2x = false; public static boolean debugWindow2x = false;
public static BehaviorSubject<Float> windowZoom = BehaviorSubject.createDefault(2F); public static BehaviorSubject<Float> windowZoom = BehaviorSubject.create(2F);
public static Observable<Float> windowZoom$ = windowZoom.map((val) -> { public static Function<Float, Float> windowZoomFunction = (val) -> {
if (StaticVars.debugOn & StaticVars.debugWindow2x) { if (StaticVars.debugOn & StaticVars.debugWindow2x) {
return val + 1; return val + 1;
} else { } else {
return val; return val;
} }
}); };
public static Iterator<Float> windowZoomValue = windowZoom$.blockingMostRecent(2F).iterator(); public static Observable<Float> windowZoom$ = windowZoom.map(windowZoomFunction);
public static StartupArguments startupArguments; public static StartupArguments startupArguments;
private StaticVars() { private StaticVars() {

View File

@ -1,15 +1,9 @@
package org.warp.picalculator.boot; package org.warp.picalculator.boot;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Stream;
import org.warp.picalculator.ConsoleUtils; import org.warp.picalculator.ConsoleUtils;
import org.warp.picalculator.PICalculator; import org.warp.picalculator.PICalculator;
import org.warp.picalculator.Utils; import org.warp.picalculator.flow.TestFlow;
import org.warp.picalculator.device.PIHardwareDisplay;
import org.warp.picalculator.gui.CalculatorHUD;
import org.warp.picalculator.gui.screens.LoadingScreen;
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

View File

@ -813,7 +813,7 @@ public class Keyboard {
refresh = true; refresh = true;
break; break;
case ZOOM_MODE: case ZOOM_MODE:
float newZoom = (StaticVars.windowZoom.blockingLatest().iterator().next().floatValue() % 3) + 1; float newZoom = (StaticVars.windowZoom.getLastValue() % 3) + 1;
StaticVars.windowZoom.onNext(newZoom); StaticVars.windowZoom.onNext(newZoom);
ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Keyboard", "Zoom: " + newZoom); ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Keyboard", "Zoom: " + newZoom);
// StaticVars.windowZoom = ((StaticVars.windowZoom - 0.5f) % 2f) + 1f; // StaticVars.windowZoom = ((StaticVars.windowZoom - 0.5f) % 2f) + 1f;

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.flow;
public interface Action0 {
void call();
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.flow;
public interface Action1<T> {
void call(T t);
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.flow;
public interface Action2<T, U> {
void call(T t, U u);
}

View File

@ -0,0 +1,98 @@
package org.warp.picalculator.flow;
import java.util.LinkedList;
import java.util.List;
public class BehaviorSubject<T> extends Subject<T> {
private T lastValue;
private boolean lastValueSet;
protected BehaviorSubject() {
super();
lastValue = null;
lastValueSet = false;
}
protected BehaviorSubject(T initialValue) {
super();
lastValue = initialValue;
lastValueSet = true;
}
public final static <T> BehaviorSubject<T> create() {
return new BehaviorSubject<>();
}
public final static <T> BehaviorSubject<T> create(T initialValue) {
return new BehaviorSubject<T>(initialValue);
}
@Override
public void onComplete() {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onComplete();
}
}
@Override
public void onError(Throwable e) {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onError(e);
};
}
@Override
public void onNext(T t) {
lastValue = t;
lastValueSet = true;
for (Subscriber<? super T> sub : this.subscribers) {
sub.onNext(t);
}
}
@Override
Throwable getThrowable() {
// TODO Auto-generated method stub
return null;
}
@Override
boolean hasComplete() {
// TODO Auto-generated method stub
return false;
}
@Override
boolean hasObservers() {
// TODO Auto-generated method stub
return false;
}
@Override
boolean hasThrowable() {
// TODO Auto-generated method stub
return false;
}
@Override
Subject<T> toSerialized() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onSubscribe(Disposable d) {
@SuppressWarnings("unchecked")
DisposableOfSubscriber ds = (DisposableOfSubscriber) d;
Subscriber<? super T> s = ds.getSubscriber();
if (lastValueSet) {
s.onNext(lastValue);
}
}
public T getLastValue() {
return lastValue;
}
}

View File

@ -0,0 +1,30 @@
package org.warp.picalculator.flow;
import java.util.Objects;
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}

View File

@ -0,0 +1,7 @@
package org.warp.picalculator.flow;
public interface Disposable {
public void dispose();
public boolean isDisposed();
}

View File

@ -0,0 +1,48 @@
package org.warp.picalculator.flow;
import java.util.LinkedList;
import java.util.List;
import org.warp.picalculator.PlatformUtils;
public class IntervalsManager {
private static List<ObservableInterval> intervals = new LinkedList<>();
static {
startChecker();
}
private IntervalsManager() {
}
public static void register(ObservableInterval t) {
synchronized (intervals) {
if (!intervals.contains(t)) {
intervals.add(t);
}
}
}
private static void startChecker() {
Thread t = new Thread(() -> {
try {
while (true) {
Thread.sleep(1000);
for (ObservableInterval interval : intervals) {
if (interval.running) {
if (interval.subscribers.size() <= 0) {
interval.stopInterval();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
PlatformUtils.setDaemon(t);
PlatformUtils.setThreadName(t, "Intervals Manager");
t.start();
}
}

View File

@ -0,0 +1,166 @@
package org.warp.picalculator.flow;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public abstract class Observable<T> implements ObservableSource<T> {
protected List<Subscriber<? super T>> subscribers = new LinkedList<>();
public Disposable subscribe() {
return null;
}
public Disposable subscribe(Action1<? super T> onNext) {
return subscribe(createSubscriber(onNext));
}
protected Observable<T>.DisposableOfSubscriber createDisposable(Subscriber<? super T> sub) {
return new DisposableOfSubscriber(sub);
}
public Disposable subscribe(Action1<? super T> onNext, Action1<Throwable> onError) {
return subscribe(createSubscriber(onNext, onError));
}
public Disposable subscribe(Action1<? super T> onNext, Action1<Throwable> onError, Action0 onCompleted) {
return subscribe(createSubscriber(onNext, onError, onCompleted));
}
public void subscribe(Observer<? super T> obs) {
subscribe(createSubscriber(obs));
}
public Disposable subscribe(Subscriber<? super T> sub) {
subscribers.add(sub);
return createDisposable(sub);
}
protected Subscriber<T> createSubscriber(Action1<? super T> onNext) {
return new Subscriber<T>() {
@Override public void onSubscribe(Subscription s) {}
public void onNext(T t) {
onNext.call(t);
}
};
}
protected Subscriber<T> createSubscriber(Action1<? super T> onNext, Action1<Throwable> onError) {
return new Subscriber<T>() {
@Override public void onSubscribe(Subscription s) {}
public void onNext(T t) {
onNext.call(t);
}
@Override
public void onError(Throwable t) {
onError.call(t);
}
};
}
protected Subscriber<T> createSubscriber(Action1<? super T> onNext, Action1<Throwable> onError, Action0 onCompl) {
return new Subscriber<T>() {
@Override public void onSubscribe(Subscription s) {}
public void onNext(T t) {
onNext.call(t);
}
@Override
public void onError(Throwable t) {
onError.call(t);
}
@Override
public void onComplete() {
onCompl.call();
}
};
}
protected Subscriber<T> createSubscriber(Observer<? super T> obs) {
return new Subscriber<T>() {
@Override public void onSubscribe(Subscription s) {}
public void onNext(T t) {
obs.onNext(t);
}
@Override
public void onError(Throwable t) {
obs.onError(t);
}
@Override
public void onComplete() {
obs.onComplete();
}
};
}
public static final <T> Observable<T> merge(Observable<T> a, Observable<T> b) {
return new ObservableMerged<>(a, b);
}
@Deprecated
public static final <T> Observable<T> of(Observable<T> a) {
return null;
}
public final <U> Observable<U> map(Function<T, U> f) {
return new ObservableMap<T, U>(this, f);
}
public static final <T, U> Observable<Pair<T,U>> combineLatest(Observable<T> a, Observable<U> b) {
return new ObservableCombinedLatest<>(a, b);
}
public static final <T, U> Observable<Pair<T,U>> combineChanged(Observable<T> a, Observable<U> b) {
return new ObservableCombinedChanged<>(a, b);
}
public static final <T, U> Observable<Pair<T,U>> zip(Observable<T> a, Observable<U> b) {
return new ObservableZipped<>(a, b);
}
public static final Observable<Long> interval(long interval) {
return new ObservableInterval(interval);
}
protected class DisposableOfSubscriber implements Disposable {
private final Subscriber<? super T> sub;
public DisposableOfSubscriber(Subscriber<? super T> sub) {
this.sub = sub;
}
protected Subscriber<? super T> getSubscriber() {
return sub;
}
protected Observable<T> getObservable() {
return Observable.this;
}
@Override
public void dispose() {
if (isDisposed()) {
throw new RuntimeException("Already disposed!");
}
subscribers.remove(sub);
Observable.this.onDisposed(sub);
}
@Override
public boolean isDisposed() {
return !subscribers.contains(sub);
}
}
public Observable<T> doOnNext(Action1<T> onNext) {
Subject<T> onNextSubject = BehaviorSubject.create();
this.subscribe((val) -> {
onNext.call(val);
onNextSubject.onNext(val);
});
return onNextSubject;
}
public void onDisposed(Subscriber<? super T> sub) {
}
}

View File

@ -0,0 +1,72 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public class ObservableCombinedChanged<T, U> extends Observable<Pair<T, U>> {
private volatile boolean initialized = false;
private Observable<T> a;
private Observable<U> b;
private Disposable disposableA;
private Disposable disposableB;
private Subject<Pair<T, U>> pairSubject;
private Subject<T> mapSubject;
public ObservableCombinedChanged(Observable<T> a, Observable<U> b) {
super();
this.a = a;
this.b = b;
this.pairSubject = SimpleSubject.create();
}
private void initialize() {
this.disposableA = a.subscribe((t) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onNext(Pair.of(t, null));
}
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
this.disposableB = b.subscribe((t) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onNext(Pair.of(null, t));
};
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
}
private void chechInitialized() {
if (!initialized) {
initialized = true;
initialize();
}
}
@Override
public Disposable subscribe(Subscriber<? super Pair<T,U>> sub) {
Disposable disp = super.subscribe(sub);
chechInitialized();
return disp;
}
@Override
public void onDisposed(Subscriber<? super Pair<T, U>> sub) {
super.onDisposed(sub);
this.disposableA.dispose();
this.disposableB.dispose();
}
}

View File

@ -0,0 +1,84 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public class ObservableCombinedLatest<T, U> extends Observable<Pair<T, U>> {
private volatile boolean initialized = false;
private Observable<T> a;
private Observable<U> b;
private Disposable disposableA;
private Disposable disposableB;
private volatile T lastA;
private volatile U lastB;
private volatile boolean didAOneTime;
private volatile boolean didBOneTime;
private Subject<Pair<T, U>> pairSubject;
private Subject<T> mapSubject;
public ObservableCombinedLatest(Observable<T> a, Observable<U> b) {
super();
this.a = a;
this.b = b;
this.pairSubject = SimpleSubject.create();
}
private void initialize() {
this.disposableA = a.subscribe((t) -> {
lastA = t;
didAOneTime = true;
receivedNext();
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
this.disposableB = b.subscribe((t) -> {
lastB = t;
didBOneTime = true;
receivedNext();
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
}
private void receivedNext() {
if (didAOneTime && didBOneTime) {
this.subscribers.forEach(sub -> {
sub.onNext(Pair.of(lastA, lastB));
});
}
}
private void chechInitialized() {
if (!initialized) {
initialized = true;
initialize();
}
}
@Override
public Disposable subscribe(Subscriber<? super Pair<T,U>> sub) {
Disposable disp = super.subscribe(sub);
chechInitialized();
return disp;
}
@Override
public void onDisposed(Subscriber<? super Pair<T, U>> sub) {
super.onDisposed(sub);
this.disposableA.dispose();
this.disposableB.dispose();
}
}

View File

@ -0,0 +1,71 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
import org.warp.picalculator.PlatformUtils;
public class ObservableInterval extends Observable<Long> {
private final long interval;
volatile boolean running;
volatile Thread timeThread;
protected ObservableInterval(long interval) {
super();
this.interval = interval;
try {
startInterval();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void stopInterval() {
if (running) {
running = false;
this.timeThread.interrupt();
}
}
@Override
public Disposable subscribe(Subscriber<? super Long> sub) {
try {
startInterval();
} catch (InterruptedException e) {
e.printStackTrace();
}
return super.subscribe(sub);
}
void startInterval() throws InterruptedException {
if (running == false) {
while (timeThread != null) {
Thread.sleep(100);
}
timeThread = new Thread(() -> {
try {
while(!Thread.interrupted()) {
for (Subscriber<? super Long> sub : this.subscribers) {
sub.onNext(System.currentTimeMillis());
}
Thread.sleep(interval);
}
} catch (InterruptedException e) {}
timeThread = null;
});
PlatformUtils.setThreadName(timeThread, "ObservableTimer");
timeThread.start();
running = true;
}
}
public static ObservableInterval create(long l) {
return new ObservableInterval(l);
}
@Override
public void onDisposed(Subscriber<? super Long> sub) {
super.onDisposed(sub);
stopInterval();
}
}

View File

@ -0,0 +1,55 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public class ObservableMap<T, U> extends Observable<U> {
private Observable<T> originalObservable;
private Function<T, U> mapAction;
private volatile boolean initialized = false;
private Disposable mapDisposable;
private Subject<T> mapSubject;
public ObservableMap(Observable<T> originalObservable, Function<T, U> mapAction) {
super();
this.originalObservable = originalObservable;
this.mapAction = mapAction;
this.mapSubject = SimpleSubject.create();
}
private void initialize() {
this.mapDisposable = originalObservable.subscribe((t) -> {
for (Subscriber<? super U> sub : this.subscribers) {
sub.onNext(mapAction.apply(t));
};
}, (e) -> {
for (Subscriber<? super U> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super U> sub : this.subscribers) {
sub.onComplete();
};
});
}
private void chechInitialized() {
if (!initialized) {
initialized = true;
initialize();
}
}
@Override
public Disposable subscribe(Subscriber<? super U> sub) {
Disposable disp = super.subscribe(sub);
chechInitialized();
return disp;
}
@Override
public void onDisposed(Subscriber<? super U> sub) {
super.onDisposed(sub);
mapDisposable.dispose();
}
}

View File

@ -0,0 +1,71 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public class ObservableMerged<T> extends Observable<T> {
private Observable<T> originalObservableA;
private Observable<T> originalObservableB;
private volatile boolean initialized = false;
private Disposable mapDisposableA;
private Disposable mapDisposableB;
private Subject<T> mapSubject;
public ObservableMerged(Observable<T> originalObservableA, Observable<T> originalObservableB) {
super();
this.originalObservableA = originalObservableA;
this.originalObservableB = originalObservableB;
this.mapSubject = SimpleSubject.create();
}
private void initialize() {
this.mapDisposableA = originalObservableA.subscribe((t) -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onNext(t);
};
}, (e) -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onComplete();
};
});
this.mapDisposableB = originalObservableB.subscribe((t) -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onNext(t);
};
}, (e) -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onComplete();
};
});
}
private void chechInitialized() {
if (!initialized) {
initialized = true;
initialize();
}
}
@Override
public Disposable subscribe(Subscriber<? super T> sub) {
Disposable disp = super.subscribe(sub);
chechInitialized();
return disp;
}
@Override
public void onDisposed(Subscriber<? super T> sub) {
super.onDisposed(sub);
this.mapDisposableA.dispose();
this.mapDisposableB.dispose();
}
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.flow;
public interface ObservableSource<T> {
public void subscribe(Observer<? super T> observer);
}

View File

@ -0,0 +1,86 @@
package org.warp.picalculator.flow;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
public class ObservableZipped<T, U> extends Observable<Pair<T, U>> {
private volatile boolean initialized = false;
private Observable<T> a;
private Observable<U> b;
private Disposable disposableA;
private Disposable disposableB;
private volatile T lastA;
private volatile U lastB;
private volatile boolean didA;
private volatile boolean didB;
private Subject<Pair<T, U>> pairSubject;
private Subject<T> mapSubject;
public ObservableZipped(Observable<T> a, Observable<U> b) {
super();
this.a = a;
this.b = b;
this.pairSubject = SimpleSubject.create();
}
private void initialize() {
this.disposableA = a.subscribe((t) -> {
lastA = t;
didA = true;
receivedNext();
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
this.disposableB = b.subscribe((t) -> {
lastB = t;
didB = true;
receivedNext();
}, (e) -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onError(e);
};
}, () -> {
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onComplete();
};
});
}
private void receivedNext() {
if (didA && didB) {
didA = false;
didB = false;
for (Subscriber<? super Pair<T, U>> sub : this.subscribers) {
sub.onNext(Pair.of(lastA, lastB));
};
}
}
private void chechInitialized() {
if (!initialized) {
initialized = true;
initialize();
}
}
@Override
public Disposable subscribe(Subscriber<? super Pair<T,U>> sub) {
Disposable disp = super.subscribe(sub);
chechInitialized();
return disp;
}
@Override
public void onDisposed(Subscriber<? super Pair<T, U>> sub) {
super.onDisposed(sub);
this.disposableA.dispose();
this.disposableB.dispose();
}
}

View File

@ -0,0 +1,8 @@
package org.warp.picalculator.flow;
public interface Observer<T> {
public void onComplete();
public void onError(Throwable e);
public void onNext(T t);
public void onSubscribe(Disposable d);
}

View File

@ -0,0 +1,72 @@
package org.warp.picalculator.flow;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
public class SimpleSubject<T> extends Subject<T> {
protected SimpleSubject() {
}
public final static <T> SimpleSubject<T> create() {
return new SimpleSubject<>();
}
@Override
public void onComplete() {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onComplete();
};
}
@Override
public void onError(Throwable e) {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onError(e);
};
}
@Override
public void onNext(T t) {
for (Subscriber<? super T> sub : this.subscribers) {
sub.onNext(t);
};
}
@Override
Throwable getThrowable() {
// TODO Auto-generated method stub
return null;
}
@Override
boolean hasComplete() {
// TODO Auto-generated method stub
return false;
}
@Override
boolean hasObservers() {
// TODO Auto-generated method stub
return false;
}
@Override
boolean hasThrowable() {
// TODO Auto-generated method stub
return false;
}
@Override
Subject<T> toSerialized() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onSubscribe(Disposable d) {
}
}

View File

@ -0,0 +1,36 @@
package org.warp.picalculator.flow;
public abstract class Subject<T> extends Observable<T> implements Observer<T> {
abstract Throwable getThrowable();
abstract boolean hasComplete();
abstract boolean hasObservers();
abstract boolean hasThrowable();
abstract Subject<T> toSerialized();
@Override
public Disposable subscribe(Action1<? super T> onNext) {
return subscribe(createSubscriber(onNext));
}
@Override
public Disposable subscribe(Action1<? super T> onNext, Action1<Throwable> onError) {
return subscribe(createSubscriber(onNext, onError));
}
@Override
public Disposable subscribe(Action1<? super T> onNext, Action1<Throwable> onError, Action0 onCompl) {
return subscribe(createSubscriber(onNext, onError, onCompl));
}
@Override
public void subscribe(Observer<? super T> obs) {
subscribe(createSubscriber(obs));
}
@Override
public Disposable subscribe(Subscriber<? super T> sub) {
Disposable disp = super.subscribe(sub);
this.onSubscribe(disp);
return disp;
}
}

View File

@ -0,0 +1,8 @@
package org.warp.picalculator.flow;
public interface Subscriber<T> {
default void onComplete() {}
default void onError(Throwable t) {}
void onNext(T t);
void onSubscribe(Subscription s);
}

View File

@ -0,0 +1,6 @@
package org.warp.picalculator.flow;
public interface Subscription {
void cancel();
void request(long n);
}

View File

@ -0,0 +1,138 @@
package org.warp.picalculator.flow;
import org.apache.commons.lang3.tuple.Pair;
public class TestFlow {
public static void main(String[] args) {
try {
BehaviorSubject<Float> subject0 = BehaviorSubject.create(0f);
Disposable s00 = subject0.subscribe((val) -> {
System.out.println(val);
});
Thread.sleep(100);
subject0.onNext(1f);
subject0.onNext(2f);
subject0.onNext(3f);
subject0.onNext(4f);
subject0.onNext(5f);
subject0.onNext(60f);
s00.dispose();
subject0.onNext(60f);
subject0.onNext(7f);
subject0.onComplete();
System.out.println("items sent.");
Subject<Float> subject1 = BehaviorSubject.create(0f);
Disposable s01 = subject1.map((val) -> val + 1).subscribe((val) -> {
System.out.println(val);
});
Thread.sleep(100);
subject1.onNext(1f);
subject1.onNext(2f);
subject1.onNext(3f);
subject1.onNext(4f);
subject1.onNext(5f);
subject1.onNext(60f);
s01.dispose();
subject1.onNext(60f);
subject1.onNext(7f);
subject1.onComplete();
System.out.println("items sent.");
BehaviorSubject<Float> subjectA = BehaviorSubject.create();
BehaviorSubject<Float> subjectB = BehaviorSubject.create();
Observable<Float> observable = Observable.merge(subjectA, subjectB);
Disposable s1 = observable.subscribe((val) -> {
System.out.println(val);
});
Thread.sleep(100);
subjectA.onNext(1f);
subjectA.onNext(2f);
subjectA.onNext(3f);
subjectA.onNext(4f);
subjectA.onNext(5f);
subjectB.onNext(60f);
s1.dispose();
subjectB.onNext(60f);
subjectA.onNext(7f);
subjectB.onComplete();
subjectA.onComplete();
Thread.sleep(100);
System.out.println("no more news subscribers left, closing publisher..");
BehaviorSubject<Float> subjectC = BehaviorSubject.create();
BehaviorSubject<Float> subjectD = BehaviorSubject.create();
Observable<Pair<Float, Float>> observableCombined = Observable.combineLatest(subjectC, subjectD);
System.out.println("Combined observable: " + observableCombined.toString());
Disposable s2 = observableCombined.subscribe((val) -> {
System.out.println(val);
});
Thread.sleep(100);
subjectC.onNext(1f);
subjectC.onNext(2f);
subjectC.onNext(3f);
subjectC.onNext(4f);
subjectC.onNext(5f);
subjectD.onNext(60f);
subjectD.onNext(60f);
subjectC.onNext(7f);
s2.dispose();
subjectD.onComplete();
subjectC.onComplete();
System.out.println("items sent.");
ObservableInterval timA = ObservableInterval.create(100L);
Disposable d = timA.subscribe((t) -> {
System.out.println(t);
});
Thread.sleep(500);
d.dispose();
System.out.println("items sent.");
ObservableInterval subjectE = ObservableInterval.create(100L);
BehaviorSubject<Float> subjectF = BehaviorSubject.create();
Observable<Pair<Long, Float>> observableZipped = Observable.zip(subjectE, subjectF);
System.out.println("Zipped observable: " + observableZipped.toString());
Disposable s3 = observableZipped.subscribe((val) -> {
System.out.println(val);
});
Thread.sleep(100);
subjectF.onNext(1f);
Thread.sleep(100);
subjectF.onNext(2f);
Thread.sleep(100);
subjectF.onNext(3f);
Thread.sleep(100);
subjectF.onNext(4f);
Thread.sleep(100);
subjectF.onNext(5f);
Thread.sleep(100);
subjectF.onNext(60f);
Thread.sleep(100);
subjectF.onNext(60f);
Thread.sleep(100);
subjectF.onNext(7f);
Thread.sleep(500);
s3.dispose();
subjectF.onComplete();
System.out.println("items sent.");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -22,6 +22,7 @@ import org.warp.picalculator.event.TouchEvent;
import org.warp.picalculator.event.TouchEventListener; import org.warp.picalculator.event.TouchEventListener;
import org.warp.picalculator.event.TouchMoveEvent; import org.warp.picalculator.event.TouchMoveEvent;
import org.warp.picalculator.event.TouchStartEvent; import org.warp.picalculator.event.TouchStartEvent;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
@ -30,8 +31,6 @@ import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.nogui.NoGuiEngine; import org.warp.picalculator.gui.graphicengine.nogui.NoGuiEngine;
import org.warp.picalculator.gui.screens.Screen; import org.warp.picalculator.gui.screens.Screen;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry; import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -401,9 +400,9 @@ public final class DisplayManager implements RenderingLoop {
DSystem.exit(0); DSystem.exit(0);
} }
Observable<Long> workTimer = Observable.interval(tickDuration, TimeUnit.MILLISECONDS); Observable<Long> workTimer = Observable.interval(tickDuration);
Observable.combineLatest(workTimer, engine.onResize(), (time, windowSize) -> windowSize).subscribe((windowSize) -> { Observable.combineChanged(workTimer, engine.onResize()).subscribe((pair) -> {
double dt = 0; double dt = 0;
final long newtime = System.nanoTime(); final long newtime = System.nanoTime();
if (precTime == -1) { if (precTime == -1) {
@ -413,8 +412,11 @@ public final class DisplayManager implements RenderingLoop {
} }
precTime = newtime; precTime = newtime;
StaticVars.screenSize[0] = windowSize[0]; if (pair.getRight() != null) {
StaticVars.screenSize[1] = windowSize[1]; Integer[] windowSize = pair.getRight();
StaticVars.screenSize[0] = windowSize[0];
StaticVars.screenSize[1] = windowSize[1];
}
screen.beforeRender((float) (dt / 1000d)); screen.beforeRender((float) (dt / 1000d));
}); });

View File

@ -3,7 +3,7 @@ package org.warp.picalculator.gui.graphicengine;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import io.reactivex.Observable; import org.warp.picalculator.flow.Observable;
public interface GraphicEngine { public interface GraphicEngine {

View File

@ -8,14 +8,13 @@ import java.util.concurrent.Semaphore;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.device.HardwareDevice; import org.warp.picalculator.device.HardwareDevice;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.Skin;
import io.reactivex.Observable;
public class CPUEngine implements GraphicEngine { public class CPUEngine implements GraphicEngine {
private SwingWindow INSTANCE; private SwingWindow INSTANCE;

View File

@ -29,11 +29,11 @@ import org.warp.picalculator.event.TouchEndEvent;
import org.warp.picalculator.event.TouchMoveEvent; import org.warp.picalculator.event.TouchMoveEvent;
import org.warp.picalculator.event.TouchPoint; import org.warp.picalculator.event.TouchPoint;
import org.warp.picalculator.event.TouchStartEvent; import org.warp.picalculator.event.TouchStartEvent;
import org.warp.picalculator.flow.BehaviorSubject;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class SwingWindow extends JFrame { public class SwingWindow extends JFrame {
@ -55,7 +55,8 @@ public class SwingWindow extends JFrame {
// Transparent 16 x 16 pixel cursor image. // Transparent 16 x 16 pixel cursor image.
final BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); final BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
mult = StaticVars.windowZoomValue.next().intValue(); mult = StaticVars.windowZoomFunction.apply(StaticVars.windowZoom.getLastValue()).intValue();
if (StaticVars.debugOn) { if (StaticVars.debugOn) {
if (Utils.debugThirdScreen) { if (Utils.debugThirdScreen) {
this.setLocation(2880, 900); this.setLocation(2880, 900);

View File

@ -10,6 +10,8 @@ import org.warp.picalculator.MmapByteBuffer;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.TestJNI; import org.warp.picalculator.TestJNI;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.flow.BehaviorSubject;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
@ -18,9 +20,6 @@ import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont; import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
import org.warp.picalculator.gui.graphicengine.cpu.CPUSkin; import org.warp.picalculator.gui.graphicengine.cpu.CPUSkin;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;
public class FBEngine implements GraphicEngine { public class FBEngine implements GraphicEngine {
private static final int FB_DISPLAY_WIDTH = 320; private static final int FB_DISPLAY_WIDTH = 320;
@ -59,7 +58,7 @@ public class FBEngine implements GraphicEngine {
@Override @Override
public void create(Runnable onInitialized) { public void create(Runnable onInitialized) {
onResize = BehaviorSubject.createDefault(new Integer[] {SIZE[0], SIZE[1]}); onResize = BehaviorSubject.create(new Integer[] {SIZE[0], SIZE[1]});
realFb = jni.retrieveBuffer(); realFb = jni.retrieveBuffer();
final long fbLen = realFb.getLength(); final long fbLen = realFb.getLength();
fb = (MappedByteBuffer) ByteBuffer.allocateDirect((int) fbLen); fb = (MappedByteBuffer) ByteBuffer.allocateDirect((int) fbLen);

View File

@ -10,6 +10,7 @@ import java.util.concurrent.Semaphore;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
@ -18,10 +19,6 @@ import org.warp.picalculator.gui.graphicengine.Skin;
import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.Texture;
import io.reactivex.Observable;
import io.reactivex.processors.BehaviorProcessor;
import io.reactivex.subjects.BehaviorSubject;
public class GPUEngine implements GraphicEngine { public class GPUEngine implements GraphicEngine {
private volatile boolean initialized = false; private volatile boolean initialized = false;
@ -63,8 +60,6 @@ public class GPUEngine implements GraphicEngine {
@Override @Override
public void setDisplayMode(int ww, int wh) { public void setDisplayMode(int ww, int wh) {
size[0] = ww;
size[1] = wh;
wnd.setSize(ww, wh); wnd.setSize(ww, wh);
} }
@ -89,7 +84,7 @@ public class GPUEngine implements GraphicEngine {
@Override @Override
public Observable<Integer[]> onResize() { public Observable<Integer[]> onResize() {
return wnd.onResize; return wnd.onResizeEvent;
} }
@Override @Override

View File

@ -28,12 +28,8 @@
package org.warp.picalculator.gui.graphicengine.gpu; package org.warp.picalculator.gui.graphicengine.gpu;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.warp.picalculator.ConsoleUtils;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.device.HardwareDevice; import org.warp.picalculator.device.HardwareDevice;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
@ -42,11 +38,11 @@ import org.warp.picalculator.event.TouchEndEvent;
import org.warp.picalculator.event.TouchMoveEvent; import org.warp.picalculator.event.TouchMoveEvent;
import org.warp.picalculator.event.TouchPoint; import org.warp.picalculator.event.TouchPoint;
import org.warp.picalculator.event.TouchStartEvent; import org.warp.picalculator.event.TouchStartEvent;
import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.flow.BehaviorSubject;
import org.warp.picalculator.flow.SimpleSubject;
import org.warp.picalculator.flow.Subject;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import com.jogamp.newt.event.GestureHandler.GestureEvent;
import com.jogamp.newt.event.GestureHandler.GestureListener;
import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.MouseEvent;
@ -67,15 +63,6 @@ import com.jogamp.opengl.fixedfunc.GLPointerFunc;
import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.Texture;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.processors.BehaviorProcessor;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.ReplaySubject;
import io.reactivex.subjects.Subject;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
/** /**
@ -95,26 +82,46 @@ class NEWTWindow implements GLEventListener {
public volatile boolean refreshViewport; public volatile boolean refreshViewport;
public List<TouchPoint> touches = new ObjectArrayList<>(); public List<TouchPoint> touches = new ObjectArrayList<>();
final BehaviorSubject<Integer[]> onResize = BehaviorSubject.create(); final BehaviorSubject<Integer[]> onRealResize;
final BehaviorSubject<Integer[]> onResizeEvent = BehaviorSubject.create();
private BehaviorSubject<Float> onZoom = BehaviorSubject.create(); private BehaviorSubject<Float> onZoom = BehaviorSubject.create();
private Subject<GL2ES1> onGLContext = PublishSubject.create(); private Subject<GL2ES1> onGLContext = SimpleSubject.create();
public NEWTWindow(GPUEngine disp) { public NEWTWindow(GPUEngine disp) {
this.disp = disp; this.disp = disp;
renderer = disp.getRenderer(); renderer = disp.getRenderer();
realWindowSize = new int[] { 1, 1 }; disp.size[0] = StaticVars.screenSize[0];
disp.size[1] = StaticVars.screenSize[1];
realWindowSize = new int[] { StaticVars.screenSize[0], StaticVars.screenSize[1] };
windowZoom = StaticVars.windowZoomFunction.apply(StaticVars.windowZoom.getLastValue());
onRealResize = BehaviorSubject.create(new Integer[] {(int) (StaticVars.screenSize[0] * windowZoom), (int) (StaticVars.screenSize[1] * windowZoom)});
Observable.zip(onZoom, onGLContext, (gl,zoom)->{return Pair.of(gl, zoom);}).subscribe((pair) -> { onRealResize.subscribe((realSize) -> {
windowZoom = pair.getLeft(); System.err.println("[[[SET REALWINDOWZOOM");
onDisplayChanged(pair.getRight(), true, false); realWindowSize[0] = realSize[0];
realWindowSize[1] = realSize[1];
disp.size[0] = realSize[0] / (int) windowZoom;
disp.size[1] = realSize[1] / (int) windowZoom;
System.err.println("[[["+realWindowSize[0]);
System.err.println("[[["+windowZoom);
System.err.println("[[["+disp.size[0]);
onResizeEvent.onNext(new Integer[] {disp.size[0], disp.size[1]});
refreshViewport = true;
}); });
Observable.zip(onResize, onGLContext, (gl,size)->{return Pair.of(gl, size);}).subscribe((pair) -> { StaticVars.windowZoom$.subscribe((zoom) -> {onZoom.onNext(zoom);});
final Integer[] size = pair.getLeft(); onZoom.subscribe((z)-> {
realWindowSize[0] = size[0]; if (windowZoom != 0) {
realWindowSize[1] =size[1]; windowZoom = z;
disp.size[0] = size[0]; disp.size[0] = (int) (realWindowSize[0] / windowZoom);
disp.size[1] = size[1]; disp.size[1] = (int) (realWindowSize[1] / windowZoom);
onDisplayChanged(pair.getRight(), false, true); StaticVars.screenSize[0] = disp.size[0];
StaticVars.screenSize[1] = disp.size[1];
System.err.println("[[[SET WINDOWZOOM");
System.err.println("[[["+realWindowSize[0]);
System.err.println("[[["+windowZoom);
System.err.println("[[[A:"+disp.size[0]);
refreshViewport = true;
}
}); });
} }
@ -472,8 +479,6 @@ class NEWTWindow implements GLEventListener {
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
StaticVars.windowZoom$.subscribe((zoom) -> {onZoom.onNext(zoom);});
onResize.onNext(new Integer[] {disp.size[0], disp.size[1]});
if (onInitialized != null) { if (onInitialized != null) {
onInitialized.run(); onInitialized.run();
@ -489,21 +494,7 @@ class NEWTWindow implements GLEventListener {
@Override @Override
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
onResize.onNext(new Integer[] {width, height}); onRealResize.onNext(new Integer[] {width, height});
}
private void onDisplayChanged(GL2ES1 gl, boolean zoomChanged, boolean sizeChanged) {
disp.size[0] = (int) (realWindowSize[0] / windowZoom);
disp.size[1] = (int) (realWindowSize[1] / windowZoom);
if (zoomChanged) {
final boolean linear = (windowZoom % ((int) windowZoom)) != 0f;
for (final Texture t : disp.registeredTextures) {
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, linear ? GL.GL_LINEAR : GL.GL_NEAREST);
t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
}
}
refreshViewport = true;
} }
@Override @Override
@ -512,18 +503,9 @@ class NEWTWindow implements GLEventListener {
GPURenderer.gl = gl; GPURenderer.gl = gl;
onGLContext.onNext(gl); onGLContext.onNext(gl);
Boolean linear = null; boolean linear = (windowZoom % ((int) windowZoom)) != 0f;
while (!disp.unregisteredTextures.isEmpty()) {
if (linear == null) {
linear = (windowZoom % ((int) windowZoom)) != 0f;
}
final Texture t = disp.unregisteredTextures.pop();
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
disp.registeredTextures.addLast(t);
}
if (refreshViewport) { if (refreshViewport) {
System.err.println("[[[REFVP");
refreshViewport = false; refreshViewport = false;
gl.glViewport(0, 0, realWindowSize[0], realWindowSize[1]); gl.glViewport(0, 0, realWindowSize[0], realWindowSize[1]);
@ -534,6 +516,17 @@ class NEWTWindow implements GLEventListener {
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity(); gl.glLoadIdentity();
for (final Texture t : disp.registeredTextures) {
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, linear ? GL.GL_LINEAR : GL.GL_NEAREST);
t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
}
}
while (disp.unregisteredTextures.isEmpty() == false) {
final Texture t = disp.unregisteredTextures.pop();
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, linear ? GL.GL_LINEAR : GL.GL_NEAREST);
t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
disp.registeredTextures.addLast(t);
} }
gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY); gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
@ -554,12 +547,16 @@ class NEWTWindow implements GLEventListener {
} }
public void setSize(final int width, final int height) { void setSize(final int width, final int height) {
int zoom = (int) windowZoom; int zoom = (int) windowZoom;
if (zoom == 0) { if (zoom == 0) {
zoom = onZoom.blockingFirst().intValue(); zoom = onZoom.getLastValue().intValue();
}
if (zoom == 0) {
zoom = 1;
} }
window.setSize(width * zoom, height * zoom); window.setSize(width * zoom, height * zoom);
onRealResize.onNext(new Integer[] {width * zoom, height * zoom});
} }
@Override @Override

View File

@ -9,11 +9,10 @@ import org.warp.picalculator.StaticVars;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.event.Key; import org.warp.picalculator.event.Key;
import org.warp.picalculator.flow.DObservable;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import io.reactivex.Observable;
public class Headless24bitEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { public class Headless24bitEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
private final Headless24bitRenderer r = new Headless24bitRenderer(); private final Headless24bitRenderer r = new Headless24bitRenderer();
@ -140,7 +139,7 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng
} }
@Override @Override
public Observable<Integer[]> onResize() { public DObservable<Integer[]> onResize() {
return null; return null;
} }

View File

@ -9,12 +9,11 @@ import org.warp.picalculator.StaticVars;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.event.Key; import org.warp.picalculator.event.Key;
import org.warp.picalculator.flow.DObservable;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer; import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer;
import io.reactivex.Observable;
public class Headless256Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { public class Headless256Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
private final Headless256Renderer r = new Headless256Renderer(); private final Headless256Renderer r = new Headless256Renderer();
@ -139,7 +138,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin
} }
@Override @Override
public Observable<Integer[]> onResize() { public DObservable<Integer[]> onResize() {
return null; return null;
} }

View File

@ -9,12 +9,11 @@ import org.warp.picalculator.StaticVars;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.event.Key; import org.warp.picalculator.event.Key;
import org.warp.picalculator.flow.DObservable;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer; import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer;
import io.reactivex.Observable;
public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
private final Headless8Renderer r = new Headless8Renderer(); private final Headless8Renderer r = new Headless8Renderer();
@ -139,7 +138,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.
} }
@Override @Override
public Observable<Integer[]> onResize() { public DObservable<Integer[]> onResize() {
return null; return null;
} }

View File

@ -5,14 +5,13 @@ import java.util.concurrent.Semaphore;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.deps.DSemaphore; import org.warp.picalculator.deps.DSemaphore;
import org.warp.picalculator.flow.Observable;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.Skin;
import io.reactivex.Observable;
public class NoGuiEngine implements GraphicEngine { public class NoGuiEngine implements GraphicEngine {
private boolean initialized; private boolean initialized;

View File

@ -26,7 +26,7 @@ public class LoadingScreen extends Screen {
@Override @Override
public void initialized() throws InterruptedException { public void initialized() throws InterruptedException {
previousZoomValue = StaticVars.windowZoomValue.next(); previousZoomValue = StaticVars.windowZoomFunction.apply(StaticVars.windowZoom.getLastValue());
StaticVars.windowZoom.onNext(1f); StaticVars.windowZoom.onNext(1f);
} }