Skip to content

Commit

Permalink
Merge pull request #81 from lf-lang/ts-multiport
Browse files Browse the repository at this point in the history
Added support for connecting multiports and started reorganizing the code base to be more modular.
  • Loading branch information
lhstrh authored Mar 7, 2022
2 parents 9ae63fd + 2139355 commit bf59b4e
Show file tree
Hide file tree
Showing 40 changed files with 1,887 additions and 1,201 deletions.
9 changes: 3 additions & 6 deletions __tests__/ActionTrigger.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {App, Triggers, Args} from '../src/core/reactor';
import {Origin, TimeValue} from '../src/core/time';
import {Reactor, Timer, Action, Sched} from '../src/core/reactor';
import {App, Triggers, Args, Origin, TimeValue, Reactor, Timer, Sched, Action} from '../src/core/internal';

//Upon initialization, this reactor should produce an
//output event
Expand Down Expand Up @@ -67,9 +65,8 @@ export class ActionTrigger extends Reactor {
class ActionTriggerTest extends App {
aTrigger: ActionTrigger;

constructor(name: string, timeout: TimeValue, success?: ()=> void, fail?: ()=>void){
constructor(timeout: TimeValue, success?: ()=> void, fail?: ()=>void){
super(timeout, false, false, success, fail);
this._setAlias(name);
this.aTrigger = new ActionTrigger(this);
}
}
Expand All @@ -86,7 +83,7 @@ describe('ActionTrigger', function () {
};

//Tell the reactor runtime to successfully terminate after 3 seconds.
var aTriggerTest = new ActionTriggerTest("ActionTriggerTest", TimeValue.secs(3), done, failure);
var aTriggerTest = new ActionTriggerTest(TimeValue.secs(3), done, failure);
//Don't give the runtime the done callback because we don't care if it terminates
aTriggerTest._start();

Expand Down
2 changes: 1 addition & 1 deletion __tests__/Adder.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import {App, IOPort, Reactor, InPort, OutPort, Present, Args, Triggers} from '../src/core/reactor';
import { IOPort, App, Reactor, Present, Args, Triggers, InPort, OutPort} from '../src/core/internal';

export class Adder extends Reactor {

Expand Down
8 changes: 3 additions & 5 deletions __tests__/Clock.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

import {Timer, Action, App, Sched, Triggers, Args} from '../src/core/reactor';
import {TimeValue, TimeUnit, Origin} from "../src/core/time"
import { Action,Timer, App, Sched, Triggers, Args,TimeValue, TimeUnit, Origin } from '../src/core/internal';

/**
* This app tests simultaneous events.
Expand All @@ -23,9 +22,8 @@ export class Clock extends App {
a2 = new Action<number>(this, Origin.logical);
a3 = new Action<number>(this, Origin.logical);

constructor(name: string, timeout: TimeValue, success: () => void, fail: () => void) {
constructor(timeout: TimeValue, success: () => void, fail: () => void) {
super(timeout, false, false, success, fail);
this._alias = name;
this.addReaction(
new Triggers(this.t1),
new Args(this.schedulable(this.a1)),
Expand Down Expand Up @@ -102,7 +100,7 @@ describe('clock', function () {
};

//Tell the reactor runtime to successfully terminate after 6 seconds.
var clock = new Clock("Clock", TimeValue.secs(6), done, fail);
var clock = new Clock(TimeValue.secs(6), done, fail);

//Don't give the runtime the done callback because we don't care if it terminates
clock._start();
Expand Down
9 changes: 4 additions & 5 deletions __tests__/HierarchicalSingleEvent.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Reactor, OutPort, InPort, App, Parameter} from '../src/core/reactor';
import {TimeValue} from "../src/core/time"
import {Reactor, App, Parameter, OutPort, InPort, TimeValue} from '../src/core/internal';

import {SingleEvent} from '../src/share/SingleEvent';
import {Logger} from '../src/share/Logger';

Expand Down Expand Up @@ -31,9 +31,8 @@ class SETest extends App {
seContainer: SEContainer;
logContainer: LogContainer;

constructor(name:string, timeout: TimeValue, keepAlive: boolean = false, fast: boolean = false, success: ()=> void, fail: ()=>void ){
constructor(timeout: TimeValue, keepAlive: boolean = false, fast: boolean = false, success: ()=> void, fail: ()=>void ){
super(timeout, keepAlive, fast, success, fail)
this._setAlias(name);
this.seContainer = new SEContainer(this);
this.logContainer = new LogContainer(this);

Expand Down Expand Up @@ -61,7 +60,7 @@ describe('HierarchicalSingleEvent', function () {
};

// Tell the reactor runtime to successfully terminate after 3 seconds.
let seTest = new SETest("SingleEventTesterApp", TimeValue.secs(3), false, false, done, failReactor);
let seTest = new SETest(TimeValue.secs(3), false, false, done, failReactor);

// Normally _setAllParents would be called as part of the initialization
// process for starting an app, but we call it directly here to set
Expand Down
6 changes: 1 addition & 5 deletions __tests__/Logger.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import {Logger} from '../src/share/Logger'
import {Reactor, InPort, Read, Triggers, Args, State, Present, ReactionSandbox, App} from '../src/core/reactor';
import { TimeValue, TimeUnit } from '../src/core/time';
import { Log, LogLevel } from '../src/core/util'


import {Reactor, App, Log, LogLevel} from '../src/core/internal';

const _reactor:Reactor = new App()
const lg:Logger = new Logger(_reactor , 10)
Expand Down
3 changes: 1 addition & 2 deletions __tests__/OutputEvent.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {App, Reactor, Parameter, Args, Triggers} from '../src/core/reactor';
import {TimeValue} from "../src/core/time"
import {App, Reactor, Parameter, Args, Triggers, TimeValue} from '../src/core/internal';
import {SingleEvent} from '../src/share/SingleEvent';

/**
Expand Down
6 changes: 2 additions & 4 deletions __tests__/OutputGet.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {OutPort, App, Timer, Write, Triggers, Args} from '../src/core/reactor';
import {TimeValue} from "../src/core/time";
import { Log } from '../src/core/util';

import {App, Timer, Write, Triggers, Args, OutPort, TimeValue, Log} from '../src/core/internal';

class OutputGetTest extends App {

Expand All @@ -10,7 +9,6 @@ class OutputGetTest extends App {
constructor(timeout: TimeValue, name:string, success: ()=> void, failure: ()=>void){
super(timeout, true, false, success, failure);
Log.global.debug(">>>>>>>>----" + this.util)
this._setAlias(name);
this.addReaction(
new Triggers(this.t),
new Args(this.writable(this.o)),
Expand Down
4 changes: 1 addition & 3 deletions __tests__/SingleEvent.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {App, Parameter} from '../src/core/reactor';
import {TimeValue} from "../src/core/time"
import {App, Parameter, TimeValue} from '../src/core/internal';
import {SingleEvent} from '../src/share/SingleEvent';
import {Logger} from '../src/share/Logger';

Expand All @@ -9,7 +8,6 @@ class SETest extends App {

constructor(timeout: TimeValue, success: ()=> void, failure: ()=>void ) {
super(timeout, false, false, success, failure);
this._setAlias("SETest");
this.singleEvent = new SingleEvent(this, new Parameter("foo"));
this.logger = new Logger(this, "foo");

Expand Down
2 changes: 1 addition & 1 deletion __tests__/alarm.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TimeValue, TimeUnit, Alarm } from '../src/core/time';
import { TimeValue, TimeUnit, Alarm } from '../src/core/internal';
import NanoTimer from 'nanotimer';

var timerA = new NanoTimer();
Expand Down
56 changes: 56 additions & 0 deletions __tests__/bank.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Bank , Reactor, App, Timer, Triggers, Args, Present, OutPort, InPort, TimeValue } from "../src/core/internal";

class Periodic extends Reactor {

t: Timer = new Timer(this, 0, TimeValue.sec(1));
o: OutPort<number> = new OutPort(this)
constructor(parent: Reactor) {
super(parent)
this.addReaction(
new Triggers(this.t),
new Args(this.t),
function (this) {
console.log(this.getBankIndex());
}
);
}
}

class Generic<T extends Present> extends Reactor {
input: InPort<T> = new InPort(this);
}

describe('Check bank index', () => {

class myApp extends App {
b = new Bank(this, 3, Periodic, this)
c = new Bank<Generic<number>, [Reactor]>(this, 2, Generic, this);
constructor() {
super();
test('contained bank member name', () => {
expect(this.b.get(0)._getFullyQualifiedName()).toBe("myApp.b[0]")
expect(this.b.get(1)._getFullyQualifiedName()).toBe("myApp.b[1]")
expect(this.b.get(2)._getFullyQualifiedName()).toBe("myApp.b[2]")
})
it('contained bank member index', () => {
expect(this.b.get(0).getBankIndex()).toBe(0);
expect(this.b.get(1).getBankIndex()).toBe(1);
expect(this.b.get(2).getBankIndex()).toBe(2);
});

it('generic bank', () => {
this.c.all().forEach(r => expect(typeof r.input == "number"))
});
var foo = this.b.port((member) => member.o)
var bar = [this.b.get(0).o, this.b.get(1).o, this.b.get(2).o]
it('select port', () => {
for (let i=0; i < foo.length; i++) {
expect(foo[i]).toBe(bar[i]);
}
});
}
}

new myApp();

});
99 changes: 99 additions & 0 deletions __tests__/connection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Reactor, App, Triggers, Args, State, OutPort, InPort, TimeUnit, TimeValue } from '../src/core/internal';

describe('Check canConnect', () => {
class Source extends Reactor {
out: OutPort<number> = new OutPort(this)
}
class Destination extends Reactor {
in: InPort<number> = new InPort(this)
out: InPort<number> = new InPort(this)
}

class TestApp extends App {
source: Source
destination: Destination

constructor() {
super()
this.source = new Source(this)
this.destination = new Destination(this)

it('canConnect success out->in', () => {
expect(this.canConnect(this.source.out, this.destination.in)).toBe(true)
})

it('canConnect success out->out', () => {
expect(this.canConnect(this.source.out, this.destination.out)).toBe(true)
})

it('canConnect failure', () => {
expect(this.canConnect(this.destination.in, this.source.out)).toBe(false)
})
}
}
var testApp = new TestApp()
})

describe('Check _connect', () => {
jest.setTimeout(5000);

class Source extends Reactor {
out: OutPort<number> = new OutPort(this)
constructor(container: Reactor) {
super(container);
this.addReaction(
new Triggers(this.startup),
new Args(this.writable(this.out)),
function(this, __out) {
__out.set(100);

}
);
}
}
class Destination extends Reactor {
in: InPort<number> = new InPort(this)
received: State<number> = new State(0)
constructor(container: Reactor) {
super(container)
this.addReaction(
new Triggers(this.in),
new Args(this.in, this.received),
function(this, __in, __received) {
let tmp = __in.get();
try
{
if(tmp)
{
__received.set(tmp)
}
} finally {

}
}
)
}
}

class TestApp extends App {
source: Source
destination: Destination

constructor(timeout: TimeValue, success?: () => void, fail?: () => void) {
super(timeout, false, false, success, fail)
this.source = new Source(this)
this.destination = new Destination(this)
this._connect(this.source.out, this.destination.in)
}
}

it("_connect success", done => {
function fail() {
throw new Error("Test has failed.");
};

let testApp = new TestApp(TimeValue.withUnits(1,TimeUnit.nsec), done, fail)
testApp._start()
expect(testApp.destination.received.get()).toBe(100)
})
})
45 changes: 25 additions & 20 deletions __tests__/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {SortableDependencyGraph, Sortable, PrioritySetElement, PrioritySet, Log, LogLevel} from '../src/core/util';
import {Reactor, App, Triggers, InPort, Args, ArgList, Startup, Shutdown} from '../src/core/reactor';
import {Reaction, Priority} from "../src/core/reaction"
import {Reactor, App, Triggers, Args, InPort, Reaction, Priority,
SortableDependencyGraph, Sortable, PrioritySet, Log, StringUtil} from '../src/core/internal';

//Log.setGlobalLevel(Log.levels.DEBUG);

Expand Down Expand Up @@ -103,11 +102,13 @@ describe('Manually constructed precedence graphs', () => {
expect(graph.size()[0]).toEqual(6); // V
expect(graph.size()[1]).toEqual(7); // E
expect(graph.toString()).toBe(
`digraph G {
"App/R[R0]"->"App/R[R1]"->"App/R[R4]"->"App/R[R3]"->"App/R[R5]";
"App/R[R0]"->"App/R[R4]";
"App/R[R1]"->"App/R[R2]"->"App/R[R3]";
}`);
StringUtil.dontIndent
`digraph G {
"app.R[R0]"->"app.R[R1]"->"app.R[R4]"->"app.R[R3]"->"app.R[R5]";
"app.R[R0]"->"app.R[R4]";
"app.R[R1]"->"app.R[R2]"->"app.R[R3]";
}`
);
});

it('initial priorities', () => {
Expand All @@ -126,9 +127,9 @@ describe('Manually constructed precedence graphs', () => {
expect(graph.size()[1]).toEqual(6); // E
expect(graph.toString()).toBe(
`digraph G {
"App/R[R0]"->"App/R[R1]"->"App/R[R2]"->"App/R[R3]"->"App/R[R5]";
"App/R[R1]"->"App/R[R4]";
"App/R[R0]"->"App/R[R4]";
"app.R[R0]"->"app.R[R1]"->"app.R[R2]"->"app.R[R3]"->"app.R[R5]";
"app.R[R1]"->"app.R[R4]";
"app.R[R0]"->"app.R[R4]";
}`);
});

Expand All @@ -138,10 +139,12 @@ describe('Manually constructed precedence graphs', () => {
expect(graph.size()[1]).toEqual(3); // E
Log.global.debug(graph.toString());
expect(graph.toString()).toBe(
`digraph G {
"App/R[R2]"->"App/R[R3]"->"App/R[R5]";
"App/R[R0]"->"App/R[R4]";
}`);
StringUtil.dontIndent
`digraph G {
"app.R[R2]"->"app.R[R3]"->"app.R[R5]";
"app.R[R0]"->"app.R[R4]";
}`
);
});

it('add node 7, make 3 dependent on it', () => {
Expand All @@ -151,11 +154,13 @@ describe('Manually constructed precedence graphs', () => {
expect(graph.size()[1]).toEqual(4); // E
Log.global.debug(graph.toString());
expect(graph.toString()).toBe(
`digraph G {
"App/R[R2]"->"App/R[R3]"->"App/R[R5]";
"App/R[R0]"->"App/R[R4]";
"App/R[R2]"->"App/R[R6]";
}`);
StringUtil.dontIndent
`digraph G {
"app.R[R2]"->"app.R[R3]"->"app.R[R5]";
"app.R[R0]"->"app.R[R4]";
"app.R[R2]"->"app.R[R6]";
}`
);
});

it('reassign priorities', () => {
Expand Down
Loading

0 comments on commit bf59b4e

Please sign in to comment.