Skip to content

Commit

Permalink
Merge pull request #18 from saurabh-prosoft/feature/generic-persistence
Browse files Browse the repository at this point in the history
Feature/generic persistence
  • Loading branch information
saurabh-prosoft committed Jun 22, 2023
2 parents 5e3b018 + 3500de0 commit e1c9531
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 30 deletions.
2 changes: 1 addition & 1 deletion docs/.vuepress/config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ module.exports = {
},
],
},
{ text: "v2.0.5", link: "/" },
{ text: "v2.0.6", link: "/" },
],
sidebar: {
"/guide/": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flow-connect",
"version": "2.0.5",
"version": "2.0.6",
"description": "FlowConnect is a highly-customizable library for creating node-based editors, graphs and diagrams.",
"type": "module",
"main": "dist/cjs/flow-connect.js",
Expand Down
12 changes: 5 additions & 7 deletions src/core/flow.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Color, FlowConnect } from "../flow-connect.js";
import { Vector } from "./vector.js";
import { SerializedVector, Vector } from "./vector.js";
import { Node, NodeOptions, SerializedNode } from "./node.js";
import { Hooks } from "./hooks.js";
import { Group, SerializedGroup } from "./group.js";
Expand All @@ -16,7 +16,7 @@ import {
} from "../common/interfaces.js";
import { SerializedSubFlowNode, SubFlowNode, SubFlowNodeOptions } from "./subflow-node.js";
import { TunnelNode, SerializedTunnelNode, TunnelNodeOptions } from "./tunnel-node.js";
import { capitalize, uuid } from "../utils/utils.js";
import { capitalize, isVector, uuid } from "../utils/utils.js";
import { Graph } from "./graph.js";
import { Terminal } from "./terminal.js";
import { Log } from "../utils/logger.js";
Expand Down Expand Up @@ -252,12 +252,10 @@ export class Flow extends Hooks implements Serializable<SerializedFlow> {
receive?: DataFetchProvider
): Promise<Record<string, any>> {
for (let key in state) {
if (
typeof state[key] === "object" &&
state[key] &&
Object.keys(state[key]).every((k) => ["x", "y"].includes(k) && typeof state[key][k] === "number")
) {
if (isVector(state[key])) {
state[key] = Vector.create(state[key].x, state[key].y);
} else if (Array.isArray(state[key]) && state[key].length > 0 && isVector(state[key][0])) {
state[key] = state[key].map((sv: SerializedVector) => Vector.create(sv.x, sv.y));
} else if (typeof state[key] === "object" && state[key] && state[key].id?.startsWith("raw##")) {
if (receive) {
state[key] = await receive({ ...state[key], id: (state[key].id as string).replace("raw##", "") });
Expand Down
2 changes: 1 addition & 1 deletion src/flow-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ export class FlowConnect extends Hooks {

let hitNode = this.getHitNode(screenPosition);
let hitColor = Color.rgbaToString(this.offUIContext.getImageData(screenPosition.x, screenPosition.y, 1, 1).data);
let currHitUINode = hitNode.getHitUINode(hitColor);
let currHitUINode = hitNode?.getHitUINode(hitColor);
if (!currHitUINode) {
this.call("dbl-press", { screenPos: screenPosition, realPos: realPosition, target: hitNode ?? this });
}
Expand Down
39 changes: 33 additions & 6 deletions src/ui/envelope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ export class Envelope extends UINode<EnvelopeStyle> {
private offPointsContext: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;

get value(): Vector[] {
return this._value.toArray().map((vec) => vec.clone());
let value;
if (this.propName) value = this.getProp().map((vec: Vector) => vec.clone());
else value = this._value.toArray().map((vec) => vec.clone());

return value;
}
set value(value: Vector[]) {
const oldVal = this.value;
let oldVal = this._value.toArray().map((vec) => vec.clone());
let newVal = value;

this.handleEnvelopeChange(value);
if (this.propName) {
this.setProp(newVal);
} else {
this.handleEnvelopeChange(newVal);
}

if (this.node.flow.state !== FlowState.Stopped) this.call("change", this, oldVal, this._value.toArray());
if (this.node.flow.state !== FlowState.Stopped) this.call("change", this, oldVal, newVal);
}

constructor(_node: Node, options: EnvelopeOptions = DefaultEnvelopeOptions()) {
Expand Down Expand Up @@ -66,7 +75,7 @@ export class Envelope extends UINode<EnvelopeStyle> {
}
this.offPointsContext = this.offPointsCanvas.getContext("2d");

this.handleEnvelopeChange(values);
this.handleEnvelopeChange(this.getProp() ?? values);
}

handleEnvelopeChange(values: Vector[]) {
Expand Down Expand Up @@ -183,6 +192,8 @@ export class Envelope extends UINode<EnvelopeStyle> {
.clampInPlace(this.currHitPoint.prev?.data.x || 0, this.currHitPoint.next?.data.x || 1, -Infinity, Infinity);
this.currHitPoint.data = Vector.create(this.currHitPoint.data.x, 1 - this.currHitPoint.data.y);

this.updateState();

this.renderOffPoints();
}
newPoint(realPosition: Vector, width: number, height: number) {
Expand All @@ -201,6 +212,9 @@ export class Envelope extends UINode<EnvelopeStyle> {

this.pointHitColorPoint.set(Color.Random().hexValue, newPointNode);
this.renderOffPoints();

this.updateState();

if (this.node.flow.state !== FlowState.Stopped) this.call("change", this, oldVal, this._value.toArray());
}
deletePoint() {
Expand All @@ -209,10 +223,23 @@ export class Envelope extends UINode<EnvelopeStyle> {
this.pointHitColorPoint.delete(this.currHitPoint);
this.renderOffPoints();

this.updateState();

if (this.node.flow.state !== FlowState.Stopped) this.call("change", this, oldVal, this._value.toArray());
}
updateState() {
if (this.propName && this.node.state[this.propName]) {
this.node.state[this.propName].length = 0;
const updatedVal = this._value.toArray().map((vec) => vec.clone());
this.node.state[this.propName].push(...updatedVal);
}
}

onPropChange(_oldVal: any, newVal: any) {
this.handleEnvelopeChange(newVal);

onPropChange() {}
this.output && this.output.setData(newVal);
}

private currHitPoint: ListNode<Vector>;
private lastDownPosition: Vector;
Expand Down
25 changes: 11 additions & 14 deletions src/utils/linked-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class List<T> extends Hooks {

constructor(public comparator?: (a: T, b: T) => number, source?: Array<T>) {
super();
if (source) source.forEach(value => this.append(value));
if (source) source.forEach((value) => this.append(value));
}

prepend(data: T) {
Expand All @@ -22,7 +22,7 @@ export class List<T> extends Hooks {
}

this.length += 1;
this.call('prepend', this, newNode);
this.call("prepend", this, newNode);
return newNode;
}
append(data: T | ListNode<T>) {
Expand All @@ -37,7 +37,7 @@ export class List<T> extends Hooks {
}

this.length += 1;
this.call('append', this, newNode);
this.call("append", this, newNode);
return newNode;
}
removeFirst(hook: boolean = true): T {
Expand All @@ -54,7 +54,7 @@ export class List<T> extends Hooks {
}

this.length -= 1;
if (hook) this.call('removefirst', this, removed);
if (hook) this.call("removefirst", this, removed);
return removed;
}
removeLast(): T {
Expand All @@ -71,7 +71,7 @@ export class List<T> extends Hooks {
}

this.length -= 1;
this.call('removelast', this, removed);
this.call("removelast", this, removed);
return removed;
}
addAfter(data: T, node: ListNode<T>): ListNode<T> {
Expand Down Expand Up @@ -100,11 +100,8 @@ export class List<T> extends Hooks {
if (this.length === 1) {
this.head = null;
this.tail = null;
}
else if (node === this.head)
this.removeFirst();
else if (node === this.tail)
this.removeLast();
} else if (node === this.head) this.removeFirst();
else if (node === this.tail) this.removeLast();
else {
if (node.prev) node.prev.next = node.next;
if (node.next) node.next.prev = node.prev;
Expand All @@ -130,7 +127,7 @@ export class List<T> extends Hooks {
get(index: number): T {
if (index >= this.length) return null;
else if (index === 0) return this.head ? this.head.data : null;
else if (index === (this.length - 1)) return this.tail ? this.tail.data : null;
else if (index === this.length - 1) return this.tail ? this.tail.data : null;
else {
let count = 0;
let curr = this.head;
Expand All @@ -152,16 +149,16 @@ export class List<T> extends Hooks {
}
map(callback: (node: ListNode<T>) => any): any[] {
let mapped: any[] = [];
this.forEach(node => mapped.push(callback(node)));
this.forEach((node) => mapped.push(callback(node)));
return mapped;
}
toArray(): T[] {
let data: T[] = [];
this.forEach(node => data.push(node.data));
this.forEach((node) => data.push(node.data));
return data;
}
toString(): string {
return this.toArray().join(', ');
return this.toArray().join(", ");
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,10 @@ export const cloneAudioBuffer = (from: AudioBuffer): AudioBuffer => {
}
return cloned;
};
export const isVector = (obj: any) => {
return (
typeof obj === "object" &&
obj &&
Object.keys(obj).every((k) => ["x", "y"].includes(k) && typeof obj[k] === "number")
);
};

0 comments on commit e1c9531

Please sign in to comment.