-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
758 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.godot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# godot-dci | ||
Lightweight dci framework wirtten with gdscript. | ||
|
||
![](dci.png) | ||
|
||
# Features | ||
|
||
- Lightweight and non-intrusive. | ||
- Easy to use. | ||
|
||
# How To Use | ||
|
||
- Copy the 'dci' directory to any location within your Godot project. | ||
- Begin your DCI coding journey with the following code: | ||
|
||
``` | ||
# define data | ||
class Person extends dci_data: | ||
var name: String = "Player" | ||
``` | ||
|
||
``` | ||
# define role (Interactions) | ||
class swimmer extends dci_behavior: | ||
func swim() -> dci_behavior: | ||
print("%s Swim." % data().name) | ||
return self | ||
class superman extends dci_behavior: | ||
func fly() -> dci_behavior: | ||
print("%s Fly." % data().name) | ||
return self | ||
``` | ||
|
||
``` | ||
# define context | ||
class FlyContext extends dci_context: | ||
# override | ||
func _on_execute(data): | ||
assert(sender() is superman, "type not match!") | ||
sender().fly() | ||
``` | ||
|
||
``` | ||
# create dci environment | ||
var dci = dci_env.new() | ||
# register role | ||
dci.add_behavior("swimmer", swimmer) | ||
dci.add_behavior("superman", superman) | ||
# register context | ||
dci.add_context("FlyContext", FlyContext.new()) | ||
dci.add_callable("FlyLambda", func(ctx: dci_context, data): | ||
assert(ctx.sender() is superman, "type not match!") | ||
ctx.sender().fly() | ||
) | ||
# data usage | ||
var man: Person = Person.new().with(dci) | ||
# cast role | ||
man.cast("swimmer").swim() \ | ||
.cast("superman").fly() | ||
# cast and context execute | ||
man.cast("superman").execute("FlyContext") | ||
man.cast("superman").execute("FlyLambda") | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
extends Control | ||
|
||
var dci: dci_env = dci_env.new("my-dci") | ||
|
||
class swimmer extends dci_behavior: | ||
func swim() -> dci_behavior: | ||
print("%s Swim." % data().name) | ||
return self | ||
|
||
class superman extends dci_behavior: | ||
func fly() -> dci_behavior: | ||
print("%s Fly." % data().name) | ||
return self | ||
|
||
class tankman extends dci_behavior: | ||
func fire() -> dci_behavior: | ||
print("%s Fire!" % data().name) | ||
return self | ||
func attack() -> dci_behavior: | ||
print("%s Attack enemies!" % data().name) | ||
return self | ||
|
||
class shopper extends dci_behavior: | ||
func buy(name: String) -> dci_behavior: | ||
print("shopper <%s> age <%d> have gold <%d> to buy <%s>." % [data().name, data().age, get_component("gold"), name]) | ||
return self | ||
|
||
class Person extends dci_data: | ||
var age: int = 13 | ||
var name: String = "Player" | ||
|
||
class FlyContext extends dci_context: | ||
# override | ||
func _on_execute(data): | ||
assert(sender() is superman, "type not match!") | ||
sender().fly() | ||
|
||
class BuySomeContext extends dci_context: | ||
# override | ||
func _on_execute(data): | ||
assert(sender() is shopper, "type not match!") | ||
sender().buy(data) | ||
|
||
func _ready(): | ||
#dci.debug_print = true | ||
|
||
# register role | ||
dci.add_behavior("swimmer", swimmer) | ||
dci.add_behavior("superman", superman) | ||
dci.add_behavior("tank", tankman) | ||
dci.add_behavior("shopper", shopper) | ||
|
||
# register context | ||
dci.add_context("BuySomeContext", BuySomeContext.new()) | ||
dci.add_callable("attack_enemies", func(ctx: dci_context, data): | ||
ctx.sender().cast("tank").attack() | ||
printt("enemies:", data) | ||
) | ||
dci.add_callable("FlyLambda", func(ctx: dci_context, data): | ||
assert(ctx.sender() is superman, "type not match!") | ||
print("Here is lambda function.") | ||
ctx.sender().fly() | ||
) | ||
|
||
# data group | ||
var man: Person = Person.new().with(dci) | ||
man.add_to_group("player") | ||
|
||
for i in 5: | ||
var enemy: Person = Person.new().with(dci) | ||
enemy.add_to_group("enemy") | ||
|
||
# cast role | ||
man.cast("swimmer").swim() \ | ||
.cast("superman").fly() \ | ||
.cast("tank").fire() | ||
|
||
# cast to entity | ||
man.cast("entity") \ | ||
.add_component("hello", 100) \ | ||
.add_component("world", 200) \ | ||
.add_component("gold", 9999) | ||
|
||
# cast to shopper | ||
var shopper = man.cast("shopper") \ | ||
.execute("BuySomeContext", "drinks") | ||
|
||
man.cast("superman").execute("FlyLambda") | ||
|
||
# fetch enemies and execute context/callable | ||
var enemies = dci.group("enemy") | ||
man.cast("tank").execute("attack_enemies", enemies) | ||
|
||
# destory | ||
man.destroy() | ||
for d in dci.group("enemy"): | ||
d.destroy() | ||
|
||
printt("data list:", dci.data_keys()) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[gd_scene load_steps=2 format=3 uid="uid://bftqdiki5eyv4"] | ||
|
||
[ext_resource type="Script" path="res://dci-scene/scene/main.gd" id="1_uua2x"] | ||
|
||
[node name="Main" 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_uua2x") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
extends RefCounted | ||
class_name dci_behavior | ||
|
||
var _data | ||
|
||
func _init(d): | ||
_data = d | ||
_data._set_behavior(self) | ||
|
||
func data(): | ||
return _data | ||
|
||
func cast(role: String) -> dci_behavior: | ||
return _data.cast(role) | ||
|
||
func execute(name: String, data = null) -> dci_behavior: | ||
_data.env().execute(name, self, data) | ||
return self | ||
|
||
func add_component(name: String, component) -> dci_behavior: | ||
_data.env().add_component(_data, name, component) | ||
return self | ||
|
||
func remove_component(name: String) -> dci_behavior: | ||
_data.env().remove_component(_data, name) | ||
return self | ||
|
||
func remove_all_components(): | ||
_data.env().remove_all_components(_data) | ||
return self | ||
|
||
func has_component(name: String) -> bool: | ||
return _data.env().has_component(_data, name) | ||
|
||
func get_component(name: String): | ||
return _data.env().get_component(_data, name) | ||
|
||
func get_components() -> Array: | ||
return _data.env().get_components(_data) | ||
|
||
func on_enter(data): | ||
_on_enter(data) | ||
|
||
func on_exit(data): | ||
_on_exit(data) | ||
|
||
# ============================================================================== | ||
|
||
# override | ||
func _on_enter(data): | ||
pass | ||
|
||
# override | ||
func _on_exit(data): | ||
pass | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
extends Node | ||
class_name dci_context | ||
|
||
func env() -> dci_env: | ||
return _env.get_ref() | ||
|
||
func sender(): | ||
if _sender == null: | ||
return null | ||
return _sender.get_ref() | ||
|
||
func execute(data = null): | ||
_on_execute(data) | ||
|
||
func group(name: String) -> Array: | ||
return env().group(name) | ||
|
||
func get_data(id: int) -> dci_data: | ||
return env().get_data(id) | ||
|
||
# ============================================================================== | ||
# override | ||
func _on_execute(data): | ||
pass | ||
|
||
# ============================================================================== | ||
# private | ||
var _env: WeakRef | ||
var _sender: WeakRef | ||
|
||
func _set_env(f: dci_env): | ||
_env = weakref(f) | ||
|
||
func _set_sender(sender): | ||
_sender = weakref(sender) | ||
|
||
func _init(parent: Node = null): | ||
# add scene tree for rpc | ||
if parent: | ||
parent.add_child(self) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
extends RefCounted | ||
class_name dci_data | ||
|
||
signal on_init(sender) | ||
signal on_destroy(sender) | ||
|
||
signal on_component_added(sender, component) | ||
signal on_component_removed(sender, component) | ||
|
||
func id() -> int: | ||
return _id | ||
|
||
func with(env) -> dci_data: | ||
env.add_data(self) | ||
return self | ||
|
||
func destroy(): | ||
env().remove_data(self) | ||
|
||
func env() -> dci_env: | ||
return _env.get_ref() | ||
|
||
func behavior(): | ||
return _behavior | ||
|
||
func cast(role: String) -> dci_behavior: | ||
return env().cast_behavior(self, role) | ||
|
||
func execute(name: String, data = null) -> dci_data: | ||
env().execute(name, self, data) | ||
return self | ||
|
||
func add_to_group(group_name: String) -> bool: | ||
return env().add_data_to_group(self, group_name) | ||
|
||
func remove_from_group(group_name: String) -> bool: | ||
return env().remove_data_from_group(self, group_name) | ||
|
||
func get_groups() -> Array: | ||
return env().get_data_groups(self) | ||
|
||
# ============================================================================== | ||
# private | ||
var _id: int # 唯一实例id | ||
var _env: WeakRef | ||
var _behavior | ||
|
||
func _set_id(id: int): | ||
_id = id | ||
|
||
func _set_env(f: dci_env): | ||
_env = weakref(f) | ||
|
||
func _set_behavior(behavior): | ||
if _behavior: | ||
_behavior.on_exit(self) | ||
_behavior = behavior | ||
if _behavior: | ||
_behavior.on_enter(self) | ||
|
Oops, something went wrong.