Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next solid-three #12

Draft
wants to merge 169 commits into
base: main
Choose a base branch
from
Draft

next solid-three #12

wants to merge 169 commits into from

Conversation

bigmistqke
Copy link

@bigmistqke bigmistqke commented Jul 16, 2023

This branch continues the context-and-proxies-branch from @vorth in which he took the proxy-implementation from @nksaraf solid-three-chess branch of react-three-fiber.

This branch' intention is to remove all the dependencies and artefacts from react, remove the dependency on zustand as an internal state manager in favour of solid/store and streamline the code, while keeping as close as possible to r3f's v9 codebase.

what has been done

  • fixed the broken event-system
  • remove all references to useRef .current
  • remove dependency on zustand
    • useThree works different then r3f's, while they have selectors to subscribe to store-updates, with our useThree is just a wrapper around useContext(ThreeContext), as we don't have to worry about unnecessary re-renders.
    • a lot of code in core now uses solid-store specific code to update the store, so the distinction between core and solid directory is further made unclear.
    • it simplified some of the internal code, since we don't have to const state = store.getState() and the like.
    • store.subscribe() has been replaced by createEffect(on(() => store, () => {…})) which I am not 100% sure is the same. store. subscribe might be deep-tracking bc off the whole immutable-thing.
  • I added an optimization to applyProps to prevent unnecessary creations/cleanups of effects with mapArray(() => Object.keys(props), ...) and checking if prop is possibly reactive (=== a getter or function)
  • refactors/cleanups:
    • the code in solid/index.ts is moved to solid/renderer.ts. core/renderer.ts is removed. It contained some types it itself had inherit from the removed reconciler.ts, they have been moved to three-types.ts.
    • index.ts, solid/index.ts (directories are merged, see below) and core/index.ts now only export files
    • removed secondary implementation of applyProps
    • removed unused three-types (remains of r3f's main branch)
    • replaced our custom three-types with r3f's v9 branch' implementation (it used to be done manually, but in the meanwhile they also figured out how to infer it from three.js)
    • our .prettierrc had the line "plugins": ["prettier-plugin-tailwindcss"] which caused my prettier to not function. I replaced our .prettierrc with the one of r3f to prevent unnecessary differences between codebases.
    • went ahead and merged the core and solid-repo back into core, more closely mimicking r3f's project-structure
    • renamed core/components to core/proxy (bc I thought it was a better parallel with reconciler and i preferred how it looked lol)
    • refactored the codebase to mimick r3f's codebase as close as possible

reflections

Currently our codebase is somewhere between r3f's main branch and v9. For example, Instance is typed like the main branch, but we have Stages like v9. Probably these changes happened after nikhil made his implementation (found pr when they made the change). Idk if we should pull everything closer to v9 or not. I think yes, but my previous attempts have all failed.

Instance has been ported to current v9 implementation. Our codebase is now up-to-date.

As I said above; since we now have solid-store-related code throughout the codebase idk if it still makes sense to make the distinction between the two. I think mb it's best to just bring it back into 1 repo and try to mimic the structure as closely to r3f as possible, so we can at least manually compare the two when needed.

I went ahead and merged those directories

I think it would probably be good to try out some more complex examples, to test out this version. Maybe port the examples of r3f.

vorth and others added 30 commits June 14, 2023 08:24
This commit discards Nikhil Saraf's older architecture based on the SolidJS
universal renderer, in favor of his newer approach that looks more like Threlte:

https://github.com/nksaraf/react-three-fiber/blob/chess-solid-three/solid-example/src/components/ModernPiece.tsx

This approach uses context to maintain the scene graph, thus avoiding the need
for the universal renderer, which adds build-time complexity and a layer (or two)
of abstraction.  It also uses a "T" proxy object to instantiate the three.js objects
and add them to the scene appropriately.

Issues:

The example seems to leave the canvas at some default size, rather than filling the
viewport.

This approach still has a dependency on "scheduler", an NPM package apparently
created as a reusable React internal package.  We might consider replacing that.
unclear why this is being done in the first place.
in core/events.ts the raycasting was checking for state.events.enabled, but this was being overwritten with events().
…leRefObject<DomEvent | null>

remove artefact from original useRef
circular dependency was causing type-errors
An endless effect was created by calling `props.onCreated` inside a useIsomorphicLayoutEffect.
In the original r3f-code it is an IsomorphicLayoutEffect with empty dependency-array, but using onMount did not render any image.
I believe we can actually just remove the effect all together, since it originally in r3f never wanted to be re-run anyway.
rotate matrix
add envMap to gems
was creating issues with drei's `<OrbitControls/>`
a bit of a silly property, since with solid-store we can just access the store directly, but handy when porting.
Use solid's utility functions `mergeProps` and `splitProps` to compose arguments, instead of de-structuring and spreading.
This way reactivity is preserved.
still remnant of experiment with suspending creation in case of Suspense
bc npm lifecycles are the worst.
and add complex git-command copy+pasted from
https://stackoverflow.com/a/62192503/4366929
otherwise submodule's head would be detached
after `git submodule update --remote --rebase`
devPreinstall still created a bug where `apps/playground` would error
bc it wasn't able to read the package.json of drei (although
the submodule was already cloned)
@connorgmeehan
Copy link

connorgmeehan commented Oct 6, 2023

@connorgmeehan cool! I would be pretty interested if there is a way to generalize this renderer, so you could plug it in other libraries. If you wanna come and hang out with us at discord

Sorry for the late response. It's funny you say that. That's one of the first things that I did when adapting this code.

Here's an early version of the generalised proxy renderer. I haven't really bothered open sourcing it the up to date code because I'm working in a private monorepo with my app.
https://github.com/sanspointes/constructables/
Basically it just lets you create a new root with a context and lets you wrap any classes into a component with automatic prop typing (which is honestly pretty buggy and slow for the typescript compiler). It also prefers defining implied props explicitly (such as position-x: number) rather than at runtime so you get proper typing.
Also here's the pixi renderer implementation that uses the generalised renderer.

I am running into performance issues, especially surrounding the way props are tracked when components are created. I would love to combine efforts. :)

Also can you re-share the discord link? I can't open it.

bigmistqke added a commit that referenced this pull request Apr 11, 2024
Implementation of proxy-based threejs renderer, based on the exploration done in the zustand-to-store branch: see #12

This branch deviates from the previous goal of staying close to r3f's codebase in favor of simplification and 'solidification'.

How the props are managed (= applying jsx-props to three-instand and managing of the scene graph) and the Primitive-component are copied from the zustand-to-store branch.

differences:
- Custom event handling
- Augment the threejs instance with far less in comparison then r3f: we only store the props of the component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants