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

org.praxislive.script.CompoundStackFrame Maven / Gradle / Ivy

Go to download

Forest-of-actors runtime supporting real-time systems and real-time recoding - bringing aspects of Erlang, Smalltalk and Extempore to Java.

There is a newer version: 6.0.0-beta1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2024 Neil C Smith.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License version 3
 * along with this work; if not, see http://www.gnu.org/licenses/
 * 
 *
 * Please visit https://www.praxislive.org if you need additional information or
 * have any questions.
 */
package org.praxislive.script;

import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue;
import java.util.function.Function;
import java.util.function.Supplier;
import org.praxislive.core.Call;
import org.praxislive.core.Value;
import org.praxislive.core.types.PError;

/**
 *
 */
final class CompoundStackFrame implements StackFrame {

    private final Queue, StackFrame>> queue;

    private StackFrame active;
    private State state;
    private List result;

    CompoundStackFrame(StackFrame base, Function, StackFrame> next) {
        queue = new ArrayDeque<>();
        queue.add(next);
        active = base;
        state = State.Incomplete;
    }

    @Override
    public State getState() {
        if (state != State.Incomplete) {
            return state;
        } else {
            return active.getState();
        }
    }

    @Override
    public void postResponse(Call call) {
        active.postResponse(call);
        checkActiveState();
    }

    @Override
    public void postResponse(State state, List args) {
        active.postResponse(state, args);
        checkActiveState();
    }

    @Override
    public StackFrame process(Env env) {
        while (state == State.Incomplete) {
            StackFrame frame = active.process(env);
            if (frame != null || active.getState() == State.Incomplete) {
                return frame;
            }
            checkActiveState();
        }
        return null;
    }

    @Override
    public List result() {
        if (result != null) {
            return result;
        } else {
            throw new IllegalStateException();
        }
    }

    void addStage(Function, StackFrame> stage) {
        queue.add(stage);
    }

    private void checkActiveState() {
        switch (active.getState()) {
            case Incomplete -> {
            }
            case OK ->
                nextOrComplete();
            default -> {
                state = active.getState();
                result = active.result();
                active = null;
                queue.clear();
            }
        }
    }

    private void nextOrComplete() {
        if (!queue.isEmpty()) {
            try {
                active = queue.remove().apply(active.result());
            } catch (Exception ex) {
                state = State.Error;
                result = List.of(PError.of(ex));
                active = null;
                queue.clear();
            }
        } else {
            state = State.OK;
            result = active.result();
            active = null;
        }
    }

    static class SupplierStackFrame implements StackFrame {

        private final Supplier> supplier;

        private State state = State.Incomplete;
        private List result;

        SupplierStackFrame(Supplier> supplier) {
            this.supplier = supplier;
        }

        @Override
        public State getState() {
            return state;
        }

        @Override
        public void postResponse(Call call) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void postResponse(State state, List args) {
            throw new UnsupportedOperationException();
        }

        @Override
        public StackFrame process(Env env) {
            try {
                result = supplier.get();
                state = State.OK;
            } catch (Exception ex) {
                result = List.of(PError.of(ex));
                state = State.Error;
            }
            return null;
        }

        @Override
        public List result() {
            return result;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy