-
Notifications
You must be signed in to change notification settings - Fork 0
Data types
ProtoJam provides several general purpose data types to help build your games without the extra boiler plate.
The Memoizer class is a basic in-memory cache for a single value (see memoization). When a value is requested, it checks the validity of the cached value returning it if valid and fetching if not. By default, the value is checked for nullness and instance validity but a custom validator may also be provided. Both the provider and validator may be coroutines.
This class is intended to help you cache values too expensive to lookup every frame like the player, an objective, or other object which must be found in the scene tree (though any type can be cached, not just nodes).
var _player_memo: Memoizer = Memoizer.new(_find_player)
func _process(_delta: float) -> void:
var player: Node3D = await _player_memo.get_value()
if null != player:
print(player.global_position)
# Will only get invoked once as long as the player remains valid
func _find_player() -> Node3D:
return get_tree().get_first_node_in_group(&"Player")🚧 WIP
This example demonstrates adding a custom validator to ensure the cached value is still in the scene tree.
enemy.gd
class_name Enemy
extends Node3D
@export var speed: float = 30.0
var _objective_memo: Memoizer = Memoizer.new(_find_objective, _validate_objective)
func _physics_process(delta: float) -> void:
var objective: Node3D = await _objective_memo.get_value()
if null != objective:
global_position.move_toward(objective.global_position, speed * delta)
func _find_objective() -> Node3D:
return get_tree().get_first_node_in_group(&"Objectives")
func _validate_objective(objective: Variant) -> bool:
# A custom validator is run after the default validation so we can be sure
# this will not be called on a null value
return objective.is_inside_tree()This example demonstrates using a memoizer to fetch its data using a coroutine.
spawner.gd
class_name Spawner
extends Node3D
const _ENEMY_SCENE_PATH: String = "res://enemy.tres"
var _enemy_scene_memo: Memoizer = Memoizer.new(_load_enemy_scene)
func spawn() -> void:
var enemy_scene: PackedScene = await _enemy_scene_memo.get_value()
if null != enemy_scene:
var enemy: Node3D = enemy_scene.instantiate()
add_child(enemy)
func _load_enemy_scene() -> PackedScene:
var scene_handle: AsyncResourceHandle = BackgroundResourceLoader.load_async(_ENEMY_SCENE_PATH, "PackedScene")
# scene_handle.ready is a signal which will be called when the scene is loaded
if null != scene_handle and scene_handle.ready:
return scene_handle.get_resource()
return nullContributions are always welcome! Check out the contributing guide to get started.
Made with ❤️ for humans by humans.