Skip to content

Commit

Permalink
Merge pull request #32 from GsLogiMaker/fix/refactor-core-components
Browse files Browse the repository at this point in the history
Refactor core 2D components and modules
  • Loading branch information
GsLogiMaker authored Nov 29, 2024
2 parents 53888b6 + 69f2a46 commit 6490e65
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 243 deletions.
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

0 comments on commit 6490e65

Please sign in to comment.