2022-11-23 21:28:38 +11:00
|
|
|
import React, { useRef, useState, useEffect } from "react";
|
2022-11-22 09:06:08 +11:00
|
|
|
import { Canvas } from "@react-three/fiber";
|
|
|
|
import { Allotment } from "allotment";
|
|
|
|
import { OrbitControls, OrthographicCamera } from "@react-three/drei";
|
2022-11-25 11:02:00 +11:00
|
|
|
// import "allotment/dist/style.css";
|
2022-11-23 21:28:38 +11:00
|
|
|
import { lexer } from "./lang/tokeniser";
|
|
|
|
import { abstractSyntaxTree } from "./lang/abstractSyntaxTree";
|
|
|
|
import { executor } from "./lang/executor";
|
|
|
|
import { BufferGeometry } from "three";
|
2022-11-24 06:18:13 +11:00
|
|
|
import CodeMirror from '@uiw/react-codemirror';
|
|
|
|
import { javascript } from '@codemirror/lang-javascript';
|
|
|
|
import { ViewUpdate } from '@codemirror/view'
|
2022-11-23 21:28:38 +11:00
|
|
|
// import { Box } from "./lang/engine";
|
2022-11-22 09:06:08 +11:00
|
|
|
|
2022-11-23 21:28:38 +11:00
|
|
|
const _code = `sketch mySketch {
|
|
|
|
path myPath = lineTo(0,1)
|
|
|
|
lineTo(1,5)
|
|
|
|
path rightPath = lineTo(1,0)
|
|
|
|
close()
|
2022-11-22 09:06:08 +11:00
|
|
|
}
|
2022-11-23 21:28:38 +11:00
|
|
|
show(mySketch)`;
|
2022-11-22 09:06:08 +11:00
|
|
|
|
|
|
|
const OrrthographicCamera = OrthographicCamera as any;
|
2022-11-12 13:11:54 +11:00
|
|
|
|
|
|
|
function App() {
|
2022-11-22 09:06:08 +11:00
|
|
|
const cam = useRef();
|
2022-11-23 21:28:38 +11:00
|
|
|
const [code, setCode] = useState(_code);
|
2022-11-24 06:18:13 +11:00
|
|
|
const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
|
|
|
setCode(value)
|
|
|
|
console.log('value:', value, viewUpdate);
|
|
|
|
}, []);
|
2022-11-23 21:28:38 +11:00
|
|
|
const [geoArray, setGeoArray] = useState<
|
|
|
|
{ geo: BufferGeometry; sourceRange: [number, number] }[]
|
|
|
|
>([]);
|
|
|
|
useEffect(() => {
|
|
|
|
try {
|
|
|
|
const tokens = lexer(code);
|
|
|
|
const ast = abstractSyntaxTree(tokens);
|
|
|
|
const programMemory = executor(ast);
|
|
|
|
const geos: { geo: BufferGeometry; sourceRange: [number, number] }[] =
|
|
|
|
programMemory.root.mySketch
|
|
|
|
.map(
|
|
|
|
({
|
|
|
|
geo,
|
|
|
|
sourceRange,
|
|
|
|
}: {
|
|
|
|
geo: BufferGeometry;
|
|
|
|
sourceRange: [number, number];
|
|
|
|
}) => ({ geo, sourceRange })
|
|
|
|
)
|
|
|
|
.filter((a: any) => !!a.geo);
|
|
|
|
setGeoArray(geos);
|
|
|
|
console.log("length", geos.length, geos);
|
|
|
|
console.log(programMemory);
|
|
|
|
} catch (e) {
|
|
|
|
console.log(e);
|
|
|
|
}
|
|
|
|
}, [code]);
|
2022-11-12 13:11:54 +11:00
|
|
|
return (
|
2022-11-22 09:06:08 +11:00
|
|
|
<div className="h-screen">
|
|
|
|
<Allotment>
|
|
|
|
<div className="bg-red h-full">
|
2022-11-24 06:18:13 +11:00
|
|
|
<CodeMirror
|
|
|
|
value={_code}
|
|
|
|
height="200px"
|
|
|
|
extensions={[javascript({ jsx: true })]}
|
|
|
|
onChange={onChange}
|
|
|
|
/>
|
2022-11-22 09:06:08 +11:00
|
|
|
</div>
|
|
|
|
<div className="h-full">
|
|
|
|
viewer
|
|
|
|
<Canvas>
|
|
|
|
<OrbitControls
|
|
|
|
enableDamping={false}
|
|
|
|
enablePan
|
|
|
|
enableRotate
|
|
|
|
enableZoom
|
|
|
|
reverseOrbit={false}
|
|
|
|
/>
|
|
|
|
<OrrthographicCamera
|
|
|
|
ref={cam}
|
|
|
|
makeDefault
|
|
|
|
position={[0, 0, 10]}
|
|
|
|
zoom={40}
|
|
|
|
rotation={[0, 0, 0]}
|
|
|
|
/>
|
|
|
|
<ambientLight />
|
|
|
|
<pointLight position={[10, 10, 10]} />
|
2022-11-23 21:28:38 +11:00
|
|
|
{geoArray.map(
|
|
|
|
(
|
|
|
|
{
|
|
|
|
geo,
|
|
|
|
sourceRange,
|
|
|
|
}: { geo: BufferGeometry; sourceRange: [number, number] },
|
|
|
|
index
|
|
|
|
) => <Line key={index} geo={geo} sourceRange={sourceRange} />
|
|
|
|
|
|
|
|
)}
|
2022-11-22 09:06:08 +11:00
|
|
|
</Canvas>
|
|
|
|
</div>
|
|
|
|
</Allotment>
|
2022-11-12 13:11:54 +11:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default App;
|
2022-11-23 21:28:38 +11:00
|
|
|
|
|
|
|
function Line({
|
|
|
|
geo,
|
|
|
|
sourceRange,
|
|
|
|
}: {
|
|
|
|
geo: BufferGeometry;
|
|
|
|
sourceRange: [number, number];
|
|
|
|
}) {
|
|
|
|
// This reference will give us direct access to the mesh
|
|
|
|
// const ref = useRef<Mesh<BufferGeometry | Material | Material[]> | undefined>();
|
|
|
|
const ref = useRef<BufferGeometry | undefined>() as any;
|
|
|
|
// Set up state for the hovered and active state
|
|
|
|
const [hovered, setHover] = useState(false);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<mesh
|
|
|
|
ref={ref}
|
|
|
|
onPointerOver={(event) => setHover(true)}
|
|
|
|
onPointerOut={(event) => setHover(false)}
|
|
|
|
>
|
|
|
|
<primitive object={geo} />
|
|
|
|
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
|
|
|
|
</mesh>
|
|
|
|
);
|
|
|
|
}
|