<commit_before>package org.fxmisc.easybind.monadic;

import java.util.function.Function;

import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.value.ObservableValue;

class FlatMapBinding<T, U> extends ObjectBinding<U> implements MonadicBinding<U> {
    private final ObservableValue<T> src;
    private final Function<? super T, ObservableValue<U>> mapper;

    private final InvalidationListener mappedListener = obs -> mappedInvalidated();
    private final InvalidationListener weakMappedListener = new WeakInvalidationListener(mappedListener);

    private final InvalidationListener srcListener = obs -> srcInvalidated();
    private final InvalidationListener weakSrcListener = new WeakInvalidationListener(srcListener);

    private ObservableValue<U> mapped = null;

    public FlatMapBinding(ObservableValue<T> src, Function<? super T, ObservableValue<U>> f) {
        this.src = src;
        this.mapper = f;
        src.addListener(weakSrcListener);
    }

    @Override
    public void dispose() {
        src.removeListener(weakSrcListener);
        disposeMapped();
    }

    @Override
    protected U computeValue() {
        if(mapped == null) {
            T baseVal = src.getValue();
            if(baseVal == null) {
                return null;
            } else {
                mapped = mapper.apply(baseVal);
                mapped.addListener(weakMappedListener);
            }
        }
        return mapped.getValue();
    }

    private void mappedInvalidated() {
        invalidate();
    }

    private void disposeMapped() {
        if(mapped != null) {
            mapped.removeListener(weakMappedListener);
            mapped = null;
        }
    }

    private void srcInvalidated() {
        disposeMapped();
        invalidate();
    }
}<commit_msg>Minor refactoring.<commit_after>package org.fxmisc.easybind.monadic;

import java.util.function.Function;

import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.value.ObservableValue;

import org.fxmisc.easybind.Subscription;

class FlatMapBinding<T, U> extends ObjectBinding<U> implements MonadicBinding<U> {
    private final ObservableValue<T> src;
    private final Function<? super T, ObservableValue<U>> mapper;

    // need to retain strong reference to listeners, so that they don't get garbage collected
    private final InvalidationListener srcListener = obs -> srcInvalidated();
    private final InvalidationListener mappedListener = obs -> mappedInvalidated();

    private final InvalidationListener weakSrcListener = new WeakInvalidationListener(srcListener);
    private final InvalidationListener weakMappedListener = new WeakInvalidationListener(mappedListener);

    private ObservableValue<U> mapped = null;
    private Subscription mappedSubscription = null;

    public FlatMapBinding(ObservableValue<T> src, Function<? super T, ObservableValue<U>> f) {
        this.src = src;
        this.mapper = f;
        src.addListener(weakSrcListener);
    }

    @Override
    public final void dispose() {
        src.removeListener(weakSrcListener);
        disposeMapped();
    }

    @Override
    protected final U computeValue() {
        if(mapped == null) {
            T baseVal = src.getValue();
            if(baseVal == null) {
                return null;
            } else {
                mapped = mapper.apply(baseVal);
                mappedSubscription = observeMapped(mapped);
            }
        }
        return mapped.getValue();
    }

    protected Subscription observeMapped(ObservableValue<U> mapped) {
        mapped.addListener(weakMappedListener);
        return () -> mapped.removeListener(weakMappedListener);
    }

    private void disposeMapped() {
        if(mapped != null) {
            mappedSubscription.unsubscribe();
            mappedSubscription = null;
            mapped = null;
        }
    }

    private void mappedInvalidated() {
        invalidate();
    }

    private void srcInvalidated() {
        disposeMapped();
        invalidate();
    }
}
{'fraction_non_alphanumeric': 0.09015223596574691, 'fraction_numerical': 0.0, 'mean_word_length': 2.864889705882353, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4228880', 'n_tokens_mistral': 1126, 'n_tokens_neox': 1089, 'n_words': 259}