This commit is contained in:
@@ -14,15 +14,12 @@ const TextEdit = Component.fromClass(Godot.TextEdit)
|
||||
* A form UI where React controls the state
|
||||
*/
|
||||
export function ControlledFormRoot() {
|
||||
const rootRef = CenterContainer.useRef()
|
||||
Component.useSignal(rootRef, "ready", () => {
|
||||
console.log("ready")
|
||||
})
|
||||
|
||||
return (
|
||||
<CenterContainer
|
||||
ref={rootRef}
|
||||
anchors_preset={Godot.Control.LayoutPreset.PRESET_FULL_RECT}
|
||||
ready={function(this) {
|
||||
console.log("ready")
|
||||
}}
|
||||
>
|
||||
<PanelContainer>
|
||||
<MarginContainer>
|
||||
|
||||
@@ -10,6 +10,10 @@ export type Props<T extends Godot.Node<Godot.NodePathMap>> = {
|
||||
} & {
|
||||
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
|
||||
[K in keyof T as T[K] extends Function | Godot.Signal ? never : K]?: T[K]
|
||||
} & {
|
||||
[K in keyof T as T[K] extends Godot.Signal ? K : never]?: T[K] extends Godot.Signal<infer F>
|
||||
? (this: T, ...args: Parameters<F>) => ReturnType<F>
|
||||
: never
|
||||
}
|
||||
|
||||
export interface Prototype<T extends Godot.Node<Godot.NodePathMap>> {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Control, Node, type NodePathMap, PackedScene, ResourceLoader } from "godot"
|
||||
/** biome-ignore-all lint/complexity/noBannedTypes: "Function" is used as a type in GodotJS, keeping it for consistency */
|
||||
import { Callable, Control, Node, type NodePathMap, PackedScene, ResourceLoader, Signal } from "godot"
|
||||
import ReactReconciler, { type HostConfig } from "react-reconciler"
|
||||
import { hasProperty } from "./utils.js"
|
||||
|
||||
@@ -225,20 +226,55 @@ export const make = () => {
|
||||
|
||||
const applyNextProps = (instance: Node<NodePathMap>, nextProps: Record<string, unknown>) => {
|
||||
Object.keys(nextProps).forEach(name => {
|
||||
(instance as any)[name] = nextProps[name]
|
||||
})
|
||||
if (!hasProperty(instance, name)) return
|
||||
|
||||
if (hasProperty(nextProps, "name")) {
|
||||
if (typeof nextProps.name !== "string")
|
||||
throw new Error("Prop 'name' should be a string")
|
||||
instance.set_name(nextProps.name)
|
||||
}
|
||||
|
||||
if (instance instanceof Control) {
|
||||
if (hasProperty(nextProps, "anchors_preset")) {
|
||||
if (typeof nextProps.anchors_preset !== "number")
|
||||
throw new Error("Prop 'anchors_preset' should be a number")
|
||||
instance.set_anchors_preset(nextProps.anchors_preset)
|
||||
if (name === "name") {
|
||||
if (typeof nextProps[name] !== "string")
|
||||
throw new Error("Prop 'name' should be a string")
|
||||
instance.set_name(nextProps[name])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (instance[name] instanceof Signal) {
|
||||
if ((typeof nextProps[name] !== "function") || nextProps[name] === undefined)
|
||||
throw new Error(`Prop '${ name }' should be a function or undefined`)
|
||||
instance[`${ name }_event`] = nextProps[name]
|
||||
|
||||
if (!isNodeSignalRegistered(instance, name)) {
|
||||
const callable = Callable.create(instance, function(this, ...args) {
|
||||
if (this[`${ name }_event`])
|
||||
(this[`${ name }_event`] as Function)(...args)
|
||||
})
|
||||
instance[`${ name }_callable`] = callable
|
||||
instance.connect(name, callable)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (instance instanceof Control) {
|
||||
if (name === "anchors_preset") {
|
||||
if (typeof nextProps[name] !== "number")
|
||||
throw new Error("Prop 'anchors_preset' should be a number")
|
||||
instance.set_anchors_preset(nextProps[name])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
instance[name] = nextProps[name]
|
||||
})
|
||||
}
|
||||
|
||||
type NodeWithSignalMetadata<A extends string> = Node<NodePathMap> & {
|
||||
[K in `${ A }_callable`]: Callable
|
||||
} & {
|
||||
[K in `${ A }_event`]?: Function
|
||||
}
|
||||
|
||||
const isNodeSignalRegistered = <A extends string>(
|
||||
u: Node<NodePathMap>,
|
||||
name: A,
|
||||
): u is NodeWithSignalMetadata<A> => (
|
||||
hasProperty(u, `${ name }_callable`) &&
|
||||
u[`${ name }_callable`] instanceof Callable
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user