/* This file is part of Reactive Cascade which is released under The MIT License. See license.md , https://github.com/futurice/cascade and http://reactivecascade.com for details. This is open source for the common good. Please contribute improvements by pull request or contact paulirotta@gmail.com */ package com.reactivecascade.reactive; import android.support.annotation.CallSuper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.reactivecascade.i.IActionOne; import com.reactivecascade.i.IActionOneR; import com.reactivecascade.i.IThreadType; import com.reactivecascade.util.RCLog; /** * A {@link Long} which can be updated in an atomic, thread-safe manner. * <p> * This is similar to an {@link java.util.concurrent.atomic.AtomicLong} with reactive bindings to * get and set the from in reactive chains (function sequences that can fire multiple times). * <p>* * Created by phou on 30-05-2015. */ public class ReactiveLong extends ReactiveValue<Long> { /** * Create a new atomic long * * @param name * @param initialValue */ public ReactiveLong(@NonNull String name, final long initialValue) { super(name, initialValue); } /** * Create a new atomic long * * @param name * @param threadType * @param inputMapping a mapping for incoming values, for example <code>l -> Math.max(0, l)</code> * @param onErrorAction */ public ReactiveLong(@NonNull String name, @NonNull IThreadType threadType, @Nullable IActionOneR<Long, Long> inputMapping, @NonNull IActionOne<Exception> onErrorAction) { super(name, threadType, inputMapping, onErrorAction); } /** * Add two longs in a thread-safe manner * * @param l * @return */ @CallSuper public long addAndGet(long l) { while (true) { long currentValue = get(); if (compareAndSet(currentValue, currentValue + l)) { return currentValue; } RCLog.d(this, "Collision in concurrent add, will try again: " + currentValue); } } /** * Multiply two longs in a thread-safe manner * * @param l the second operand * @return the updated from */ @CallSuper public long multiplyAndGet(long l) { while (true) { final long currentValue = get(); if (compareAndSet(currentValue, currentValue * l)) { return currentValue; } RCLog.d(this, "Collision in concurrent add, will try again: " + currentValue); } } /** * Increment the long in a thread-safe manner * * @return the updated from */ @CallSuper public long incrementAndGet() { return addAndGet(1); } /** * Decrement the long in a thread-safe manner * * @return the updated from */ @CallSuper public long decrementAndGet() { return addAndGet(-1); } }