Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Jul 6, 2024
1 parent ac566e2 commit ecc518b
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 187 deletions.
1 change: 0 additions & 1 deletion examples/Hello.fixture.tsx

This file was deleted.

8 changes: 8 additions & 0 deletions examples/cube.fixture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Cube } from "../lib"
import { JsCadFixture } from "../lib/components/jscad-fixture"

export default () => (
<JsCadFixture>
<Cube size={10} />
</JsCadFixture>
)
8 changes: 8 additions & 0 deletions examples/sphere.fixture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Sphere } from "../lib"
import { JsCadFixture } from "../lib/components/jscad-fixture"

export default () => (
<JsCadFixture wireframe>
<Sphere radius={10} />
</JsCadFixture>
)
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import React from "react"
import { createJSCADRenderer, Cube, Sphere } from "../lib"
import { createJSCADRenderer, Cube, Sphere } from "../../lib"
import * as jscad from "@jscad/modeling"
import * as THREE from "three"
// @ts-ignore
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import convertCSGToThreeGeom from "../lib/convert-csg-to-three-geom"
import convertCSGToThreeGeom from "../../lib/convert-csg-to-three-geom"

const { createJSCADRoot } = createJSCADRenderer(jscad)
const { createJSCADRoot } = createJSCADRenderer(jscad as any)

function Scene() {
return (
<>
<Cube size={10} />
<Sphere radius={5} />
</>
)
}

export default function JSCadShapeFixture() {
export function JsCadFixture({
children,
wireframe,
}: {
children: any
wireframe?: boolean
}) {
const containerRef = React.useRef<HTMLDivElement>(null)

React.useEffect(() => {
if (containerRef.current) {
const jscadGeoms: any[] = []
const root = createJSCADRoot(jscadGeoms)
root.render(<Scene />)
root.render(children)

// Here, you would typically use the container to render the 3D shape
// For this example, we'll just log the result
Expand Down Expand Up @@ -60,7 +57,7 @@ export default function JSCadShapeFixture() {
console.log(geometry)
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
wireframe: true,
wireframe,
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
Expand Down
118 changes: 118 additions & 0 deletions lib/create-host-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
export function createHostConfig(jscad: JSCADModule) {
const hostConfig: ReactReconciler.HostConfig<
string, // Type
Props, // Props
JSCADPrimitive, // Container
JSCADPrimitive, // Instance
never, // TextInstance
never, // SuspenseInstance
never, // HydratableInstance
JSCADPrimitive, // PublicInstance
{}, // HostContext
boolean, // UpdatePayload
never, // ChildSet
number, // TimeoutHandle
number // NoTimeout
> = {
now: Date.now,
supportsMutation: true,
supportsPersistence: false,
supportsHydration: false,

createInstance(
type: string,
props: Props,
rootContainerInstance: any,
hostContext: any,
internalInstanceHandle: any
) {
switch (type) {
case "cube":
return jscad.primitives.cube({ size: (props as CubeProps).size })
case "sphere":
return jscad.primitives.sphere({
radius: (props as SphereProps).radius,
})
default:
throw new Error(`Unknown element type: ${type}`)
}
},

createTextInstance() {
throw new Error("Text elements are not supported in JSCAD")
},

appendInitialChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
},

appendChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
},

removeChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.subtract(parentInstance, child) as JSCADPrimitive
},

appendChildToContainer(container: JSCADPrimitive[], child: JSCADPrimitive) {
container.push(child)
},

removeChildFromContainer(
container: JSCADPrimitive[],
child: JSCADPrimitive
) {
const index = container.indexOf(child)
if (index !== -1) container.splice(index, 1)
},

prepareUpdate() {
return true
},

commitUpdate(
instance: JSCADPrimitive,
updatePayload: any,
type: string,
oldProps: Props,
newProps: Props
) {
// Re-create the instance with new props
return this.createInstance(type, newProps, instance, {}, null)
},

finalizeInitialChildren() {
return false
},

prepareForCommit() {
return null
},
resetAfterCommit() {},
getPublicInstance(instance: JSCADPrimitive) {
return instance
},
getRootHostContext() {
return {}
},
getChildHostContext() {
return {}
},
shouldSetTextContent() {
return false
},
clearContainer() {},
scheduleTimeout: setTimeout,
cancelTimeout: clearTimeout,
noTimeout: -1,
isPrimaryRenderer: true,
getCurrentEventPriority: () => 99,
getInstanceFromNode: () => null,
beforeActiveInstanceBlur: () => {},
afterActiveInstanceBlur: () => {},
prepareScopeUpdate: () => {},
getInstanceFromScope: () => null,
detachDeletedInstance: () => {},
}
return hostConfig
}
174 changes: 3 additions & 171 deletions lib/index.tsx
Original file line number Diff line number Diff line change
@@ -1,157 +1,11 @@
import ReactReconciler from "react-reconciler"
import React from "react"

// Define a type for the JSCAD module structure we expect
interface JSCADModule {
primitives: {
cube: (options: { size: number | [number, number, number] }) => any
sphere: (options: { radius: number }) => any
}
booleans: {
union: (a: any, b: any) => any
subtract: (a: any, b: any) => any
}
}

// Define types for JSCAD objects and operations
type JSCADPrimitive =
| ReturnType<JSCADModule["primitives"]["cube"]>
| ReturnType<JSCADModule["primitives"]["sphere"]>
type JSCADOperation =
| JSCADModule["booleans"]["union"]
| JSCADModule["booleans"]["subtract"]

// Define prop types for our components
interface CubeProps {
size: number | [number, number, number]
}

interface SphereProps {
radius: number
}
import type { JSCADModule, JSCADPrimitive } from "./jscad-primitives"
import { createHostConfig } from "./create-host-config"
import { Cube, Sphere, type CubeProps, type SphereProps } from "./jscad-fns"

type Props = CubeProps | SphereProps

// Create a function that returns the host config
function createHostConfig(jscad: JSCADModule) {
const hostConfig: ReactReconciler.HostConfig<
string, // Type
Props, // Props
JSCADPrimitive, // Container
JSCADPrimitive, // Instance
never, // TextInstance
never, // SuspenseInstance
never, // HydratableInstance
JSCADPrimitive, // PublicInstance
{}, // HostContext
boolean, // UpdatePayload
never, // ChildSet
number, // TimeoutHandle
number // NoTimeout
> = {
now: Date.now,
supportsMutation: true,
supportsPersistence: false,
supportsHydration: false,

createInstance(
type: string,
props: Props,
rootContainerInstance: any,
hostContext: any,
internalInstanceHandle: any
) {
switch (type) {
case "cube":
return jscad.primitives.cube({ size: (props as CubeProps).size })
case "sphere":
return jscad.primitives.sphere({
radius: (props as SphereProps).radius,
})
default:
throw new Error(`Unknown element type: ${type}`)
}
},

createTextInstance() {
throw new Error("Text elements are not supported in JSCAD")
},

appendInitialChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
},

appendChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
},

removeChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.subtract(parentInstance, child) as JSCADPrimitive
},

appendChildToContainer(container: JSCADPrimitive[], child: JSCADPrimitive) {
container.push(child)
},

removeChildFromContainer(
container: JSCADPrimitive[],
child: JSCADPrimitive
) {
const index = container.indexOf(child)
if (index !== -1) container.splice(index, 1)
},

prepareUpdate() {
return true
},

commitUpdate(
instance: JSCADPrimitive,
updatePayload: any,
type: string,
oldProps: Props,
newProps: Props
) {
// Re-create the instance with new props
return this.createInstance(type, newProps, instance, {}, null)
},

finalizeInitialChildren() {
return false
},

prepareForCommit() {
return null
},
resetAfterCommit() {},
getPublicInstance(instance: JSCADPrimitive) {
return instance
},
getRootHostContext() {
return {}
},
getChildHostContext() {
return {}
},
shouldSetTextContent() {
return false
},
clearContainer() {},
scheduleTimeout: setTimeout,
cancelTimeout: clearTimeout,
noTimeout: -1,
isPrimaryRenderer: true,
getCurrentEventPriority: () => 99,
getInstanceFromNode: () => null,
beforeActiveInstanceBlur: () => {},
afterActiveInstanceBlur: () => {},
prepareScopeUpdate: () => {},
getInstanceFromScope: () => null,
detachDeletedInstance: () => {},
}
return hostConfig
}

// Create a function that returns the reconciler and root creation function
function createJSCADRenderer(jscad: JSCADModule) {
const hostConfig = createHostConfig(jscad)
Expand All @@ -178,15 +32,6 @@ function createJSCADRenderer(jscad: JSCADModule) {
return { createJSCADRoot }
}

// Example usage
function Cube({ size }: CubeProps) {
return <cube size={size} />
}

function Sphere({ radius }: SphereProps) {
return <sphere radius={radius} />
}

function Scene() {
return (
<>
Expand All @@ -198,16 +43,3 @@ function Scene() {

// Export the creation function and components
export { createJSCADRenderer, Cube, Sphere, Scene }

// Usage example (commented out as it depends on the actual JSCAD module)
/*
import * as jscad from '@jscad/modeling';
const { createJSCADRoot } = createJSCADRenderer(jscad);
const container: JSCADPrimitive[] = [];
const root = createJSCADRoot(container);
root.render(<Scene />);
console.log(container);
*/
9 changes: 9 additions & 0 deletions lib/jscad-fns/cube.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Define prop types for our components
export interface CubeProps {
size: number | [number, number, number]
}

// Example usage
export function Cube({ size }: CubeProps) {
return <cube size={size} />
}
2 changes: 2 additions & 0 deletions lib/jscad-fns/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./cube"
export * from "./sphere"
Loading

0 comments on commit ecc518b

Please sign in to comment.