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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 935e48b4d598edb584ef80612774fec7028552597b1a6e56b4d2ec4b6283f616
4
- data.tar.gz: 9a51961b11ec757601e3912eee99918a4ec9b39b7913d7dc95aaae25218bc627
3
+ metadata.gz: a7a9e0845eb973be63f59ba48dcceaf4e7a98ba28b4c29c1b11db4e5c98cc505
4
+ data.tar.gz: f4eda02740d8e094cc7191651053e8ba34c289d01381f4cd3c9493679d574e62
5
5
  SHA512:
6
- metadata.gz: e2a1e6a8aa77715d47b2238920626da6b232e75e4fd92cc22b525c88d7de1036c54d1c704aa29dc5276fce1573876b164b48e6492102288a5168e0c1ccb3d41f
7
- data.tar.gz: 5592475d04f9fb7198f4d6222673a98ebe6dbeec7ecd80e22fcf580022f4a8b7ced2901dfda2e8da887b5ca432fd1a48164ebdc5b6f89914405e14d77da69fe0
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.1.2)
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 = BehaveFun.build_tree { success }
41
+ tree = builder.build_tree { success }
35
42
  # from hash
36
- tree = BehaveFun.build_tree_from_hash(type: :success)
43
+ tree = builder.build_tree_from_hash(type: :success)
37
44
  # from json
38
- tree = BehaveFun.build_tree_from_json(json_string)
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 = BehaveFun.build_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`. Don't forget call `running` `success` or `fail` in `#execute` method at the end.
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
- class IsCounterEven < BehaveFun::Task
75
- def execute
76
- context[:counter].even? ? success : fail
77
- end
79
+ is_counter_even = -> { context[:counter].even? ? success : fail }
78
80
 
79
- add_to_task_builder
80
- end
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 build_task(&block)
13
- task = build_tree(&block).root
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
@@ -26,7 +26,5 @@ module BehaveFun
26
26
  def child_fail
27
27
  fail
28
28
  end
29
-
30
- add_to_task_builder
31
29
  end
32
30
  end
@@ -16,7 +16,5 @@ module BehaveFun
16
16
  def serializable_status_fields
17
17
  [:current_child_idx, :order]
18
18
  end
19
-
20
- add_to_task_builder
21
19
  end
22
20
  end
@@ -16,7 +16,5 @@ module BehaveFun
16
16
  def serializable_status_fields
17
17
  [:current_child_idx, :order]
18
18
  end
19
-
20
- add_to_task_builder
21
19
  end
22
20
  end
@@ -31,7 +31,5 @@ module BehaveFun
31
31
  def serializable_status_fields
32
32
  [:current_child_idx]
33
33
  end
34
-
35
- add_to_task_builder
36
34
  end
37
35
  end
@@ -31,7 +31,5 @@ module BehaveFun
31
31
  def serializable_status_fields
32
32
  [:current_child_idx]
33
33
  end
34
-
35
- add_to_task_builder
36
34
  end
37
35
  end
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def child_success
4
4
  fail
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  end
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def child_fail
4
4
  success
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  end
@@ -7,7 +7,5 @@ module BehaveFun
7
7
  def child_success
8
8
  fail
9
9
  end
10
-
11
- add_to_task_builder
12
10
  end
13
11
  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 if @times == -1
11
+ return @children[0].reset unless params[:times]
17
12
 
18
13
  @counter += 1
19
- if @counter < @times
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
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def child_fail
4
4
  success
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  end
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def child_success
4
4
  success
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  end
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def execute
4
4
  fail
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  end
@@ -3,7 +3,5 @@ module BehaveFun
3
3
  def execute
4
4
  success
5
5
  end
6
-
7
- add_to_task_builder
8
6
  end
9
7
  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 < @duration
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
@@ -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(**params)
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
@@ -1,3 +1,3 @@
1
1
  module BehaveFun
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
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.1.2
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-17 00:00:00.000000000 Z
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/task_builder.rb
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