Skip to content

Commit

Permalink
add color to snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
stackdump committed Nov 24, 2023
1 parent a974698 commit 5c575eb
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 19 deletions.
28 changes: 19 additions & 9 deletions model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ export interface Result {
out: Vector;
ok: boolean;
role: string;
inhibited?: boolean;
overflow?: boolean;
underflow?: boolean;
}

export interface Model {
Expand Down Expand Up @@ -268,19 +271,25 @@ export function newModel({schema, declaration, type}: ModelOptions): Model {
return ok;
}

function vectorAdd(state: Vector, delta: Vector, multiple: number): { out: Vector; ok: boolean } {
function vectorAdd(state: Vector, delta: Vector, multiple: number): {
out: Vector; ok: boolean; overflow: boolean; underflow: boolean;
} {
let overflow = false;
let underflow = false;
const cap = capacityVector();
const out: Vector = [];
let ok = true;
for (const i in state) {
out[i] = (state[i] + (delta[i] || 0) * multiple);
if (out[i] < 0) {
underflow = true;
ok = false; // underflow: contains negative
} else if (cap[i] > 0 && cap[i] - out[i] < 0) {
overflow = true;
ok = false; // overflow: exceeds capacity
}
}
return {out, ok};
return {out, ok, overflow, underflow};
}

function guardFails(state: Vector, action: string, multiple: number) {
Expand All @@ -300,11 +309,12 @@ export function newModel({schema, declaration, type}: ModelOptions): Model {

function testFire(state: Vector, action: string, multiple: number): Result {
const t = def.transitions.get(action);
if (!t || guardFails(state, action, multiple)) {
return {out: [], ok: false, role: t?.role?.label || "unknown"};
const inhibited = guardFails(state, action, multiple);
if (!t || inhibited) {
return {out: [], ok: false, role: t?.role?.label || "unknown", inhibited};
}
const res = vectorAdd(state, t.delta, multiple);
return {out: res.out, ok: res.ok, role: t.role.label};
const {out, ok,underflow, overflow} = vectorAdd(state, t.delta, multiple);
return {out, ok, role: t.role.label, inhibited, overflow, underflow};
}

function fire(state: Vector, action: string, multiple: number, resolve?: (res: Result) => void, reject?: (res: Result) => void): Result {
Expand All @@ -324,7 +334,7 @@ export function newModel({schema, declaration, type}: ModelOptions): Model {
elementaryOutputs++;
}
}
res = {...res, ok: !failsHardCap && elementaryOutputs < 2 };
res = {...res, ok: !failsHardCap && elementaryOutputs < 2, overflow: failsHardCap };
break;
case ModelType.workflow:
let wfOutputs = 0;
Expand All @@ -339,7 +349,7 @@ export function newModel({schema, declaration, type}: ModelOptions): Model {
wfOut[i] = res.out[i];
} // NOTE: ignore negative values
}
res = {...res, out: wfOut, ok: !failsWfCap && wfOutputs < 2 };
res = {...res, out: wfOut, ok: !failsWfCap && wfOutputs < 2, overflow: failsWfCap };
break;
}
if (res.ok) {
Expand Down Expand Up @@ -399,7 +409,7 @@ export function newModel({schema, declaration, type}: ModelOptions): Model {
if (outStates <= 1) {
res.ok = true;
}
return { out, ok: res.ok, role: res.role };
return { out, ok: res.ok, role: res.role, inhibited: res.inhibited };
}

if (declaration) {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pflow-dev/metamodel",
"version": "0.3.4",
"version": "0.4.0",
"main": "/index.js",
"types": "/index.d.ts",
"description": "create workflows and petriNets with a DSL",
Expand Down
25 changes: 18 additions & 7 deletions snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Model, Place, Transition} from "./model";
import {Model, Place, Transition, Vector} from "./model";

const tokenTemplate = ({p, tokens}: { p: Place; tokens: number }) => {
if (tokens === 0) {
Expand Down Expand Up @@ -32,12 +32,13 @@ interface ArcParams {
const arcTemplate = ({stroke, markerEnd, weight, x1, y1, x2, y2, midX, offsetX, midY, offsetY}: ArcParams) =>
`<line stroke="${stroke}" marker-end="${markerEnd}" x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" />` +
`<text x="${midX - offsetX}" y="${midY + offsetY}" >${weight}</text>`;

const transitionTemplate = ({fill, stroke, t}: { fill: string; stroke: string; t: Transition }) =>
`<rect width="30" height="30" fill="${fill}" stroke="${stroke}" rx="${4}" x="${t.position.x - 15}" y="${t.position.y - 15}" />` +
`<text font-size="smaller" x="${t.position.x - 15}" y="${t.position.y - 20}" >${t.label}</text>`;
const placeTemplate = ({p}: { p: Place }) =>
const placeTemplate = ({p, tokens}: { p: Place; tokens: number }) =>
`<circle cx="${p.position.x}" cy="${p.position.y}" r="16" fill="white" stroke="black" />` +
`${tokenTemplate({p, tokens: p.initial})}` +
`${tokenTemplate({p, tokens})}` +
`<text font-size="smaller" x="${p.position.x - 18}" y="${p.position.y - 20}" >${p.label}</text>`;
const template = ({
page,
Expand Down Expand Up @@ -92,23 +93,33 @@ function getArcPoints(

type HashChar = "#" | "%32";

export function snapshot(model: Model, options?: { hashChar?: HashChar }) {
export function snapshot(model: Model, options?: { state?: Vector; hashChar?: HashChar }) {
const state = options?.state;
const hashChar = options?.hashChar ? options.hashChar : "#"; // use "%32" for data URI

const {transitions, places} = model.def;
const page = model.getSize(); // FIXME: port from other repo
let transitionTags = "";
transitions.forEach((t) => {
function getFill() {
const res = model.testFire(state, t.label, 1);
if (res.ok) {
return "#62fa75";
}
if (res.inhibited) {
return "#fab5b0";
}
return "#ffffff";
}
transitionTags += transitionTemplate({
fill: "white",
fill: getFill(), // "white", // TODO: colorize model
stroke: "black",
t,
});
});
const placeIndex: Array<Place> = [];
let placeTags = "";
places.forEach((p) => {
placeTags += placeTemplate({p: p});
placeTags += placeTemplate({p: p, tokens: state? state[p.offset] : p.initial});
placeIndex[p.offset] = p;
});
let arcTags = "";
Expand Down

0 comments on commit 5c575eb

Please sign in to comment.