update stores to be reactive

This commit is contained in:
Nitwel 2024-04-09 17:11:24 +02:00
parent e73db3ee47
commit b716f950bc
31 changed files with 212 additions and 108 deletions

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -22,6 +22,7 @@ meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
@ -29,4 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -4,13 +4,13 @@ static func state(value: Variant, options: Dictionary={}):
if value is Dictionary:
return store(value)
return State.new(value, options)
return RdotState.new(value, options)
static func store(value: Dictionary):
return RdotStore.new(value)
static func computed(computation: Callable, options: Dictionary={}):
return Computed.new(computation, options)
return RdotComputed.new(computation, options)
## DIY overloading of
## bind(target, prop, value)
@ -20,7 +20,7 @@ static func bind(target, prop, value, arg1=null, arg2=null):
if value is RdotStore:
return _bind_store(target, prop, value, arg1, arg2)
if value is State or value is Computed:
if value is RdotState or value is RdotComputed:
return _bind_state(target, prop, value, arg1)
assert(false, "Invalid arguments to bind, value must be a R.State or a RdotStore")
@ -77,8 +77,8 @@ static func effect(callback: Callable):
graph.watcher.unwatch([c])
class State:
var node: RdotState
class RdotState:
var node: RdotStateInternal
var value = null:
get:
return do_get()
@ -86,7 +86,7 @@ class State:
do_set(value)
func _init(value: Variant, options: Dictionary={}):
var ref = RdotState.createSignal(value)
var ref = RdotStateInternal.createSignal(value)
var node = ref[1]
self.node = node
node.wrapper = self
@ -98,7 +98,7 @@ class State:
node.equals = equals
func do_get():
return RdotState.signalGetFn.call(self.node)
return RdotStateInternal.signalGetFn.call(self.node)
func do_set(value: Variant):
var graph = RdotGraph.getInstance()
@ -107,10 +107,10 @@ class State:
var ref = self.node
RdotState.signalSetFn.call(ref, value)
RdotStateInternal.signalSetFn.call(ref, value)
class Computed:
var node: RdotComputed
class RdotComputed:
var node: RdotComputedInternal
var value = null:
get:
return do_get()
@ -118,7 +118,7 @@ class Computed:
pass
func _init(computation: Callable, options: Dictionary={}):
var ref = RdotComputed.createdComputed(computation)
var ref = RdotComputedInternal.createdComputed(computation)
var node = ref[1]
node.consumerAllowSignalWrites = true
self.node = node
@ -131,7 +131,7 @@ class Computed:
node.equals = equals
func do_get():
return RdotComputed.computedGet(node)
return RdotComputedInternal.computedGet(node)
class Watcher:
var node: RdotNode
@ -145,10 +145,10 @@ class Watcher:
node.producerNode = []
self.node = node
## signals: Array[RState | RComputed]
## signals: Array[RdotState | RComputed]
func _assertSignals(signals: Array):
for s in signals:
assert(s is State or s is Computed, "Watcher expects signals to be RState or RComputed")
assert(s is RdotState or s is RdotComputed, "Watcher expects signals to be RdotState or RdotComputed")
func watch(signals:=[]):
_assertSignals(signals)

View File

@ -1,5 +1,5 @@
extends RdotNode
class_name RdotComputed
class_name RdotComputedInternal
enum State {
SET = 0,
@ -14,7 +14,7 @@ var error = null
var computation := Callable()
var equal := func(this, a, b): return a == b
static func computedGet(node: RdotComputed) -> Variant:
static func computedGet(node: RdotComputedInternal) -> Variant:
var graph := RdotGraph.getInstance()
graph.producerUpdateValueVersion(node)
@ -25,7 +25,7 @@ static func computedGet(node: RdotComputed) -> Variant:
return node.value
static func createdComputed(computation: Callable):
var node = RdotComputed.new()
var node = RdotComputedInternal.new()
node.computation = computation
var computed = func():

View File

@ -1,11 +1,11 @@
extends RdotNode
class_name RdotState
class_name RdotStateInternal
var equal: Callable = func(this, a, b): a == b
var value: Variant = null
static func createSignal(initialValue: Variant):
var node = RdotState.new()
var node = RdotStateInternal.new()
node.value = initialValue
var getter = func():
@ -20,11 +20,11 @@ static func setPostSignalSetFn(fn: Callable) -> Callable:
graph.postSignalSetFn = fn
return prev
static func signalGetFn(this: RdotState):
static func signalGetFn(this: RdotStateInternal):
RdotGraph.getInstance().producerAccessed(this)
return this.value
static func signalSetFn(node: RdotState, newValue: Variant):
static func signalSetFn(node: RdotStateInternal, newValue: Variant):
var graph := RdotGraph.getInstance()
assert(graph.producerUpdatesAllowed())
@ -33,14 +33,14 @@ static func signalSetFn(node: RdotState, newValue: Variant):
node.value = newValue
signalValueChanged(node)
static func signalUpdateFn(node: RdotState, updater: Callable):
static func signalUpdateFn(node: RdotStateInternal, updater: Callable):
var graph := RdotGraph.getInstance()
assert(graph.producerUpdatesAllowed())
signalSetFn(node, updater.call(node.value))
static func signalValueChanged(node: RdotState):
static func signalValueChanged(node: RdotStateInternal):
var graph := RdotGraph.getInstance()
node.version += 1

View File

@ -30,7 +30,7 @@ func _set(property, value):
return true
func _access_property(property):
if (_proxied_value[property] is R.State) == false:
if (_proxied_value[property] is R.RdotState) == false:
_proxied_value[property] = R.state(_proxied_value[property])
func _get_property_list():

View File

@ -30,5 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -30,5 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -30,5 +30,5 @@ animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/naming_version=0
gltf/embedded_image_handling=1

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2941c9ce2676249f899aea64a13012d3b2f52dcf239d5f0c09570f14a4433348
size 7954301

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d0vi854404eve"
path.s3tc="res://.godot/imported/scene_0.png-9a0770c34bd6836b2bfe1d70dcace53b.s3tc.ctex"
path.etc2="res://.godot/imported/scene_0.png-9a0770c34bd6836b2bfe1d70dcace53b.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={}
[deps]
source_file="res://assets/models/sky_dome/scene_0.png"
dest_files=["res://.godot/imported/scene_0.png-9a0770c34bd6836b2bfe1d70dcace53b.s3tc.ctex", "res://.godot/imported/scene_0.png-9a0770c34bd6836b2bfe1d70dcace53b.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e93ccbdefa9cb54244f602dd3361a296a51c1cf1b4ca69344408b3f81853c6d7
size 7587197

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ds78ylaicfb3u"
path.s3tc="res://.godot/imported/scene_4.png-a9e7d42c59bc553f60827e5915c54b69.s3tc.ctex"
path.etc2="res://.godot/imported/scene_4.png-a9e7d42c59bc553f60827e5915c54b69.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={}
[deps]
source_file="res://assets/models/sky_dome/scene_4.png"
dest_files=["res://.godot/imported/scene_4.png-a9e7d42c59bc553f60827e5915c54b69.s3tc.ctex", "res://.godot/imported/scene_4.png-a9e7d42c59bc553f60827e5915c54b69.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -60,7 +60,7 @@ const SensorEntity = preload ("res://content/entities/sensor/sensor.gd")
var active: bool = false
func update_data(delta: float) -> void:
func update_data(_delta: float) -> void:
var data_list = []
for room in House.body.get_rooms(0):
@ -80,7 +80,5 @@ func update_data(delta: float) -> void:
return data
)
print(data_list)
wall_material.set_shader_parameter("data", data_list)
wall_material.set_shader_parameter("data_size", data_list.size())

View File

@ -3,29 +3,29 @@ class_name Tabs3D
signal on_select(selected: int)
var selected: Node3D:
set(value):
if selected == value:
return
var selected = R.state(null)
if selected != null:
selected.active = false
selected = value
selected.active = true
on_select.emit(selected.get_index())
@export var initial_selected: Node3D
func _ready():
if initial_selected != null:
selected = initial_selected
if initial_selected:
selected.value = initial_selected
R.effect(func(_arg):
on_select.emit(selected.value)
)
for option in get_children():
if option is Button3D == false:
continue
option.on_button_down.connect(func():
selected=option
selected.value=option
)
R.effect(func(_arg):
option.active=option == selected.value
option.disabled=option == selected.value
)
option.toggleable = true

View File

@ -8,15 +8,14 @@ var children: Array = []
func _ready():
children = get_children()
for child in children:
for i in range(children.size()):
var child = children[i]
child.visible = true
if tabs.selected != null && tabs.selected.get_index() == child.get_index():
continue
remove_child(child)
tabs.on_select.connect(func(index):
for child in get_children():
remove_child(child)
add_child(children[index])
)
R.effect(func(_arg):
if tabs.selected.value.get_index() == i:
add_child(child)
else:
remove_child(child)
)

View File

@ -1,5 +1,8 @@
extends StoreClass
const StoreClass = preload("./store.gd")
const StoreClass = preload ("./store.gd")
func _init():
self.state = R.state({})
func clear():
pass

View File

@ -3,29 +3,31 @@ extends StoreClass
const StoreClass = preload ("./store.gd")
## Type Room
## name: String
## corners: Vec2[]
## height: float
var rooms = []
## Type Entity
## id: String
## position: Vec3
## rotation: Vec3
## room: String
var entities = []
var align_position1: Vector3
var align_position2: Vector3
func _init():
_save_path = "user://house.json"
self.state = R.store({
## Type Room
## name: String
## corners: Vec2[]
## height: float
"rooms": [],
## Type Entity
## id: String
## position: Vec3
## rotation: Vec3
## room: String
"entities": [],
"align_position1": Vector3(),
"align_position2": Vector3()
})
func clear():
rooms = []
entities = []
self.state.rooms = []
self.state.entities = []
func get_room(name):
for room in rooms:
for room in self.state.rooms:
if room.name == name:
return room
return null

View File

@ -3,23 +3,23 @@ extends StoreClass
const StoreClass = preload ("./store.gd")
## The adapter to use for connecting with a backend
var type: String = "HASS_WS"
var url: String = ""
var token: String = ""
## If the voice assistant should be enabled
var voice_assistant: bool = false
## If the onboarding process has been completed
var onboarding_complete: bool = false
func _init():
_save_path = "user://settings.json"
self.state = R.store({
## The adapter to use for connecting with a backend
"type": "HASS_WS",
"url": "",
"token": "",
## If the voice assistant should be enabled
"voice_assistant": false,
## If the onboarding process has been completed
"onboarding_complete": false
})
func clear():
type = "HASS_WS"
url = ""
token = ""
voice_assistant = false
onboarding_complete = false
self.state.type = "HASS_WS"
self.state.url = ""
self.state.token = ""
self.state.voice_assistant = false
self.state.onboarding_complete = false

View File

@ -9,6 +9,7 @@ signal on_loaded
## Signal emitted when the data is saved.
signal on_saved
var state: RdotStore
var _loaded = false
var _save_path = null
@ -20,44 +21,42 @@ func is_loaded():
func clear():
pass
func create_dict():
var data: Dictionary = {}
func sanitizeState(dict=state):
var data = {}
for prop_info in get_property_list():
if prop_info.name.begins_with("_")||prop_info.hint_string != "":
var key = prop_info.name
if key.begins_with("_")||(prop_info.has("hint_string")&&prop_info.hint_string != ""):
continue
var prop = get(prop_info.name)
if prop is Store:
data[prop_info.name] = prop.create_dict()
if dict[key] is Dictionary:
data[key] = sanitizeState(dict[key])
else:
data[prop_info.name] = VariantSerializer.stringify_value(prop)
data[key] = VariantSerializer.stringify_value(dict[key])
return data
func use_dict(dict: Dictionary):
func use_dict(dict: Dictionary, target=state):
for prop_info in get_property_list():
if prop_info.name.begins_with("_")||prop_info.hint_string != "":
var key = prop_info.name
if key.begins_with("_")||(prop_info.has("hint_string")&&prop_info.hint_string != ""):
continue
var prop = get(prop_info.name)
if dict.has(prop_info.name) == false:
if dict.has(key) == false:
continue
var prop_value = dict[prop_info.name]
if prop is Store:
prop.use_dict(prop_value)
if target[key] is Dictionary:
use_dict(dict[key], target[key])
else:
set(prop_info.name, prop_value)
target[key] = dict[key]
func save_local(path=_save_path):
if path == null:
return false
var data = create_dict()
var data = sanitizeState()
var save_file = FileAccess.open(path, FileAccess.WRITE)

View File

@ -79,7 +79,6 @@ static func generate_wall_mesh_grid(corners, height, grid: Vector2=Vector2(0.1,
if y == steps.y - 1:
close_distance.y = fmod(height, grid.y) / grid.y
print(close_distance.y)
for x in range(0, steps.x):
var point = corner + forward_dir * x + Vector3.UP * grid.y * y