behave_fun 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +20 -14
- data/lib/behave_fun.rb +2 -29
- data/lib/behave_fun/branch_tasks/dynamic_guard_selector.rb +0 -2
- data/lib/behave_fun/branch_tasks/random_selector.rb +0 -2
- data/lib/behave_fun/branch_tasks/random_sequence.rb +0 -2
- data/lib/behave_fun/branch_tasks/selector.rb +0 -2
- data/lib/behave_fun/branch_tasks/sequence.rb +0 -2
- data/lib/behave_fun/decorators/always_fail.rb +0 -2
- data/lib/behave_fun/decorators/always_succeed.rb +0 -2
- data/lib/behave_fun/decorators/invert.rb +0 -2
- data/lib/behave_fun/decorators/repeat.rb +2 -9
- data/lib/behave_fun/decorators/until_fail.rb +0 -2
- data/lib/behave_fun/decorators/until_success.rb +0 -2
- data/lib/behave_fun/leaf_tasks/failure.rb +0 -2
- data/lib/behave_fun/leaf_tasks/success.rb +0 -2
- data/lib/behave_fun/leaf_tasks/wait.rb +1 -8
- data/lib/behave_fun/task.rb +7 -5
- data/lib/behave_fun/task_builder_factory.rb +130 -0
- data/lib/behave_fun/version.rb +1 -1
- metadata +3 -3
- data/lib/behave_fun/task_builder.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7a9e0845eb973be63f59ba48dcceaf4e7a98ba28b4c29c1b11db4e5c98cc505
|
4
|
+
data.tar.gz: f4eda02740d8e094cc7191651053e8ba34c289d01381f4cd3c9493679d574e62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23c14f5aee8434fc001ff9579e64454247ca46b4ae9cf84260bb47575b81a16e662611ba7a57d86ac75769d2d87f0bcee605c9f2ebd8137cf76855dcc8faf7ad
|
7
|
+
data.tar.gz: 8335771314c4fbb5e09c0cef08d77da21a114cbd5d0f1cb6707966ca530ffb2ac80c2517aff056fd4ad6c8e490347f6e672121ae7999398d804c3d7c87c6b376
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
behave_fun (0.
|
4
|
+
behave_fun (0.2.0)
|
5
5
|
activesupport (~> 6.0.0)
|
6
6
|
zeitwerk (~> 2.3.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (6.0.3)
|
11
|
+
activesupport (6.0.3.1)
|
12
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
13
|
i18n (>= 0.7, < 2)
|
14
14
|
minitest (~> 5.1)
|
data/README.md
CHANGED
@@ -13,36 +13,43 @@ Main features:
|
|
13
13
|
|
14
14
|
Add this line to your application's Gemfile:
|
15
15
|
|
16
|
-
```ruby
|
16
|
+
``` ruby
|
17
17
|
gem 'behave_fun'
|
18
18
|
```
|
19
19
|
|
20
20
|
And then execute:
|
21
21
|
|
22
|
+
```
|
22
23
|
$ bundle install
|
24
|
+
```
|
23
25
|
|
24
26
|
Or install it yourself as:
|
25
27
|
|
28
|
+
```
|
26
29
|
$ gem install behave_fun
|
30
|
+
```
|
27
31
|
|
28
32
|
## Usage
|
29
33
|
|
30
34
|
To build a behavior tree:
|
31
35
|
|
32
36
|
``` ruby
|
37
|
+
builder = BehaveFun.build_builder {
|
38
|
+
# add_task_type YourCustomTask
|
39
|
+
}
|
33
40
|
# ruby dsl
|
34
|
-
tree =
|
41
|
+
tree = builder.build_tree { success }
|
35
42
|
# from hash
|
36
|
-
tree =
|
43
|
+
tree = builder.build_tree_from_hash(type: :success)
|
37
44
|
# from json
|
38
|
-
tree =
|
45
|
+
tree = builder.build_tree_from_json(json_string)
|
39
46
|
```
|
40
47
|
|
41
48
|
To build a complex behavior tree:
|
42
49
|
|
43
50
|
``` ruby
|
44
51
|
# write_spec, write_code, run_spec, git_push and release_gem are customized tasks
|
45
|
-
tree =
|
52
|
+
tree = builder.build_tree {
|
46
53
|
sequence {
|
47
54
|
until_success {
|
48
55
|
sequence {
|
@@ -57,7 +64,7 @@ tree = BehaveFun.build_tree {
|
|
57
64
|
}
|
58
65
|
```
|
59
66
|
|
60
|
-
To create customized task, create a class that extends `BehaveFun::Task
|
67
|
+
To create customized task, create a class that extends `BehaveFun::Task` (or use a lambda if only need to overwrite `#execute` method). Don't forget call `running` `success` or `fail` in `#execute` method at the end.
|
61
68
|
|
62
69
|
``` ruby
|
63
70
|
# a task that increase data by 1, always success
|
@@ -66,18 +73,17 @@ class Counter < BehaveFun::Task
|
|
66
73
|
context[:counter] += 1
|
67
74
|
success
|
68
75
|
end
|
69
|
-
|
70
|
-
add_to_task_builder
|
71
76
|
end
|
72
77
|
|
73
78
|
# a task that detect tree data is even or not
|
74
|
-
|
75
|
-
def execute
|
76
|
-
context[:counter].even? ? success : fail
|
77
|
-
end
|
79
|
+
is_counter_even = -> { context[:counter].even? ? success : fail }
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
+
# add these tasks to your builder
|
82
|
+
builder = BehaveFun.build_builder {
|
83
|
+
add_task_type Counter
|
84
|
+
add_lambda_task_type :is_counter_even, &is_counter_even
|
85
|
+
}
|
86
|
+
builder.build_tree { counter }
|
81
87
|
```
|
82
88
|
|
83
89
|
To run a tree:
|
data/lib/behave_fun.rb
CHANGED
@@ -9,35 +9,8 @@ loader.setup
|
|
9
9
|
module BehaveFun
|
10
10
|
module_function
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
task.control = nil
|
15
|
-
task
|
16
|
-
end
|
17
|
-
|
18
|
-
def build_tree(&block)
|
19
|
-
builder = TaskBuilder.new(Tree.new)
|
20
|
-
builder.instance_eval(&block)
|
21
|
-
builder.control
|
22
|
-
end
|
23
|
-
|
24
|
-
def build_tree_from_hash(hash)
|
25
|
-
build_tree do
|
26
|
-
build_from_hash(hash[:root])
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def build_tree_from_json(json)
|
31
|
-
hash = ActiveSupport::JSON.decode(json).deep_symbolize_keys
|
32
|
-
build_tree_from_hash(hash)
|
33
|
-
end
|
34
|
-
|
35
|
-
def as_json(tree)
|
36
|
-
tree.as_json
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_json(tree)
|
40
|
-
ActiveSupport::JSON.encode(as_json(tree))
|
12
|
+
def build_builder(&block)
|
13
|
+
BehaveFun::TaskBuilderFactory.new(&block)
|
41
14
|
end
|
42
15
|
|
43
16
|
class Error < StandardError; end
|
@@ -2,21 +2,16 @@ module BehaveFun
|
|
2
2
|
class Decorators::Repeat < Decorator
|
3
3
|
attr_accessor :counter
|
4
4
|
|
5
|
-
def initialize(times: -1)
|
6
|
-
super
|
7
|
-
@times = times
|
8
|
-
end
|
9
|
-
|
10
5
|
def start
|
11
6
|
super
|
12
7
|
@counter = 0
|
13
8
|
end
|
14
9
|
|
15
10
|
def child_success
|
16
|
-
return @children[0].reset
|
11
|
+
return @children[0].reset unless params[:times]
|
17
12
|
|
18
13
|
@counter += 1
|
19
|
-
if @counter <
|
14
|
+
if @counter < params[:times]
|
20
15
|
@children[0].reset
|
21
16
|
else
|
22
17
|
success
|
@@ -30,7 +25,5 @@ module BehaveFun
|
|
30
25
|
def serializable_status_fields
|
31
26
|
[:counter]
|
32
27
|
end
|
33
|
-
|
34
|
-
add_to_task_builder
|
35
28
|
end
|
36
29
|
end
|
@@ -2,18 +2,13 @@ module BehaveFun
|
|
2
2
|
class LeafTasks::Wait < Task
|
3
3
|
attr_accessor :counter
|
4
4
|
|
5
|
-
def initialize(duration: )
|
6
|
-
super
|
7
|
-
@duration = duration
|
8
|
-
end
|
9
|
-
|
10
5
|
def start
|
11
6
|
super
|
12
7
|
@counter = 0
|
13
8
|
end
|
14
9
|
|
15
10
|
def execute
|
16
|
-
if @counter <
|
11
|
+
if @counter < params[:duration]
|
17
12
|
@counter += 1
|
18
13
|
running
|
19
14
|
else
|
@@ -24,7 +19,5 @@ module BehaveFun
|
|
24
19
|
def serializable_status_fields
|
25
20
|
[:counter]
|
26
21
|
end
|
27
|
-
|
28
|
-
add_to_task_builder
|
29
22
|
end
|
30
23
|
end
|
data/lib/behave_fun/task.rb
CHANGED
@@ -5,7 +5,7 @@ module BehaveFun
|
|
5
5
|
attr_accessor :control, :guard
|
6
6
|
attr_reader :context, :children, :params, :status
|
7
7
|
|
8
|
-
def initialize(
|
8
|
+
def initialize(params = {})
|
9
9
|
@params = params
|
10
10
|
@children = []
|
11
11
|
@status = :fresh
|
@@ -15,10 +15,6 @@ module BehaveFun
|
|
15
15
|
name.demodulize.underscore
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.add_to_task_builder(name = task_name)
|
19
|
-
BehaveFun::TaskBuilder.add_task_type(self, name: name)
|
20
|
-
end
|
21
|
-
|
22
18
|
def context=(context)
|
23
19
|
@context = context
|
24
20
|
children.each { _1.context = context }
|
@@ -119,5 +115,11 @@ module BehaveFun
|
|
119
115
|
@status = :fresh
|
120
116
|
children.each { |child| child.reset }
|
121
117
|
end
|
118
|
+
|
119
|
+
def dup
|
120
|
+
cloned = self.class.new(params)
|
121
|
+
children.each { cloned.add_child(_1.dup) }
|
122
|
+
cloned
|
123
|
+
end
|
122
124
|
end
|
123
125
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module BehaveFun
|
2
|
+
class TaskBuilderFactory
|
3
|
+
attr_reader :tasks
|
4
|
+
|
5
|
+
def initialize(&block)
|
6
|
+
@tasks = {}
|
7
|
+
|
8
|
+
add_task_type BehaveFun::LeafTasks::Success
|
9
|
+
add_task_type BehaveFun::LeafTasks::Failure
|
10
|
+
add_task_type BehaveFun::LeafTasks::Wait
|
11
|
+
add_task_type BehaveFun::Decorators::AlwaysSucceed
|
12
|
+
add_task_type BehaveFun::Decorators::AlwaysFail
|
13
|
+
add_task_type BehaveFun::Decorators::UntilSuccess
|
14
|
+
add_task_type BehaveFun::Decorators::UntilFail
|
15
|
+
add_task_type BehaveFun::Decorators::Invert
|
16
|
+
add_task_type BehaveFun::Decorators::Repeat
|
17
|
+
add_task_type BehaveFun::BranchTasks::Sequence
|
18
|
+
add_task_type BehaveFun::BranchTasks::Selector
|
19
|
+
add_task_type BehaveFun::BranchTasks::RandomSequence
|
20
|
+
add_task_type BehaveFun::BranchTasks::RandomSelector
|
21
|
+
add_task_type BehaveFun::BranchTasks::DynamicGuardSelector
|
22
|
+
|
23
|
+
instance_eval(&block) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_task_type(type, name: type.task_name)
|
27
|
+
tasks[name.to_sym] = type
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_lambda_task_type(task_name, &block)
|
31
|
+
type = Class.new(Task) do
|
32
|
+
def name
|
33
|
+
task_name
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method(:execute, &block)
|
37
|
+
end
|
38
|
+
tasks[task_name.to_sym] = type
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_task(&block)
|
42
|
+
task = build_tree(&block).root
|
43
|
+
task.control = nil
|
44
|
+
task
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_tree(&block)
|
48
|
+
builder = Builder.new(self, Tree.new)
|
49
|
+
builder.instance_eval(&block)
|
50
|
+
builder.control
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_task_from_hash(hash)
|
54
|
+
tree = build_tree do
|
55
|
+
build_from_hash(hash)
|
56
|
+
end
|
57
|
+
tree.root
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_tree_from_hash(hash)
|
61
|
+
build_tree do
|
62
|
+
build_from_hash(hash[:root])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_tree_from_json(json)
|
67
|
+
hash = ActiveSupport::JSON.decode(json).deep_symbolize_keys
|
68
|
+
build_tree_from_hash(hash)
|
69
|
+
end
|
70
|
+
|
71
|
+
def as_json(tree)
|
72
|
+
tree.as_json
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_json(tree)
|
76
|
+
ActiveSupport::JSON.encode(as_json(tree))
|
77
|
+
end
|
78
|
+
|
79
|
+
class Builder
|
80
|
+
attr_reader :factory, :control
|
81
|
+
|
82
|
+
def initialize(factory, control)
|
83
|
+
@factory = factory
|
84
|
+
@control = control
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_task(type, params = {}, &block)
|
88
|
+
task = type.new(params)
|
89
|
+
@control.add_child(task)
|
90
|
+
|
91
|
+
if block
|
92
|
+
builder = Builder.new(factory, task)
|
93
|
+
builder.instance_eval(&block)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def guard_with(&block)
|
98
|
+
builder = Builder.new(factory, Tree.new)
|
99
|
+
builder.instance_eval(&block)
|
100
|
+
control.guard = builder.control.root
|
101
|
+
end
|
102
|
+
|
103
|
+
def include(task)
|
104
|
+
cloned_task = task.dup
|
105
|
+
@control.add_child(cloned_task)
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_from_hash(task_hash)
|
109
|
+
type_name, params, guard_with, children =
|
110
|
+
task_hash.values_at(:type, :params, :guard_with, :children)
|
111
|
+
params ||= {}
|
112
|
+
children ||= []
|
113
|
+
type = factory.tasks[type_name.to_sym]
|
114
|
+
add_task type, **params do
|
115
|
+
guard_with { build_from_hash(guard_with) } if guard_with
|
116
|
+
children.each { build_from_hash(_1) }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def method_missing(name, *args, &block)
|
121
|
+
type = factory.tasks[name.to_sym]
|
122
|
+
if type
|
123
|
+
add_task(type, *args, &block)
|
124
|
+
else
|
125
|
+
super
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/behave_fun/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: behave_fun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ayaya zhao
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -74,7 +74,7 @@ files:
|
|
74
74
|
- lib/behave_fun/leaf_tasks/success.rb
|
75
75
|
- lib/behave_fun/leaf_tasks/wait.rb
|
76
76
|
- lib/behave_fun/task.rb
|
77
|
-
- lib/behave_fun/
|
77
|
+
- lib/behave_fun/task_builder_factory.rb
|
78
78
|
- lib/behave_fun/task_serializer.rb
|
79
79
|
- lib/behave_fun/tree.rb
|
80
80
|
- lib/behave_fun/version.rb
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module BehaveFun
|
2
|
-
class TaskBuilder
|
3
|
-
attr_reader :control
|
4
|
-
|
5
|
-
def initialize(control)
|
6
|
-
@control = control
|
7
|
-
end
|
8
|
-
|
9
|
-
def add_task(type, **params, &block)
|
10
|
-
task = type.new(**params)
|
11
|
-
@control.add_child(task)
|
12
|
-
|
13
|
-
if block
|
14
|
-
builder = TaskBuilder.new(task)
|
15
|
-
builder.instance_eval(&block)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def guard_with(&block)
|
20
|
-
builder = TaskBuilder.new(Tree.new)
|
21
|
-
builder.instance_eval(&block)
|
22
|
-
control.guard = builder.control.root
|
23
|
-
end
|
24
|
-
|
25
|
-
def include(task)
|
26
|
-
cloned_task = BehaveFun.build_task { build_from_hash(task.as_json) }
|
27
|
-
@control.add_child(cloned_task)
|
28
|
-
end
|
29
|
-
|
30
|
-
def build_from_hash(task_hash)
|
31
|
-
type_name, params, guard_with, children =
|
32
|
-
task_hash.values_at(:type, :params, :guard_with, :children)
|
33
|
-
params ||= {}
|
34
|
-
children ||= []
|
35
|
-
type = self.class.tasks[type_name.to_sym]
|
36
|
-
add_task type, **params do
|
37
|
-
guard_with { build_from_hash(guard_with) } if guard_with
|
38
|
-
children.each { build_from_hash(_1) }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.tasks
|
43
|
-
@tasks ||= {}
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.add_task_type(type, name: type.task_name)
|
47
|
-
tasks[name.to_sym] = type
|
48
|
-
define_method name do |params = {}, &block|
|
49
|
-
add_task(type, **params, &block)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|