Skip to content

Commit

Permalink
API rework
Browse files Browse the repository at this point in the history
  • Loading branch information
irdkwmnsb authored and spcfox committed Jun 16, 2023
1 parent dc54527 commit b33e100
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 45 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 0 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BubbleSortStarter } from "./visualizers/bubble-sort/start";
import { globalStore } from "./lib";
import { BubbleSortRender } from "./visualizers/bubble-sort/render";
import { useVisualizer } from "./lib/hooks";
import { useEffect, useState } from "react";
Expand Down
2 changes: 1 addition & 1 deletion src/lib/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useSyncExternalStore } from "react";
import { globalStore } from ".";
import { globalStore } from "../visualizers/bubble-sort";

export const useVisualizer = () => {
return useSyncExternalStore(globalStore.subscribe, globalStore.getCurSnapshot);
Expand Down
12 changes: 0 additions & 12 deletions src/lib/index.tsx

This file was deleted.

16 changes: 16 additions & 0 deletions src/lib/manifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC } from "react";

export type StartProps<Arguments> = {
doStart: (args: Arguments, noStop: boolean) => void
}

export type RenderProps<State, Event> = {
curState: State;
curEvent: Event;
}

export type AlgorithmManifest<State, Event, Arguments extends unknown[]> = {
algo: (...args: Arguments) => Promise<void>,
startComponent: FC<StartProps<Arguments>>,
renderComponent: FC<RenderProps<State, Event>>
}
41 changes: 23 additions & 18 deletions src/lib/store.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import _ from "lodash";

type StoredEvent = {
name: string;
state: any;
args: any[];
type BaseEvent = {
name: string,
args: unknown[]
};

type StoredEvent<Event extends BaseEvent, State> = Event & {
state: State;
}

type Snapshot = {
curState?: any;
curEvent?: StoredEvent;
type Snapshot<State, Event extends BaseEvent, Arguments> = {
curState?: State;
curEvent?: StoredEvent<Event, State>;
currentStep?: number;
events?: StoredEvent[];
events?: StoredEvent<Event, State>[];
bindedObjects?: Record<string, any>;
next: () => void;
start: (args: any[], noStop: boolean) => void;
}

export class RuntimeStore {
events: StoredEvent[] = [];
bindedObjects: Record<string, any> = {};
export class RuntimeStore<State, Event extends BaseEvent, Arguments> {
events: StoredEvent<Event, State>[] = [];
bindedObjects: Record<keyof State, State[keyof State]> = {} as Record<keyof State, State[keyof State]>; // TODO: fix this
continuation?: () => void;
subscribers: (() => void)[] = [];
algorithm?: (...args) => Promise<void>;
Expand All @@ -29,17 +32,19 @@ export class RuntimeStore {
this.algorithm = algorithm;
}

bind = (name: string, value: any) => {
bind = (name: keyof State, value: State[keyof State]) => {
console.log("Binded", name);
this.bindedObjects[name] = value;
}

here = async (name: string, ...args: any[]): Promise<void> => {
here = async (name: Event["name"], ...args: Event["args"]): Promise<void> => {
console.log("!!", this.bindedObjects);
this.currentStep++;
this.events.push({
name,
state: _.cloneDeep(this.bindedObjects),
args
});
args,
state: _.cloneDeep(this.bindedObjects) as State,
} as StoredEvent<Event, State>);
if (this.noStop) {
return Promise.resolve();
}
Expand Down Expand Up @@ -88,7 +93,7 @@ export class RuntimeStore {
this.events = [];
this.continuation = undefined;
this.currentStep = 0;
this.bindedObjects = {};
this.bindedObjects = {} as Record<keyof State, State[keyof State]>; // TODO: fix this
this.noStop = noStop;
this.notifyReact();
this.algorithm(...args).then(() => {
Expand All @@ -103,7 +108,7 @@ export class RuntimeStore {
};
}

_dataSnapshot: Snapshot = {
_dataSnapshot: Snapshot<State, Event, Arguments> = {
start: this.start,
next: this.next,
};
Expand Down
9 changes: 6 additions & 3 deletions src/visualizers/bubble-sort/bubble-sort.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bind, here } from "../../lib";
import { bind, here } from "./";

export const bubbleSort = async (array: number[]) => {
bind("array", array);
Expand All @@ -22,8 +22,11 @@ export type BubbleSortState = {
}

export type BubbleSortEvent = {
name: "compare" | "swap";
args: [number, number];
name: "swap" | "compare",
args: [number, number]
} | {
name: "done",
args: []
}

export type BubbleSortArguments = [number[]];
21 changes: 21 additions & 0 deletions src/visualizers/bubble-sort/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AlgorithmManifest } from "../../lib/manifest";
import { RuntimeStore } from "../../lib/store";
import { BubbleSortArguments, BubbleSortEvent, BubbleSortState, bubbleSort } from "./bubble-sort";
import { BubbleSortRender } from "./render";
import { BubbleSortStarter } from "./start";

export const manifest: AlgorithmManifest<BubbleSortState, BubbleSortEvent, BubbleSortArguments> = {
algo: bubbleSort,
startComponent: BubbleSortStarter,
renderComponent: BubbleSortRender
}

export const globalStore = new RuntimeStore<BubbleSortState, BubbleSortEvent, BubbleSortArguments>(bubbleSort);

export const bind = (name: keyof BubbleSortState, value: BubbleSortState[keyof BubbleSortState]) => {
globalStore.bind(name, value);
}

export const here = async (name: BubbleSortEvent["name"], ...args: BubbleSortEvent["args"]): Promise<void> => {
return globalStore.here(name, ...args);
}
23 changes: 17 additions & 6 deletions src/visualizers/bubble-sort/render.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
import { RenderProps } from "../../lib/manifest";
import { BubbleSortEvent, BubbleSortState } from "./bubble-sort";

export type RenderProps = {
curState: BubbleSortState;
curEvent: BubbleSortEvent;
}
// export type RenderProps = {
// curState: BubbleSortState;
// curEvent: BubbleSortEvent;
// }

const COLORS = {
"compare": "red",
"swap": "green",
"done": "cyan"
}

export const BubbleSortRender = ({ curState, curEvent }) => {
const getColor = (event: BubbleSortEvent, index: number) => {
if (event.name === "done") {
return COLORS["done"]
} else {
if(event.args.includes(index)) {
return COLORS[event.name]
}
}
}

export const BubbleSortRender = ({ curState, curEvent }: RenderProps<BubbleSortState, BubbleSortEvent>) => {
console.log("Rendering", curState, curEvent);
const comparing = curEvent?.args;
return <div>
Renderer:
<div>
{curState && curState.array.map((value, index) => {
return <div key={value + "!" + index} style={{
backgroundColor: comparing?.includes(index) || curEvent.name === "done" ? COLORS[curEvent.name] : "white"
backgroundColor: getColor(curEvent, index)
}}>
{value}
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/visualizers/bubble-sort/start.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BubbleSortArguments } from "./bubble-sort"

type Props = {
doStart: (args: BubbleSortArguments, noStop: boolean) => void
}
// type Props = {
// doStart: (args: BubbleSortArguments, noStop: boolean) => void
// }

export const BubbleSortStarter = ({ doStart}: Props) => {
export const BubbleSortStarter = ({ doStart }) => {
return <div>
<button onClick={() => doStart([[5, 4, 3, 2, 1]], false)}>Start</button>
<button onClick={() => doStart([[5, 4, 3, 2, 1]], true)}>Run Full</button>
Expand Down

0 comments on commit b33e100

Please sign in to comment.