Skip to content

Commit

Permalink
more typing, render custom node
Browse files Browse the repository at this point in the history
  • Loading branch information
orangecms committed Nov 24, 2023
1 parent dbd143c commit bcd1d47
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 21 deletions.
54 changes: 54 additions & 0 deletions app/DTNode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { memo, useState } from "react";
import { Handle, NodeProps, Position } from "reactflow";

const style = {
// wordWrap: "break-word",
whiteSpace: "pre-wrap" as "pre-wrap", // This is weird, TypoScripto...
padding: 4,
border: "2px solid",
background: "#0c0c0c",
color: "#fff",
width: 150,
fontSize: 11,
fontFamily: "Fira Code",
};

const DTNode = ({
data,
isConnectable,
targetPosition = Position.Top,
sourcePosition = Position.Bottom
}: NodeProps) => {
const [hovered, setHovered] = useState(false);

const hoverOn = () => setHovered(true);
const hoverOff = () => setHovered(false);

const borderColor = hovered ? "#987987" : "#789789";
const borderStyle = hovered ? "dotted" : "solid";
return (
<>
<Handle
type="target"
position={targetPosition}
isConnectable={isConnectable}
/>
<div
style={{...style, borderColor, borderStyle }}
onMouseEnter={hoverOn}
onMouseLeave={hoverOff}
>
{data?.label}
</div>
<Handle
type="source"
position={sourcePosition}
isConnectable={isConnectable}
/>
</>
);
};

DTNode.displayName = "DTNode";

export default memo(DTNode);
77 changes: 60 additions & 17 deletions app/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
const fourU8ToU32 = (f: number[]) => (f[0] << 24) | (f[1] << 16) | (f[2] << 8) | f[3];
type DTProp = any; // TODO
// TODO
type DTNode = any & {
name: string;
props: DTProp[];
children?: DTNode;
addr?: string;
};

// TODO: Differentiate?
enum NodeType {
custom = "custom",
}

type TransformedNode = {
id: string;
type: NodeType;
position: {
x: number;
y: number;
};
data: {
label: string;
};
};
type TransformedEdge = any; // TODO

const fourU8ToU32 = (f: number[]): number =>
(f[0] << 24) | (f[1] << 16) | (f[2] << 8) | f[3];

const u8ArrToU32Arr = (u8a: number[]) => {
const u8ArrToU32Arr = (u8a: number[]): number[] => {
let res = [];
for (let i = 0; i < u8a.length/4; i++) {
const c = u8a.slice(i*4, (i+1)*4);
Expand All @@ -9,10 +37,7 @@ const u8ArrToU32Arr = (u8a: number[]) => {
return res;
};

type DTNode = any; // TODO
type DTProp = any; // TODO

const u8ArrToStr = (u8a: number[]) => u8a.reduce((a,c,i) => {
const u8ArrToStr = (u8a: number[]): string => u8a.reduce((a,c,i) => {
if (i === u8a.length -1) {
return a;
}
Expand All @@ -21,27 +46,27 @@ const u8ArrToStr = (u8a: number[]) => u8a.reduce((a,c,i) => {
}, "");

// some props are simple strings
const getStringProp = (n: DTNode, pname: string) => {
const getStringProp = (n: DTNode, pname: string): string | undefined => {
const p = n.props.find((p: DTProp) => p[0] === pname);
if (p) {
return u8ArrToStr(p[1]);
}
};

// many props are just numbers
const getProp = (n: DTNode, pname: string) => {
const getProp = (n: DTNode, pname: string): number[] | null => {
const p = n.props.find((p: DTProp) => p[0] === pname);
return p ? u8ArrToU32Arr(p[1]) : null;
};

// strings representation of lists of numbers for pretty-printing
const getPropStr = (n: DTNode, pname: string) => {
const getPropStr = (n: DTNode, pname: string): string | null => {
const p = getProp(n, pname);
return p ? p.join(", ") : null;
};

// transform a node's props into numbers and strings, omitting many
const transformNode = (n: DTNode) => {
const transformNode = (n: DTNode): DTNode => {
const name = n.name || "root";
// phandle is an identifier to the node
const phandle = getProp(n, "phandle");
Expand Down Expand Up @@ -75,9 +100,6 @@ export const transform = (n: DTNode, id: string = "10000") => {
}
};

type TransformedNode = any; // TODO
type TransformedEdge = any; // TODO

const NODE_WIDTH = 160;
const NODE_HEIGHT = 80;

Expand All @@ -94,20 +116,41 @@ const weightedNode = (node: DTNode): DTNode => {
return { ...node, size: 1 };
};

/**
* Format to hex with leading 0x, padded with zeroes to groups of four digits.
* At least print 8 digits, but omit the first 4 of 12 if they are all 0.
*/
const transformAddr = (addr: string): string => {
if (addr === undefined) {
return "";
}
const padded = addr.padStart(12, "0");
const p1 = padded.substr(0, 4);
const p2 = padded.substr(4, 4);
const p3 = padded.substr(8, 4);
if (p1 === "0000") {
return `0x${p2}_${p3}`;
}
return `0x${p1}_${p2}_${p3}`;
};

// flatten tree to list of nodes, use IDs to define ReactFlow edges
export const getNodesEdges = (tree: DTNode) => {
const nodes: TransformedNode = [];
const edges: TransformedEdge = [];
const nodes: TransformedNode[] = [];
const edges: TransformedEdge[] = [];
const rec = (n: DTNode, d: number = 1, baseX: number = 0, baseY: number = 0) => {
const [name, addr] = n.name.split("@");
const baseAddr = transformAddr(addr);

nodes.push({
id: n.id,
type: "custom",
type: NodeType.custom,
position: {
x: baseX + n.size * NODE_WIDTH / 2,
y: baseY + d * NODE_HEIGHT,
},
data: {
label: n.name,
label: `${name}\n${baseAddr}\n${n.size}`,
},
});
let offset = baseX;
Expand Down
17 changes: 17 additions & 0 deletions app/page.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/* latin-ext */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/firacode/v22/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJV77Nv7g.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/firacode/v22/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVD7Ng.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

.main {
height: 100vh;
display: flex;
Expand Down
11 changes: 7 additions & 4 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import ReactFlow, {
addEdge
} from "reactflow";
import { useFilePicker } from "use-file-picker";
import styles from "./page.module.css"
// TODO: wire up; this is a fixture
import { nodes as iNodes, edges as iEdges } from "./nodes-edges.json";
import { transform, getNodesEdges } from "./lib";
import DTNode from "./DTNode";
import styles from "./page.module.css"

const nodeTypes = {
custom: DTNode
};

export default function Home() {
const [fbuf, setFbuf] = useState<ArrayBuffer | null>(null);
Expand Down Expand Up @@ -90,7 +93,7 @@ export default function Home() {
</div>
<div style={{ width: "100vw", height: "90%" }}>
<ReactFlow
{...{ nodes, edges, onNodesChange, onEdgesChange, onConnect }}>
{...{ nodes, edges, nodeTypes, onNodesChange, onEdgesChange, onConnect }}>
<Controls />
</ReactFlow>
</div>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"scripts": {
"start": "next dev",
"build": "next build",
"typecheck": "tsc --noEmit",
"lint": "next lint"
},
"dependencies": {
Expand Down

0 comments on commit bcd1d47

Please sign in to comment.