Skip to content

Commit

Permalink
splendid (#143)
Browse files Browse the repository at this point in the history
* improvements

* reactive wildcards

* json betterer
  • Loading branch information
Brendonovich authored Jun 16, 2023
1 parent 9655cd1 commit 3c6d5c6
Show file tree
Hide file tree
Showing 23 changed files with 205 additions and 179 deletions.
2 changes: 0 additions & 2 deletions app/src/UIStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ export function createUIStore() {
};
},
setSelectedItem(item?: Node | CommentBox) {
if (state.selectedItem) state.selectedItem.selected = false;
state.selectedItem = item ?? null;
if (item) item.selected = true;
},
setPinPosition(pin: Pin, position: XY) {
state.pinPositions.set(pin, position);
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/Graph/CommentBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default (props: Props) => {
<div
class={clsx(
"bg-white/30 rounded border-black/75 border-2 absolute top-0 left-0",
props.box.selected && "ring-2 ring-yellow-500"
UI.state.selectedItem === props.box && "ring-2 ring-yellow-500"
)}
style={{
transform: `translate(${position().x}px, ${position().y}px)`,
Expand Down Expand Up @@ -125,7 +125,7 @@ export default (props: Props) => {

onMount(() => ref?.focus());

createEffect(() => setEditing(props.box.selected));
createEffect(() => setEditing(UI.state.selectedItem === props.box));

onCleanup(() => {
if (value() !== "") props.box.text = value();
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/Graph/IO/DataInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ const Input = (props: InputProps) => {
<Match
when={
props.type instanceof WildcardType &&
props.type.wildcard.value.isSome() &&
props.type.wildcard.value().isSome() &&
props.type
}
>
{(type) => (
<Input
value={props.value}
onChange={props.onChange}
type={type().wildcard.value.unwrap()}
type={type().wildcard.value().unwrap()}
connected={props.connected}
/>
)}
Expand Down
11 changes: 5 additions & 6 deletions app/src/components/Graph/IO/DataPin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
DataInput,
DataOutput,
ListType,
OptionType,
t,
WildcardType,
} from "@macrograph/core";
Expand Down Expand Up @@ -43,8 +42,8 @@ export const DataPin = (props: Props) => {
if (type instanceof WildcardType) {
const value = type.wildcard.value;

if (value.isSome()) {
return rounding(value.unwrap());
if (value().isSome()) {
return rounding(value().unwrap());
}
}

Expand All @@ -54,7 +53,7 @@ export const DataPin = (props: Props) => {
const innerType = {
get value() {
if (pin.type instanceof WildcardType) {
return pin.type.wildcard.value.unwrapOr(pin.type);
return pin.type.wildcard.value().unwrapOr(pin.type);
} else return pin.type;
},
};
Expand All @@ -70,7 +69,7 @@ export const DataPin = (props: Props) => {
const value = type();

if (value instanceof t.Wildcard) {
return value.wildcard.value.unwrapOr(value);
return value.wildcard.value().unwrapOr(value);
} else return value;
},
};
Expand Down Expand Up @@ -164,7 +163,7 @@ export const DataPin = (props: Props) => {
);
}}
</Match>
<Match when={pin.type}>
<Match when={innerType.value}>
{(type) => {
return (
<div
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/Graph/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const Node = (props: Props) => {
ref={ref}
class={clsx(
"absolute top-0 left-0 text-[12px] overflow-hidden rounded-lg flex flex-col bg-black/75 border-black/75 border-2",
node().selected && "ring-2 ring-yellow-500"
UI.state.selectedItem === node() && "ring-2 ring-yellow-500"
)}
style={{
transform: `translate(${node().position.x}px, ${
Expand Down
28 changes: 14 additions & 14 deletions app/src/components/Graph/util.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import {
AnyType,
BasePrimitiveType,
EnumType,
ListType,
MapType,
OptionType,
PrimitiveVariant,
StructType,
t,
} from "@macrograph/core";

const PrimitiveVariantColours: Record<PrimitiveVariant, string> = {
Expand All @@ -20,20 +16,24 @@ export const colour = (type: AnyType): string => {
if (type instanceof BasePrimitiveType)
return PrimitiveVariantColours[type.primitiveVariant()];

if (type instanceof ListType || type instanceof OptionType)
if (type instanceof t.List || type instanceof t.Option)
return colour(type.inner);

if (type instanceof MapType) return colour(type.value);
if (type instanceof t.Map) return colour(type.value);

if (type instanceof EnumType) return "[--mg-current:#1B4DFF]";
if (type instanceof t.Enum) return "[--mg-current:#1B4DFF]";

if (type instanceof StructType) return "[--mg-current:#FACC15]";
if (type instanceof t.Struct) return "[--mg-current:#FACC15]";

const value = type.wildcard.value;
if (type instanceof t.Wildcard) {
const value = type.wildcard.value();

if (value.isSome()) {
return colour(value.unwrap());
} else {
return "[--mg-current:white]";
if (value.isSome()) {
return colour(value.unwrap());
} else {
return "[--mg-current:white]";
}
}

throw new Error();
};
2 changes: 0 additions & 2 deletions core/src/models/CommentBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export class CommentBox {
size: XY;
text: string;

selected = false;

constructor(args: CommentBoxArgs) {
this.position = args.position;
this.size = args.size;
Expand Down
19 changes: 17 additions & 2 deletions core/src/models/Core.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createMutable } from "solid-js/store";
import { Package, PackageArgs } from "./Package";
import { Node } from "./Node";
import { DataInput, DataOutput, ExecOutput } from "./IO";
import { DataInput, DataOutput, ExecOutput, ScopeOutput } from "./IO";
import { EventsMap, RunCtx } from "./NodeSchema";
import { z } from "zod";
import { Project, SerializedProject } from "./Project";
Expand Down Expand Up @@ -87,7 +87,7 @@ export class Core {
}

class ExecutionContext {
data = new Map<DataOutput, any>();
data = new Map<DataOutput | ScopeOutput, any>();

constructor(public root: Node) {}

Expand All @@ -113,6 +113,21 @@ class ExecutionContext {

await this.execNode(output.connection.node as any);
},
execScope: async (scopeOutput, data) => {
NODE_EMIT.emit(node);

const output = node.output(scopeOutput);

if (!output) throw new Error(`Output ${scopeOutput} not found!`);
if (!(output instanceof ScopeOutput))
throw new Error(`Output ${scopeOutput} is not a ScopeOutput!`);

if (!output.connection) return;

this.data.set(output, data);

await this.execNode(output.connection.node as any);
},
setOutput: (name, value) => {
const output = node.output(name);

Expand Down
24 changes: 13 additions & 11 deletions core/src/models/Graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,20 +248,22 @@ export class Graph {

graph.nodeIdCounter = data.nodeIdCounter;

graph.nodes = new ReactiveMap(
Object.entries(data.nodes)
.map(([idStr, serializedNode]) => {
const id = z.coerce.number().parse(idStr);
const node = Node.deserialize(graph, serializedNode);
batch(() => {
graph.nodes = new ReactiveMap(
Object.entries(data.nodes)
.map(([idStr, serializedNode]) => {
const id = z.coerce.number().parse(idStr);
const node = Node.deserialize(graph, serializedNode);

if (node === null) return null;
if (node === null) return null;

project.core.addEventNodeMapping(node);
project.core.addEventNodeMapping(node);

return [id, node] as [number, Node];
})
.filter(Boolean) as [number, Node][]
);
return [id, node] as [number, Node];
})
.filter(Boolean) as [number, Node][]
);
});

let i = 0;
let connections = [...data.connections];
Expand Down
63 changes: 38 additions & 25 deletions core/src/models/Node.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IOBuilder, NodeSchema, ScopeRef } from "./NodeSchema";
import { IOBuilder, NodeSchema } from "./NodeSchema";
import {
DataInput,
DataInputArgs,
Expand All @@ -20,7 +20,7 @@ import { XY } from "../bindings";
import { createMutable } from "solid-js/store";
import { z } from "zod";
import { untrack, createRoot, createRenderEffect } from "solid-js";
import { typesCanConnect, Wildcard } from "../types";
import { typesCanConnect } from "../types";

export interface NodeArgs {
id: number;
Expand Down Expand Up @@ -52,17 +52,13 @@ export class Node {
schema: NodeSchema;
inputs: (DataInput | ExecInput | ScopeInput)[] = [];
outputs: (DataOutput | ExecOutput | ScopeOutput)[] = [];
wildcards = new Map<string, Wildcard>();
scopes = new Map<string, ScopeRef>();

io!: IOBuilder;
dispose: () => void;

selected = false;

constructor(args: NodeArgs) {
this.id = args.id;
this.name = args.schema.name;
this.id = args.id;
this.graph = args.graph;
this.position = args.position;
this.schema = args.schema;
Expand All @@ -71,7 +67,7 @@ export class Node {

this.dispose = createRoot((dispose) => {
createRenderEffect(() => {
const builder = new IOBuilder(this.wildcards, this.scopes);
const builder = new IOBuilder(this.io);

reactiveThis.schema.generateIO(builder, {});

Expand All @@ -80,22 +76,33 @@ export class Node {
this.io = builder;
});

return dispose;
return () => {
dispose();
};
});

return reactiveThis;
}

updateIO(reactiveThis: this, io: IOBuilder) {
reactiveThis.wildcards = io.wildcards;
reactiveThis.scopes = io.scopes;
this.io?.wildcards.forEach((w) => {
if (!io.wildcards.has(w.id)) {
w.dispose();
}
});

reactiveThis.inputs = reactiveThis.inputs.filter((oldInput) =>
io.inputs.find(
(newInput) =>
oldInput.id === newInput.id && oldInput.variant === newInput.variant
let newInputs = [];
for (const oldInput of reactiveThis.inputs) {
if (
io.inputs.find(
(newInput) =>
oldInput.id === newInput.id && oldInput.variant === newInput.variant
)
)
);
newInputs.push(oldInput);
else this.graph.disconnectPin(oldInput);
}
reactiveThis.inputs = newInputs;

io.inputs.forEach((newInput, newIndex) => {
const oldInputIndex = reactiveThis.inputs.findIndex(
Expand All @@ -116,16 +123,22 @@ export class Node {
}
});

reactiveThis.outputs = reactiveThis.outputs.filter((oldOutput) =>
io.outputs.find(
(newOutput) =>
oldOutput.id === newOutput.id &&
oldOutput.variant === newOutput.variant &&
(oldOutput instanceof DataOutput && newOutput.variant === "Data"
? typesCanConnect(oldOutput.type, newOutput.type)
: true)
let newOutputs = [];
for (const oldOutput of reactiveThis.outputs) {
if (
io.outputs.find(
(newOutput) =>
oldOutput.id === newOutput.id &&
oldOutput.variant === newOutput.variant &&
(oldOutput instanceof DataOutput && newOutput.variant === "Data"
? typesCanConnect(oldOutput.type, newOutput.type)
: true)
)
)
);
newOutputs.push(oldOutput);
else this.graph.disconnectPin(oldOutput);
}
reactiveThis.outputs = newOutputs;

io.outputs.forEach((newOutput, newIndex) => {
const oldOutputIndex = reactiveThis.outputs.findIndex(
Expand Down
9 changes: 3 additions & 6 deletions core/src/models/NodeSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,18 @@ export class IOBuilder {
wildcards = new Map<string, Wildcard>();
scopes = new Map<string, ScopeRef>();

constructor(
public existingWildcards: Map<string, Wildcard>,
public existingScopes: Map<string, ScopeRef>
) {}
constructor(public previous?: IOBuilder) {}

wildcard(id: string) {
const wildcard = this.existingWildcards.get(id) ?? new Wildcard(id);
const wildcard = this.previous?.wildcards.get(id) ?? new Wildcard(id);

this.wildcards.set(id, wildcard);

return wildcard;
}

scope(id: string) {
const scope = this.existingScopes.get(id) ?? new ScopeRef();
const scope = this.previous?.scopes.get(id) ?? new ScopeRef();

this.scopes.set(id, scope);

Expand Down
3 changes: 2 additions & 1 deletion core/src/types/base.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ZodType } from "zod";
import { TypeVariant } from ".";
import { TypeVariant, Wildcard } from ".";

export abstract class BaseType<TOut = any> {
abstract default(): TOut;
abstract variant(): TypeVariant;
abstract toString(): string;
abstract asZodType(): ZodType<TOut>;
abstract getWildcards(): Wildcard[];
}
Loading

0 comments on commit 3c6d5c6

Please sign in to comment.