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

com.spotify.mobius.extras.patterns.InnerUpdate Maven / Gradle / Ivy

/*
 * -\-\-
 * Mobius
 * --
 * Copyright (c) 2017-2020 Spotify AB
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * -/-/-
 */
package com.spotify.mobius.extras.patterns;

import static com.spotify.mobius.internal_util.Preconditions.checkNotNull;

import com.google.auto.value.AutoValue;
import com.spotify.mobius.Next;
import com.spotify.mobius.Update;
import com.spotify.mobius.functions.BiFunction;
import com.spotify.mobius.functions.Function;
import javax.annotation.Nonnull;

/**
 * Helper class for putting an update function inside another update function.
 *
 * 

It is sometimes useful to compose two update functions that each have their own model, events, * and effects. Typically when you do this you will store the inner model inside the outer model, * and route some of the outer events to the inner update function. This class helps you wire up * this conversion between inner and outer model, events, and effects. * *

The outer update function must still make the decision if the inner update function should be * called or not, this class only helps with converting the types of the inner update function * * @param the outer model type * @param the outer event type * @param the outer effect type * @param the inner model type * @param the inner event type * @param the inner effect type */ @AutoValue public abstract class InnerUpdate implements Update { protected abstract Update innerUpdate(); protected abstract Function modelExtractor(); protected abstract Function eventExtractor(); protected abstract BiFunction modelUpdater(); protected abstract InnerEffectHandler innerEffectHandler(); @Nonnull @Override public final Next update(M model, E event) { MI innerModel = checkNotNull(modelExtractor().apply(model)); EI innerEvent = checkNotNull(eventExtractor().apply(event)); Next innerNext = checkNotNull(innerUpdate().update(innerModel, innerEvent)); M newModel = model; boolean modelUpdated = innerNext.hasModel(); if (modelUpdated) { newModel = checkNotNull(modelUpdater().apply(model, innerNext.modelUnsafe())); } return checkNotNull( innerEffectHandler().handleInnerEffects(newModel, modelUpdated, innerNext.effects())); } public static Builder builder() { return new AutoValue_InnerUpdate.Builder<>(); } @AutoValue.Builder public abstract static class Builder { /** The inner update function. */ public abstract Builder innerUpdate(Update innerUpdate); /** A function that extracts the inner model from an outer model. */ public abstract Builder modelExtractor(Function modelExtractor); /** A function the extracts the inner event from an outer event. */ public abstract Builder eventExtractor(Function eventExtractor); /** * A bifunction that given the old outer model and the new inner model creates a new outer * model. */ public abstract Builder modelUpdater(BiFunction modelUpdater); /** * An inner effect handler that decides what to do with inner effects. The function is applied * after. */ public abstract Builder innerEffectHandler( InnerEffectHandler innerEffectHandler); public abstract InnerUpdate build(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy