123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Phoenix Shell.
- *
- * Phoenix Shell is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- export class DelegatingPStratumImplAPI {
- constructor (facade) {
- this.facade = facade;
- }
- get delegate () {
- return this.facade.delegate;
- }
- }
- export class DelegatingPStratumImplType {
- constructor (facade) {
- this.facade = facade;
- }
- getImplAPI () {
- return new DelegatingPStratumImplAPI(this.facade);
- }
- }
- export class TerminalPStratumImplType {
- getImplAPI () {
- return {};
- }
- }
- export class PStratum {
- constructor (impl) {
- this.impl = impl;
- const implTypeClass = this.impl.constructor.TYPE
- ?? DelegatingPStratumImplType;
-
- this.implType = new implTypeClass(this);
- this.api = this.implType.getImplAPI();
- this.lookValue = null;
- this.seqNo = 0;
- this.history = [];
- // TODO: make this configurable
- this.historyOn = ! this.impl.reach;
- }
- setDelegate (delegate) {
- this.delegate = delegate;
- }
- look () {
- if ( this.looking ) {
- return this.lookValue;
- }
- this.looking = true;
- this.lookValue = this.impl.next(this.api);
- return this.lookValue;
- }
- next () {
- this.seqNo++;
- let toReturn;
- if ( this.looking ) {
- this.looking = false;
- toReturn = this.lookValue;
- } else {
- toReturn = this.impl.next(this.api);
- }
- this.history.push(toReturn.value);
- return toReturn;
- }
- fork () {
- const forkImpl = this.impl.fork(this.api);
- const fork = new PStratum(forkImpl);
- // DRY: sync state
- fork.looking = this.looking;
- fork.lookValue = this.lookValue;
- fork.seqNo = this.seqNo;
- fork.history = [...this.history];
- return fork;
- }
- join (friend) {
- // DRY: sync state
- this.looking = friend.looking;
- this.lookValue = friend.lookValue;
- this.seqNo = friend.seqNo;
- this.history = friend.history;
- this.impl.join(this.api, friend.impl);
- }
- reach (start, end) {
- if ( this.impl.reach ) {
- return this.impl.reach(this.api, start, end)
- }
- if ( this.historyOn ) {
- return this.history.slice(start, end);
- }
- }
- }
|