5
packages/example/gen/godot/src/TestUi2.nodes.gen.ts
Normal file
5
packages/example/gen/godot/src/TestUi2.nodes.gen.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
declare module "godot" {
|
||||||
|
interface SceneNodes {
|
||||||
|
"src/TestUi2.tscn": {};
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/example/gen/godot/src/TestUi2.tscn.gen.ts
Normal file
6
packages/example/gen/godot/src/TestUi2.tscn.gen.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import TestUi2 from "../../../src/TestUi2";
|
||||||
|
declare module "godot" {
|
||||||
|
interface ResourceTypes {
|
||||||
|
"res://src/TestUi2.tscn": PackedScene<TestUi2>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,4 +8,8 @@ export default class TestUi1 extends Control {
|
|||||||
_ready(): void {
|
_ready(): void {
|
||||||
Renderer.renderComponent(this, TestUi1Component)
|
Renderer.renderComponent(this, TestUi1Component)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_exit_tree(): void {
|
||||||
|
console.log("exit tree")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Godot, { Vector2 } from "godot"
|
import Godot, { Vector2 } from "godot"
|
||||||
import { useEffect, useState } from "react"
|
import { useState } from "react"
|
||||||
import { Component } from "react-godot-renderer"
|
import { Component } from "react-godot-renderer"
|
||||||
|
|
||||||
|
|
||||||
@@ -11,26 +11,16 @@ const Button = Component.make(Godot.Button)
|
|||||||
export function TestUi1Component() {
|
export function TestUi1Component() {
|
||||||
const [text, setText] = useState("Default text")
|
const [text, setText] = useState("Default text")
|
||||||
|
|
||||||
const textEditRef = TextEdit.useUnsafeRef()
|
const textEditRef = TextEdit.useRef()
|
||||||
const buttonRef = Button.useUnsafeRef()
|
Component.useSignal(textEditRef, "text_changed", function(this) {
|
||||||
|
setText(this.text)
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
const buttonRef = Button.useRef()
|
||||||
const onTextChanged = Godot.Callable.create(() => {
|
Component.useSignal(buttonRef, "pressed", () => {
|
||||||
setText(textEditRef.current.text)
|
console.log("Pressed!")
|
||||||
})
|
})
|
||||||
|
|
||||||
textEditRef.current.text_changed.connect(onTextChanged)
|
|
||||||
return () => { textEditRef.current.text_changed.disconnect(onTextChanged) }
|
|
||||||
}, [textEditRef.current])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const onPressed = Godot.Callable.create(() => {
|
|
||||||
console.log("Pressed!")
|
|
||||||
})
|
|
||||||
|
|
||||||
buttonRef.current.pressed.connect(onPressed)
|
|
||||||
return () => { buttonRef.current.pressed.disconnect(onPressed) }
|
|
||||||
}, [buttonRef.current])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HFlowContainer
|
<HFlowContainer
|
||||||
|
|||||||
9
packages/example/src/TestUi2.ts
Normal file
9
packages/example/src/TestUi2.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Control } from "godot"
|
||||||
|
|
||||||
|
|
||||||
|
export default class TestUi2 extends Control {
|
||||||
|
// Called when the node enters the scene tree for the first time.
|
||||||
|
_ready(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/example/src/TestUi2.ts.uid
Normal file
1
packages/example/src/TestUi2.ts.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bm1qao8uj6b1f
|
||||||
12
packages/example/src/TestUi2.tscn
Normal file
12
packages/example/src/TestUi2.tscn
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b17syqj60kwx1"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://bm1qao8uj6b1f" path="res://src/TestUi2.ts" id="1_1lkkw"]
|
||||||
|
|
||||||
|
[node name="TestUi2" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_1lkkw")
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type * as Godot from "godot"
|
import Godot from "godot"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ export type Props<T extends Godot.Node<Godot.NodePathMap>> = {
|
|||||||
readonly ref?: React.RefObject<T | null>
|
readonly ref?: React.RefObject<T | null>
|
||||||
} & {
|
} & {
|
||||||
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
|
// biome-ignore lint/complexity/noBannedTypes: using Function here is completely fine
|
||||||
[K in keyof T as T[K] extends Function ? never : K]?: T[K]
|
[K in keyof T as T[K] extends Function | Godot.Signal ? never : K]?: T[K]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Prototype<T extends Godot.Node<Godot.NodePathMap>> {
|
export interface Prototype<T extends Godot.Node<Godot.NodePathMap>> {
|
||||||
@@ -36,3 +36,28 @@ export const make = <T extends Godot.Node<Godot.NodePathMap>>(
|
|||||||
),
|
),
|
||||||
Prototype,
|
Prototype,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export declare namespace useSignal {
|
||||||
|
export type SignalNames<T extends Godot.Node<Godot.NodePathMap>> = {
|
||||||
|
[K in keyof T & string]: T[K] extends Godot.Signal ? K : never
|
||||||
|
}[keyof T & string]
|
||||||
|
|
||||||
|
export type Function<T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>> = (
|
||||||
|
T[N] extends Godot.Signal<infer F>
|
||||||
|
? (this: T, ...args: Parameters<F>) => ReturnType<F>
|
||||||
|
: never
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSignal = <T extends Godot.Node<Godot.NodePathMap>, N extends useSignal.SignalNames<T>>(
|
||||||
|
ref: React.RefObject<T | null>,
|
||||||
|
name: N,
|
||||||
|
f: useSignal.Function<T, N>,
|
||||||
|
// biome-ignore lint/correctness/useExhaustiveDependencies: "f" is non-reactive
|
||||||
|
): void => React.useEffect(() => {
|
||||||
|
if (!ref.current) return
|
||||||
|
const signal = ref.current[name] as Godot.Signal
|
||||||
|
const callable = Godot.Callable.create(ref.current, f)
|
||||||
|
signal.connect(callable)
|
||||||
|
return () => { signal.disconnect(callable) }
|
||||||
|
}, [ref.current])
|
||||||
|
|||||||
Reference in New Issue
Block a user