diff --git a/gs-defaults/src/main/java/org/genericsystem/defaults/tools/RxJavaHelpers.java b/gs-defaults/src/main/java/org/genericsystem/defaults/tools/RxJavaHelpers.java index eb9216e42..27c8d8e7b 100644 --- a/gs-defaults/src/main/java/org/genericsystem/defaults/tools/RxJavaHelpers.java +++ b/gs-defaults/src/main/java/org/genericsystem/defaults/tools/RxJavaHelpers.java @@ -132,9 +132,7 @@ public static Observable prevFromObservableValue(final ObservableValue private static Observable> fromNullableObservableValue(final ObservableValue fxObservable) { return Observable.create((ObservableEmitter> emitter) -> { - if (fxObservable.getValue() != null) { - emitter.onNext(Optional.of(fxObservable.getValue())); - } + emitter.onNext(Optional.ofNullable(fxObservable.getValue())); final ChangeListener listener = (observableValue, prev, current) -> { emitter.onNext(Optional.ofNullable(current)); diff --git a/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/DocPropertiesSwitcher.java b/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/DocPropertiesSwitcher.java index 66fa96016..ea0a6d075 100644 --- a/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/DocPropertiesSwitcher.java +++ b/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/DocPropertiesSwitcher.java @@ -3,7 +3,6 @@ import java.io.File; import org.genericsystem.api.core.Snapshot; -import org.genericsystem.common.Generic; import org.genericsystem.common.Root; import org.genericsystem.cv.comparator.ImgFilterFunction; import org.genericsystem.cv.model.Doc; @@ -15,17 +14,15 @@ import org.genericsystem.cv.model.ZoneGeneric.ZoneInstance; import org.genericsystem.cv.model.ZoneText; import org.genericsystem.cv.model.ZoneText.ZoneTextInstance; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.ir.DistributedVerticle; import org.genericsystem.reactor.Context; import org.genericsystem.reactor.Tag; import org.genericsystem.reactor.context.TagSwitcher; -import javafx.beans.binding.Bindings; -import javafx.beans.binding.BooleanBinding; +import io.reactivex.Observable; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.value.ObservableValue; -import javafx.collections.ObservableList; public class DocPropertiesSwitcher { @@ -33,115 +30,107 @@ public class DocPropertiesSwitcher { public static class DOC_CLASS_EMPTY implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocClassEmpty(context, false); } } public static class DOC_CLASS_NOT_EMPTY implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocClassEmpty(context, true); } } public static class SUPERVISION_AVAILABLE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isSupervisionAvailable(context, false); } } public static class SUPERVISION_NOT_AVAILABLE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isSupervisionAvailable(context, true); } } public static class DOC_DEZONED implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isClassZoneFilePresent(context, false); } } public static class DOC_NOT_DEZONED implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isClassZoneFilePresent(context, true); } } public static class DOC_OCRD implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocOcrd(context, false); } } public static class DOC_NOT_OCRD implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocOcrd(context, true); } } public static class DOC_SUPERVISED implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocSupervised(context, false); } } public static class DOC_NOT_SUPERVISED implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { return isDocSupervised(context, true); } } - public static ObservableValue isDocClassEmpty(Context context, boolean reverse) { + public static Observable isDocClassEmpty(Context context, boolean reverse) { DocClassInstance currentDocClass = (DocClassInstance) context.getGeneric(); Doc doc = context.getGeneric().getRoot().find(Doc.class); - ObservableList docInstances = currentDocClass.getHolders(doc).toObservableList(); - BooleanBinding binding = Bindings.createBooleanBinding(() -> { - return null == docInstances || docInstances.isEmpty(); - }, docInstances); - return reverse ? binding.not() : binding; + return currentDocClass.getHolders(doc).setOnChanged().map(set -> reverse ? !set.isEmpty() : set.isEmpty()); } - public static ObservableValue isSupervisionAvailable(Context context, boolean reverse) { + public static Observable isSupervisionAvailable(Context context, boolean reverse) { DocClassInstance currentDocClass = (DocClassInstance) context.getGeneric(); - BooleanBinding binding = getBooleanBinding(currentDocClass.getValue().toString()); - return reverse ? binding.not() : binding; + Observable binding = getBooleanBinding(currentDocClass.getValue().toString()); + return reverse ? binding.map(bool -> !bool) : binding; } - public static ObservableValue isClassZoneFilePresent(Context context, boolean reverse) { + public static Observable isClassZoneFilePresent(Context context, boolean reverse) { DocInstance currentDoc = (DocInstance) context.getGeneric(); DocClassInstance docClassInstance = currentDoc.getDocClass(); - BooleanBinding binding = getBooleanBinding(docClassInstance.getValue().toString()); - return reverse ? binding.not() : binding; + Observable binding = getBooleanBinding(docClassInstance.getValue().toString()); + return reverse ? binding.map(bool -> !bool) : binding; } - private static BooleanBinding getBooleanBinding(String docClass) { + private static Observable getBooleanBinding(String docClass) { ObjectProperty file = new SimpleObjectProperty<>(new File(ZONES_FILE_BASE_PATH + docClass + "/zones/zones.json")); - BooleanBinding binding = Bindings.createBooleanBinding(() -> { - return null != file.get() && file.get().exists(); - }, file); - return binding; + return RxJavaHelpers.optionalValuesOf(file).map(opt -> opt.isPresent() && opt.get().exists()); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static ObservableValue isDocOcrd(Context context, boolean reverse) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Observable isDocOcrd(Context context, boolean reverse) { DocInstance currentDoc = (DocInstance) context.getGeneric(); Root root = currentDoc.getRoot(); ZoneText zoneText = root.find(ZoneText.class); ZoneGeneric zoneGeneric = root.find(ZoneGeneric.class); // The original image should ALWAYS exist ImgFilterInstance imgFilterInstance = ((ImgFilter) root.find(ImgFilter.class)).getImgFilter(ImgFilterFunction.ORIGINAL.getName()); - ObservableList zoneTextInstances = (ObservableList) currentDoc.getHolders(zoneText).toObservableList(); - BooleanBinding binding = Bindings.createBooleanBinding(() -> { + Observable obs = currentDoc.getHolders(zoneText).setOnChanged().map(zoneTextInstances -> { Snapshot zoneInstances = (Snapshot) currentDoc.getDocClass().getHolders(zoneGeneric); // Consider the document as not OCR'd when the class was not de-zoned if (zoneInstances.isEmpty()) @@ -153,25 +142,17 @@ public static ObservableValue isDocOcrd(Context context, boolean revers return null != zti; }); } - }, zoneTextInstances); - return reverse ? binding.not() : binding; + }); + return reverse ? obs.map(bool -> !bool) : obs; } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static ObservableValue isDocSupervised(Context context, boolean reverse) { + public static Observable isDocSupervised(Context context, boolean reverse) { // TODO: will a document be considered as not supervised if a field needs to be left empty? DocInstance currentDoc = (DocInstance) context.getGeneric(); Root root = currentDoc.getRoot(); ZoneText zoneText = root.find(ZoneText.class); - ObservableList zoneTextInstances = (ObservableList) currentDoc.getHolders(zoneText).toObservableList().filtered(zt -> "reality".equals(((ZoneTextInstance) zt).getImgFilter().getValue())); - BooleanBinding binding = Bindings.createBooleanBinding(() -> { - if (zoneTextInstances.isEmpty()) { - return false; - } else { - // If any field is empty, return false otherwise true - return !zoneTextInstances.stream().anyMatch(g -> "".equals(g.getValue().toString())); - } - }, zoneTextInstances); - return reverse ? binding.not() : binding; + Observable obs = currentDoc.getHolders(zoneText).filter(zt -> "reality".equals(((ZoneTextInstance) zt).getImgFilter().getValue())) + .setOnChanged().map(zoneTextInstances -> !zoneTextInstances.isEmpty() && !zoneTextInstances.stream().anyMatch(g -> "".equals(g.getValue().toString()))); + return reverse ? obs.map(bool -> !bool) : obs; } } diff --git a/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/PageSwitcher.java b/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/PageSwitcher.java index 5b865813f..c17eac85a 100644 --- a/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/PageSwitcher.java +++ b/gs-ir/src/main/java/org/genericsystem/ir/app/gui/utils/PageSwitcher.java @@ -1,12 +1,12 @@ package org.genericsystem.ir.app.gui.utils; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.reactor.Context; import org.genericsystem.reactor.Tag; import org.genericsystem.reactor.context.TagSwitcher; -import javafx.beans.binding.Bindings; +import io.reactivex.Observable; import javafx.beans.property.Property; -import javafx.beans.value.ObservableValue; public class PageSwitcher { @@ -16,17 +16,17 @@ public class PageSwitcher { public static class HOME_PAGE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property pageProperty = tag.getContextProperty(PAGE, context); - return Bindings.createBooleanBinding(() -> HOME_PAGE.equals(pageProperty.getValue()), pageProperty); + return RxJavaHelpers.optionalValuesOf(pageProperty).map(opt -> opt.isPresent() && HOME_PAGE.equals(opt.get())); } } public static class FILTERS_STATISTICS implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property pageProperty = tag.getContextProperty(PAGE, context); - return Bindings.createBooleanBinding(() -> FILTERS_STATISTICS.equals(pageProperty.getValue()), pageProperty); + return RxJavaHelpers.optionalValuesOf(pageProperty).map(opt -> opt.isPresent() && FILTERS_STATISTICS.equals(opt.get())); } } diff --git a/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizExtractors.java b/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizExtractors.java index dabf660b2..bdf35247a 100644 --- a/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizExtractors.java +++ b/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizExtractors.java @@ -4,6 +4,7 @@ import org.genericsystem.api.core.Snapshot; import org.genericsystem.common.Generic; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.quiz.model.Answer; import org.genericsystem.quiz.model.Description; import org.genericsystem.quiz.model.Question; @@ -16,9 +17,7 @@ import org.genericsystem.reactor.context.TagSwitcher; import io.reactivex.Observable; -import javafx.beans.binding.Bindings; import javafx.beans.property.Property; -import javafx.beans.value.ObservableValue; public class QuizExtractors { @@ -69,23 +68,23 @@ public Generic apply(Generic[] generics) { public static class FILTER_QUIZ implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { if (tag.getContextProperty(QuizContextAction.SELECTED_QUIZ, context) == null) tag.getRootTag().createNewContextProperty(QuizContextAction.SELECTED_QUIZ, context.getRootContext()); Property selectedQuiz = tag.getContextProperty(QuizContextAction.SELECTED_QUIZ, context); - return Bindings.createBooleanBinding(() -> selectedQuiz.getValue() == null || context.getGeneric().getComponent(1).equals(selectedQuiz.getValue()), selectedQuiz); + return RxJavaHelpers.optionalValuesOf(selectedQuiz).map(optQuiz -> !optQuiz.isPresent() || context.getGeneric().getComponent(1).equals(optQuiz.get())); } } public static class FILTER_USER implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { if (tag.getContextProperty(QuizContextAction.SELECTED_USER, context) == null) tag.getRootTag().createNewContextProperty(QuizContextAction.SELECTED_USER, context.getRootContext()); Property selectedUser = tag.getContextProperty(QuizContextAction.SELECTED_USER, context); - return Bindings.createBooleanBinding(() -> selectedUser.getValue() == null || selectedUser.getValue().trim().isEmpty() || - ((String) context.getGeneric().getComponent(0).getValue()).trim().toLowerCase().contains(selectedUser.getValue().trim().toLowerCase()), selectedUser); + return RxJavaHelpers.optionalValuesOf(selectedUser).map(optUser -> !optUser.isPresent() || optUser.get().trim().isEmpty() + || ((String) context.getGeneric().getComponent(0).getValue()).trim().toLowerCase().contains(optUser.get().trim().toLowerCase())); } } diff --git a/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizTagSwitcher.java b/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizTagSwitcher.java index b14879991..65345e89b 100644 --- a/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizTagSwitcher.java +++ b/gs-quiz/src/main/java/org/genericsystem/quiz/utils/QuizTagSwitcher.java @@ -1,15 +1,15 @@ package org.genericsystem.quiz.utils; import org.genericsystem.common.Generic; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.quiz.model.Quiz; import org.genericsystem.quiz.model.ScoreUserQuiz; import org.genericsystem.reactor.Context; import org.genericsystem.reactor.Tag; import org.genericsystem.reactor.context.TagSwitcher; -import javafx.beans.binding.Bindings; +import io.reactivex.Observable; import javafx.beans.property.Property; -import javafx.beans.value.ObservableValue; public class QuizTagSwitcher { @@ -21,7 +21,7 @@ public class QuizTagSwitcher { public static class QUIZ_NOT_DONE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property loggedUser = tag.getLoggedUserProperty(context); Generic quiz = context.getGeneric(); @@ -30,9 +30,8 @@ public ObservableValue apply(Context context, Tag tag) { Generic scoreUser = quiz.getLink(context.getRootContext().find(ScoreUserQuiz.class), loggedUser.getValue()); - return Bindings.createBooleanBinding(() -> scoreUser == null, loggedUser); + return RxJavaHelpers.optionalValuesOf(loggedUser).map(optUser -> scoreUser == null); } - } // ************* NAVIGATION ENTRE LES PAGES ********************** @@ -40,27 +39,27 @@ public ObservableValue apply(Context context, Tag tag) { public static class HOME_PAGE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property pageProperty = tag.getContextProperty(PAGE, context); - return Bindings.createBooleanBinding(() -> HOME_PAGE.equals(pageProperty.getValue()), pageProperty); + return RxJavaHelpers.valuesOf(pageProperty).map(page -> HOME_PAGE.equals(page)); } } public static class QUESTION_PAGE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property pageProperty = tag.getContextProperty(PAGE, context); - return Bindings.createBooleanBinding(() -> QUESTION_PAGE.equals(pageProperty.getValue()), pageProperty); + return RxJavaHelpers.valuesOf(pageProperty).map(page -> QUESTION_PAGE.equals(page)); } } public static class RESULT_PAGE implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property pageProperty = tag.getContextProperty(PAGE, context); - return Bindings.createBooleanBinding(() -> RESULT_PAGE.equals(pageProperty.getValue()), pageProperty); + return RxJavaHelpers.valuesOf(pageProperty).map(page -> RESULT_PAGE.equals(page)); } } } diff --git a/gs-reactor/src/main/java/org/genericsystem/reactor/FilteredChildren.java b/gs-reactor/src/main/java/org/genericsystem/reactor/FilteredChildren.java index 9c66cda55..e2182c662 100644 --- a/gs-reactor/src/main/java/org/genericsystem/reactor/FilteredChildren.java +++ b/gs-reactor/src/main/java/org/genericsystem/reactor/FilteredChildren.java @@ -7,6 +7,8 @@ import com.sun.javafx.collections.ObservableListWrapper; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; @@ -36,7 +38,8 @@ static class FilteredTagChildren extends FilteredChildren { if (child.getMetaBinding() != null) return new ObservableValue[] {}; ObservableList result = new ObservableListWrapper<>(child.getObservableSwitchers(), s -> { - ObservableValue selector = context.getCache().safeSupply(() -> s.apply(context, child)); + Property selector = new SimpleBooleanProperty(); + context.getHtmlDomNode(tag).getDisposables().add(context.getCache().safeSupply(() -> s.apply(context, child)).subscribe(bool -> selector.setValue(bool))); selectorsByChildAndSwitcher.get(child).put(s, selector); return new ObservableValue[] { selector }; }); diff --git a/gs-reactor/src/main/java/org/genericsystem/reactor/MetaBinding.java b/gs-reactor/src/main/java/org/genericsystem/reactor/MetaBinding.java index 60ddaa031..93647038c 100644 --- a/gs-reactor/src/main/java/org/genericsystem/reactor/MetaBinding.java +++ b/gs-reactor/src/main/java/org/genericsystem/reactor/MetaBinding.java @@ -38,7 +38,7 @@ public Observable buildFilteredChildren(Context context, Tag @SuppressWarnings("unchecked") private Observable buildObservableBySubContext(Snapshot snapshot, Context subContext, Tag childTag, int index) { return RxJavaHelpers.changesOf(childTag.getObservableSwitchers()).switchMap(list -> list.isEmpty() ? Observable.just(new IndexedSubContext(subContext, true, index)) : - Observable.combineLatest(list.stream().map(switcher -> RxJavaHelpers.valuesOf(switcher.apply(subContext, childTag))).toArray(Observable[]::new), + Observable.combineLatest(list.stream().map(switcher -> switcher.apply(subContext, childTag)).toArray(Observable[]::new), args -> new IndexedSubContext(subContext, Arrays.stream(args).allMatch(v -> Boolean.TRUE.equals(v)), index)).distinctUntilChanged()) .mergeWith(snapshot.getRemovals().filter(context -> context.equals(subContext)).map(context -> new IndexedSubContext(context, false, -1))) .takeUntil(indexedContext -> ((IndexedSubContext) indexedContext).getIndex() < 0); diff --git a/gs-reactor/src/main/java/org/genericsystem/reactor/context/TagSwitcher.java b/gs-reactor/src/main/java/org/genericsystem/reactor/context/TagSwitcher.java index 931cfa46c..e371ca9a6 100644 --- a/gs-reactor/src/main/java/org/genericsystem/reactor/context/TagSwitcher.java +++ b/gs-reactor/src/main/java/org/genericsystem/reactor/context/TagSwitcher.java @@ -3,55 +3,55 @@ import java.util.function.BiFunction; import org.genericsystem.common.Generic; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.reactor.Context; import org.genericsystem.reactor.Tag; import org.genericsystem.reactor.contextproperties.UserRoleDefaults; import org.genericsystem.security.model.Role.Admin; import org.genericsystem.security.model.UserRole; -import javafx.beans.binding.Bindings; +import io.reactivex.Observable; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; -public interface TagSwitcher extends BiFunction> { +public interface TagSwitcher extends BiFunction> { public static class NORMAL_MODE_ONLY implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - Property adminProperty = tag.getAdminModeProperty(context); - return Bindings.createBooleanBinding(() -> !Boolean.TRUE.equals(adminProperty.getValue()), adminProperty); + public Observable apply(Context context, Tag tag) { + return RxJavaHelpers.optionalValuesOf(tag.getAdminModeProperty(context)).map(opt -> !opt.isPresent() || !opt.get()); } } public static class ADMIN_MODE_ONLY implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - return tag.getAdminModeProperty(context); + public Observable apply(Context context, Tag tag) { + return RxJavaHelpers.optionalValuesOf(tag.getAdminModeProperty(context)).map(opt -> opt.isPresent() && opt.get()); } } public static class LOGGED_USER implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property loggedUserProperty = ((UserRoleDefaults) tag).getLoggedUserProperty(context); - return Bindings.createBooleanBinding(() -> loggedUserProperty.getValue() != null, loggedUserProperty); + return RxJavaHelpers.optionalValuesOf(loggedUserProperty).map(opt -> opt.isPresent()); } } public static class NO_LOGGED_USER implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property loggedUserProperty = ((UserRoleDefaults) tag).getLoggedUserProperty(context); - return Bindings.createBooleanBinding(() -> loggedUserProperty.getValue() == null, loggedUserProperty); + return RxJavaHelpers.optionalValuesOf(loggedUserProperty).map(opt -> !opt.isPresent()); } } public static class LOGGED_USER_ADMIN implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Property loggedUserProperty = tag.getLoggedUserProperty(context); ObservableValue adminObservable = context.find(Admin.class).getObservableLink(context.find(UserRole.class), loggedUserProperty.getValue()); - return Bindings.createBooleanBinding(() -> loggedUserProperty.getValue() != null && adminObservable.getValue() != null, loggedUserProperty, adminObservable); + return RxJavaHelpers.optionalValuesOf(loggedUserProperty).map(opt -> opt.isPresent() && adminObservable.getValue() != null); } } } diff --git a/gs-reactor/src/main/java/org/genericsystem/reactor/gscomponents/Controller.java b/gs-reactor/src/main/java/org/genericsystem/reactor/gscomponents/Controller.java index b87de4b43..3dc708e6e 100644 --- a/gs-reactor/src/main/java/org/genericsystem/reactor/gscomponents/Controller.java +++ b/gs-reactor/src/main/java/org/genericsystem/reactor/gscomponents/Controller.java @@ -13,11 +13,8 @@ import io.reactivex.subjects.BehaviorSubject; import io.reactivex.subjects.ReplaySubject; import io.reactivex.subjects.Subject; -import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableMap; @@ -205,12 +202,10 @@ public Observable nextText() { public static class MainSwitcher implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Controller controller = Controller.get(tag, context); - Property> classProperty = new SimpleObjectProperty<>(); - controller.getClassProperty().subscribe(clazz -> classProperty.setValue(clazz)); Property activeProperty = controller.getActiveProperty(); - return Bindings.createBooleanBinding(() -> !activeProperty.getValue() || tag.getClass().equals(classProperty.getValue()), classProperty, activeProperty); + return Observable.combineLatest(RxJavaHelpers.valuesOf(activeProperty), controller.getClassProperty(), (active, clazz) -> !active || tag.getClass().equals(clazz)); } } @@ -260,40 +255,32 @@ public Observable apply(Context context, Tag tag) { public static class CountTextSwitcher implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - return Controller.get(tag, context).activeProperty; + public Observable apply(Context context, Tag tag) { + return RxJavaHelpers.valuesOf(Controller.get(tag, context).activeProperty); } } - // TODO: Dispose subscriptions. public static class PrevSwitcher implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - Property result = new SimpleBooleanProperty(); - Controller.get(tag, context).hasPrev(tag).subscribe(bool -> result.setValue(bool)); - return result; + public Observable apply(Context context, Tag tag) { + return Controller.get(tag, context).hasPrev(tag); } - } public static class NextSwitcher implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - Property result = new SimpleBooleanProperty(); - Controller.get(tag, context).hasNext(tag).subscribe(bool -> result.setValue(bool)); - return result; + public Observable apply(Context context, Tag tag) { + return Controller.get(tag, context).hasNext(tag); } } public static class LastSwitcher implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { - Property result = new SimpleBooleanProperty(); - Controller.get(tag, context).hasNext(tag).subscribe(bool -> result.setValue(!bool)); - return result; + public Observable apply(Context context, Tag tag) { + return Controller.get(tag, context).hasNext(tag).map(bool -> !bool); } } } \ No newline at end of file diff --git a/gs-todomvc/src/main/java/org/genericsystem/todomvc/TodoApp.java b/gs-todomvc/src/main/java/org/genericsystem/todomvc/TodoApp.java index 58f9250cf..66825e5dd 100644 --- a/gs-todomvc/src/main/java/org/genericsystem/todomvc/TodoApp.java +++ b/gs-todomvc/src/main/java/org/genericsystem/todomvc/TodoApp.java @@ -5,6 +5,7 @@ import org.genericsystem.api.core.Snapshot; import org.genericsystem.common.Generic; import org.genericsystem.defaults.tools.BidirectionalBinding; +import org.genericsystem.defaults.tools.RxJavaHelpers; import org.genericsystem.reactor.Context; import org.genericsystem.reactor.ReactorStatics; import org.genericsystem.reactor.Tag; @@ -48,11 +49,11 @@ import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosContent.TodoItem.ItemContent.TodoCheckBox; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.ClearCompletedButton; -import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.ItemsLeft; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.Filters; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.Filters.ModeActiveLink; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.Filters.ModeAllLink; import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.Filters.ModeCompleteLink; +import org.genericsystem.todomvc.TodoApp.RootDiv.ContentDiv.TodosFooter.ItemsLeft; import org.genericsystem.todomvc.TodoApp.RootDiv.MainFooter; import org.genericsystem.todomvc.Todos.Completed; @@ -79,30 +80,31 @@ public static void main(String[] mainArgs) { ApplicationServer.startSimpleGenericApp(mainArgs, TodoApp.class, "/todo2/"); } - protected static Property>> getModeProperty(Tag tag, Context model) { + protected static Property> getModeProperty(Tag tag, Context model) { return tag.getContextProperty(FILTER_MODE, model); } @Override public void init() { - addContextAttribute(FILTER_MODE, c -> new SimpleObjectProperty>>(ALL)); + addContextAttribute(FILTER_MODE, c -> new SimpleObjectProperty>(ALL)); } public static class StateFilter implements TagSwitcher { @Override - public ObservableValue apply(Context context, Tag tag) { + public Observable apply(Context context, Tag tag) { Generic todo = context.getGeneric(); ObservableValue completed = todo.getObservableHolder(todo.getRoot().find(Completed.class)); - Property>> mode = getModeProperty(tag, context); - return Bindings.createBooleanBinding(() -> mode.getValue().test(completed), completed, mode); + Property> modeProp = getModeProperty(tag, context); + return Observable.combineLatest(RxJavaHelpers.optionalValuesOf(completed), RxJavaHelpers.valuesOf(modeProp), + (optCompleted, mode) -> mode.test(optCompleted.isPresent() ? optCompleted.get() : null)); } } - static Predicate> ALL = o -> true; - static Predicate> ACTIVE = completedObs -> { - return completedObs.getValue() != null ? Boolean.FALSE.equals(completedObs.getValue().getValue()) : true; + static Predicate ALL = o -> true; + static Predicate ACTIVE = completedObs -> { + return completedObs != null ? Boolean.FALSE.equals(completedObs.getValue()) : true; }; - static Predicate> COMPLETE = ACTIVE.negate(); + static Predicate COMPLETE = ACTIVE.negate(); static Predicate completed = todo -> { Generic completed = todo.getHolder(todo.getRoot().find(Completed.class));