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

Refactor core 2D components and modules #32

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions cpp/src/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "world.h"
#include "entity.h"
#include "component_builder.h"
#include "godot_cpp/classes/resource.hpp"
#include "godot_cpp/classes/script.hpp"
#include "godot_cpp/classes/text_server_manager.hpp"
#include "godot_cpp/classes/wrapped.hpp"
Expand Down Expand Up @@ -488,6 +489,18 @@ GFWorld::GFWorld() {

#undef DEFINE_GD_COMPONENT
#undef DEFINE_GD_COMPONENT_WITH_HOOKS

// Register modules from scripts
Engine* engine = Engine::get_singleton();
if (engine->has_singleton("_glecs_modules")) {
ecs_entity_t prev_scope = ecs_get_scope(raw());
ecs_set_scope(raw(), glecs);

Object* glecs_modules = engine->get_singleton("_glecs_modules");
glecs_modules->call("register_modules", this);

ecs_set_scope(raw(), prev_scope);
}
}

GFWorld::~GFWorld() {
Expand Down Expand Up @@ -583,6 +596,10 @@ Ref<GFEntity> GFWorld::lookup(String path) {
false
);

if (!ecs_is_alive(raw(), id)) {
return nullptr;
}

return GFEntity::from_id(id, this);
}

Expand Down
1 change: 0 additions & 1 deletion cpp/src/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#ifndef WORLD_H
#define WORLD_H


#include "godot_cpp/classes/script.hpp"
#include "godot_cpp/variant/dictionary.hpp"
#include <flecs.h>
Expand Down
68 changes: 14 additions & 54 deletions examples/asteroids/asteroids.gd
Original file line number Diff line number Diff line change
@@ -1,64 +1,24 @@

extends Node2D

var world:= GFWorld()

var world:= GFWorld.new()

var texture:= load("res://icon.png")

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var e:= GFEntity.spawn().set_name("Test")
e.add_component(RenderableSprite2D, [texture])

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

class RenderableSprite2D extends GFComponent:
static func _get_members() -> Dictionary: return {
texture = null,
rid = RID(),
}
GFEntity.spawn(world) \
.set_name("Test") \
.add_component(GFTexture2D, [texture]) \
.add_component(GFCanvasItem) \
.add_component(GFPosition2D)

world.start_rest_api()

func _register(world:GFWorld):
# On add
world.observer_builder("flecs/core/OnAdd") \
.with(RenderableSprite2D) \
.for_each(func(sprite:RenderableSprite2D):
await Engine.get_main_loop().process_frame
var texture:= sprite.get_texture()
if sprite.get_texture() == null:
return
var rid:= RenderingServer.canvas_item_create()
sprite.set_rid(rid)
RenderingServer.canvas_item_set_parent(rid, Engine.get_main_loop().current_scene.get_canvas_item())
RenderingServer.canvas_item_add_texture_rect(
rid,
Rect2(-texture.get_size() / 2, texture.get_size()),
texture,
)
)

# On set
world.observer_builder("flecs/core/OnSet") \
.with(RenderableSprite2D) \
.for_each(func(sprite:RenderableSprite2D):
var texture:= sprite.get_texture()
var rid:= sprite.get_rid()
RenderingServer.canvas_item_clear(rid)
RenderingServer.canvas_item_add_texture_rect(
rid,
Rect2(-texture.get_size() / 2, texture.get_size()),
sprite.get_texture(),
)
)

func get_rid() -> RID:
return getm(&"rid")
func set_rid(v:RID) -> void:
setm(&"rid", v)

func get_texture() -> Texture2D:
return getm(&"texture")
func set_texture(v:Texture2D) -> void:
setm(&"texture", v)
func _process(delta: float) -> void:
world.progress(delta)
world.lookup("Test") \
.get_component(GFPosition2D) \
.set_vec(get_global_mouse_position())
2 changes: 1 addition & 1 deletion examples/asteroids/asteroids.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dglcrfdcbfvvf"]

[ext_resource type="Script" path="res://examples/asteroids/asteroids.gd" id="1_i0ls5"]
[ext_resource type="Script" path="res://addons/glecs/examples/asteroids/asteroids.gd" id="1_i0ls5"]

[node name="Asteroids" type="Node2D"]
script = ExtResource("1_i0ls5")
Expand Down
17 changes: 17 additions & 0 deletions gd/modules.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

## Registers default Glecs modules with new worlds.

@tool
class_name _GlecsModules extends Node

const MODULES:= [
preload("./rendering/rendering.gd"),
]

static var _register_self_singleton = (func():
Engine.register_singleton("_glecs_modules", _GlecsModules)
).call()

static func register_modules(w:GFWorld) -> void:
for module in MODULES:
w.register_script(module)
9 changes: 9 additions & 0 deletions gd/rendering/2d/2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

extends GFModule

const _CANVAS_ITEM:= preload("./canvas_item.gd")
const _POSITION_2D:= preload("./position2d.gd")
const _ROTATION_2D:= preload("./rotation2d.gd")
const _SCALE_2D:= preload("./scale2d.gd")
const _TEXTURE_2D:= preload("./texture2d.gd")
const _SYSTEMS:= preload("./systems.gd")
33 changes: 33 additions & 0 deletions gd/rendering/2d/canvas_item.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

## A component that gives entities functionality of a CanvasItem.

class_name GFCanvasItem extends GFComponent

func get_rid() -> RID: return getm(&"rid")
func set_rid(v:RID) -> void: setm(&"rid", v)
func _build(b: GFComponentBuilder) -> void:
b.add_member("rid", TYPE_RID)


## Sets the parent canvas item of this canvas item by its [RID].
func set_parent_canvas_item(rid:RID) -> void:
RenderingServer.canvas_item_set_parent(
get_rid(),
rid
)


## Updates the transform of this canvas item via the three 2D spatial
## components.
func update_transform_c(
pos:GFPosition2D,
rot:GFRotation2D,
scale:GFScale2D,
) -> void:
var loc:Vector2 = pos.get_vec() if pos else Vector2()
var angle:float = rot.get_angle() if rot else 0.0
var size:Vector2 = scale.get_scale() if scale else Vector2.ONE
RenderingServer.canvas_item_set_transform(
get_rid(),
Transform2D(angle, size, 0, loc)
)
13 changes: 13 additions & 0 deletions gd/rendering/2d/position2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

## A component that represents a position in 2D space.

class_name GFPosition2D extends GFComponent

func get_vec() -> Vector2: return getm(&"vec")
func set_vec(v:Vector2) -> void: return setm(&"vec", v)
func get_x() -> float: return getm(&"vec").x
func set_x(v:float) -> void: return setm(&"vec", Vector2(v, get_y()))
func get_y() -> float: return getm(&"vec").y
func set_y(v:float) -> void: return setm(&"vec", Vector2(get_x(), v))
func _build(b: GFComponentBuilder) -> void:
b.add_member("vec", TYPE_VECTOR2)
9 changes: 9 additions & 0 deletions gd/rendering/2d/rotation2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

## A component that represents a rotaition in 2D space.

class_name GFRotation2D extends GFComponent

func get_angle() -> float: return getm(&"angle")
func set_angle(v:float) -> void: return setm(&"angle", v)
func _build(b: GFComponentBuilder) -> void:
b.add_member("angle", TYPE_FLOAT)
9 changes: 9 additions & 0 deletions gd/rendering/2d/scale2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

## A component that represents scale in 2D space.

class_name GFScale2D extends GFComponent

func get_scale() -> Vector2: return getm(&"scale")
func set_scale(v:Vector2) -> void: return setm(&"scale", v)
func _build(b: GFComponentBuilder) -> void:
b.add_member("scale", TYPE_VECTOR2)
97 changes: 97 additions & 0 deletions gd/rendering/2d/systems.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

## A component that gives entities functionality of a CanvasItem.

extends GFModule

func _register(w:GFWorld):
#region GFCanvasItem
# On add GFCanvasItem
w.observer_builder("/root/flecs/core/OnAdd") \
.with(GFCanvasItem) \
.for_each(func(item:GFCanvasItem):
item.set_rid(RenderingServer.canvas_item_create())
# Set parent to root
var root_canvas_item:CanvasItem = Engine.get_main_loop() \
.current_scene
item.set_parent_canvas_item(root_canvas_item.get_canvas_item())
)

# On set GFCanvasItem
w.observer_builder("/root/flecs/core/OnSet") \
.with(GFCanvasItem) \
.for_each(func(item:GFCanvasItem):
item.set_parent_canvas_item(
Engine.get_main_loop().current_scene.get_canvas_item()
)
)

# On remove GFCanvasItem
w.observer_builder("/root/flecs/core/OnRemove") \
.with(GFCanvasItem) \
.for_each(func(item:GFCanvasItem):
RenderingServer.free_rid(item.get_rid())
)
#endregion

#region GFPosition2D
# On GFPosition2D set, update visual transform of CanvasItemC
w.observer_builder("/root/flecs/core/OnSet") \
.with(GFCanvasItem).access_filter() \
.with(GFPosition2D) \
.maybe_with(GFRotation2D) \
.maybe_with(GFScale2D) \
.for_each(func(
item:GFCanvasItem,
pos:GFPosition2D,
rot:GFRotation2D,
scl:GFScale2D,
):
item.update_transform_c(pos, rot, scl)
)
#endregion

#region GFRotation2D
# On GFPosition2D set, update visual transform of GFCanvasItem
w.observer_builder("/root/flecs/core/OnSet") \
.with(GFCanvasItem).access_filter() \
.with(GFRotation2D) \
.maybe_with(GFPosition2D) \
.maybe_with(GFScale2D) \
.for_each(func(
item:GFCanvasItem,
rot:GFRotation2D,
pos:GFPosition2D,
scl:GFScale2D,
):
item.update_transform_c(pos, rot, scl)
)
#endregion

#region GFScale2D
# On GFScale2D set, update visual transform of GFCanvasItem
w.observer_builder("/root/flecs/core/OnSet") \
.with(GFCanvasItem).access_filter() \
.with(GFScale2D) \
.maybe_with(GFPosition2D) \
.maybe_with(GFRotation2D) \
.for_each(func(
item:GFCanvasItem,
scal:GFScale2D,
pos:GFPosition2D,
rot:GFRotation2D,
):
item.update_transform_c(pos, rot, scal)
)
#endregion

#region GFTexture2D
w.observer_builder("/root/flecs/core/OnAdd") \
.with(GFTexture2D) \
.with(GFCanvasItem) \
.for_each(GFTexture2D.update_texture_rect)

w.observer_builder("/root/flecs/core/OnSet") \
.with(GFTexture2D) \
.with(GFCanvasItem) \
.for_each(GFTexture2D.update_texture_rect)
#endregion
21 changes: 21 additions & 0 deletions gd/rendering/2d/texture2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

## A component containing a [Texture2D].

class_name GFTexture2D extends GFComponent

func get_texture() -> Texture2D: return getm(&"texture")
func set_texture(v:Texture2D) -> void: return setm(&"texture", v)
func _build(b: GFComponentBuilder) -> void:
b.add_member("texture", TYPE_OBJECT)

static func update_texture_rect(sprite:GFTexture2D, item:GFCanvasItem) -> void:
var texture:= sprite.get_texture()

if texture == null:
return

RenderingServer.canvas_item_add_texture_rect(
item.get_rid(),
Rect2(-texture.get_size() / 2, texture.get_size()),
texture,
)
3 changes: 3 additions & 0 deletions gd/rendering/rendering.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extends GFModule

const _M:= preload("./2d/2d.gd")
Loading
Loading