edoors-ruby 0.0.6 → 0.0.7

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.
@@ -22,18 +22,18 @@ require 'version'
22
22
  #
23
23
  module Edoors
24
24
  #
25
- PATH_SEP = '/'.freeze
26
- LINK_SEP = ','.freeze
27
- ACT_SEP = '?'.freeze
25
+ PATH_SEP = '/'.freeze
26
+ ACT_SEP = '?'.freeze
28
27
  #
29
- ACT_GET = 'get'.freeze
30
- ACT_ERROR = 'error'.freeze
28
+ ACT_GET = 'get'.freeze
29
+ ACT_ERROR = 'error'.freeze
31
30
  #
32
- SYS_ACT_HIBERNATE = 'hibernate'.freeze
33
- SYS_ACT_ADD_LINK = 'sys_add_link'.freeze
31
+ SYS_ACT_HIBERNATE = 'hibernate'.freeze
32
+ SYS_ACT_ADD_LINK = 'sys_add_link'.freeze
33
+ SYS_ACT_ADD_ROOM = 'sys_add_room'.freeze
34
34
  #
35
- FIELD_ERROR_MSG = 'edoors_error'.freeze
36
- FIELD_HIBERNATE_PATH= 'hibernate_path'.freeze
35
+ FIELD_ERROR_MSG = 'edoors_error'.freeze
36
+ FIELD_HIBERNATE_PATH = 'hibernate_path'.freeze
37
37
  #
38
38
  class Exception < ::Exception; end
39
39
  #
@@ -22,14 +22,24 @@
22
22
  module Edoors
23
23
  #
24
24
  ACT_FOLLOW = 'follow'.freeze
25
+ ACT_PASS_THROUGH = 'pass_through'.freeze
25
26
  #
26
27
  class Board < Door
28
+ #
29
+ # creates a Board object from the arguments.
30
+ #
31
+ # @param [String] n the name of this Board
32
+ # @param [Iota] p the parent
27
33
  #
28
34
  def initialize n, p
29
35
  super n, p
30
36
  @postponed = {}
31
37
  end
32
38
  #
39
+ # called by JSON#generate to serialize the Board object into JSON data
40
+ #
41
+ # @param [Array] a belongs to JSON generator
42
+ #
33
43
  def to_json *a
34
44
  {
35
45
  'kls' => self.class.name,
@@ -38,6 +48,12 @@ module Edoors
38
48
  }.merge(hibernate!).to_json *a
39
49
  end
40
50
  #
51
+ # creates a Board object from a JSON data
52
+ #
53
+ # @param [Hash] o belongs to JSON parser
54
+ #
55
+ # @raise Edoors::Exception if the json kls attribute is wrong
56
+ #
41
57
  def self.json_create o
42
58
  raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
43
59
  board = self.new o['name'], o['parent']
@@ -48,9 +64,13 @@ module Edoors
48
64
  board
49
65
  end
50
66
  #
67
+ # process the given particle then forward it to user code
68
+ #
69
+ # @param [Particle] p the Particle to be processed
70
+ #
51
71
  def process_p p
52
72
  @viewer.receive_p p if @viewer
53
- if p.action!=Edoors::ACT_ERROR
73
+ if p.action!=Edoors::ACT_ERROR and p.action!=Edoors::ACT_PASS_THROUGH
54
74
  p2 = @postponed[p.link_value] ||= p
55
75
  return if p2==p
56
76
  @postponed.delete p.link_value
@@ -62,6 +82,25 @@ module Edoors
62
82
  _garbage if not @saved.nil?
63
83
  end
64
84
  #
85
+ # stores back the given Particle
86
+ #
87
+ # @param [Particle] p the particle to be stored
88
+ #
89
+ # this can be used to prevent the overhead of sending the particle back to self
90
+ #
91
+ def keep! p
92
+ @postponed[p.link_value] = p
93
+ @saved = nil
94
+ end
95
+ #
96
+ # sends away all stored Particle
97
+ #
98
+ def flush!
99
+ while p=@postponed.shift
100
+ send_p p[1]
101
+ end
102
+ end
103
+ #
65
104
  end
66
105
  #
67
106
  end
@@ -22,12 +22,21 @@
22
22
  module Edoors
23
23
  #
24
24
  class Door < Iota
25
+ #
26
+ # creates a Door object from the arguments.
27
+ #
28
+ # @param [String] n the name of this Door
29
+ # @param [Iota] p the parent
25
30
  #
26
31
  def initialize n, p
27
32
  super n, p
28
33
  @saved = nil
29
34
  end
30
35
  #
36
+ # called by JSON#generate to serialize the Door object into JSON data
37
+ #
38
+ # @param [Array] a belongs to JSON generator
39
+ #
31
40
  def to_json *a
32
41
  {
33
42
  'kls' => self.class.name,
@@ -35,6 +44,12 @@ module Edoors
35
44
  }.merge(hibernate!).to_json *a
36
45
  end
37
46
  #
47
+ # creates a Door object from a JSON data
48
+ #
49
+ # @param [Hash] o belongs to JSON parser
50
+ #
51
+ # @raise Edoors::Exception if the json kls attribute is wrong
52
+ #
38
53
  def self.json_create o
39
54
  raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
40
55
  door = self.new o['name'], o['parent']
@@ -42,23 +57,37 @@ module Edoors
42
57
  door
43
58
  end
44
59
  #
45
- def require_p p_kls
60
+ # require a Particle of the given class
61
+ #
62
+ # @param [Class] p_kls the class of the desired Particle
63
+ #
64
+ def require_p p_kls=Edoors::Particle
46
65
  @spin.require_p p_kls
47
66
  end
48
67
  #
68
+ # release the given Particle
69
+ #
70
+ # @param [Particle] p the Particle to be released
71
+ #
49
72
  def release_p p
50
73
  @saved=nil if @saved==p # particle is released, all is good
51
74
  @spin.release_p p
52
75
  end
53
76
  #
77
+ # release the Particle that have not been released or sent by user code
78
+ #
54
79
  def _garbage
55
- puts " ! #{path} didn't give back #{@saved}" if @spin.debug_errors
80
+ puts " ! #{path} didn't give back #{@saved}" if @spin.debug_garbage
56
81
  puts "\t#{@saved.data Edoors::FIELD_ERROR_MSG}" if @saved.action==Edoors::ACT_ERROR
57
82
  @spin.release_p @saved
58
83
  @saved = nil
59
84
  end
60
85
  private :_garbage
61
86
  #
87
+ # process the given particle then forward it to user code
88
+ #
89
+ # @param [Particle] p the Particle to be processed
90
+ #
62
91
  def process_p p
63
92
  @viewer.receive_p p if @viewer
64
93
  @saved = p
@@ -66,12 +95,24 @@ module Edoors
66
95
  _garbage if not @saved.nil?
67
96
  end
68
97
  #
98
+ # dead end, for now user defined Door do not have to deal with system Particle
99
+ # the Particle is released
100
+ #
101
+ # @param [Particle] p the Particle to deal with
102
+ #
69
103
  def process_sys_p p
70
104
  # nothing todo with it now
71
105
  @spin.release_p p
72
106
  end
73
107
  #
74
- def _send sys, p, a=nil, d=nil
108
+ # send the given Particle through the direct @parent
109
+ #
110
+ # @param [Particle] p the Particle to be sent
111
+ # @param [Boolean] sys if true send to system Particle fifo
112
+ # @param [String] a the post action
113
+ # @param [Iota] d the post destination
114
+ #
115
+ def _send p, sys, a, d
75
116
  p.init! self
76
117
  p.set_dst! a, d||self if a
77
118
  @saved=nil if @saved==p # particle is sent back the data, all is good
@@ -80,12 +121,28 @@ module Edoors
80
121
  end
81
122
  private :_send
82
123
  #
124
+ # send the given Particle to the application Particle fifo
125
+ #
126
+ # @param [Particle] p the Particle to be sent
127
+ # @param [String] a the post action
128
+ # @param [Iota] d the post destination
129
+ #
130
+ # @see Door#_send real implementation
131
+ #
83
132
  def send_p p, a=nil, d=nil
84
- _send false, p, a, d
133
+ _send p, false, a, d
85
134
  end
86
135
  #
136
+ # send the given Particle to the system Particle fifo
137
+ #
138
+ # @param [Particle] p the Particle to be sent
139
+ # @param [String] a the post action
140
+ # @param [Iota] d the post destination
141
+ #
142
+ # @see Door#_send real implementation
143
+ #
87
144
  def send_sys_p p, a=nil, d=nil
88
- _send true, p, a, d
145
+ _send p, true, a, d
89
146
  end
90
147
  #
91
148
  end
@@ -20,8 +20,18 @@
20
20
 
21
21
  #
22
22
  module Edoors
23
+ #
24
+ IOTA_NAME = 'edoors_iota_name'.freeze
23
25
  #
24
26
  class Iota
27
+ #
28
+ # creates a Iota object from the arguments.
29
+ #
30
+ # @param [String] n the name of this Iota
31
+ # @param [Iota] p the parent
32
+ #
33
+ # @see Room#add_iota adds itself to it's parent children list
34
+ # @see Spin#add_to_world adds itself to @spin's world
25
35
  #
26
36
  def initialize n, p
27
37
  raise Edoors::Exception.new "Iota name #{n} is not valid" if n.include? Edoors::PATH_SEP
@@ -39,25 +49,33 @@ module Edoors
39
49
  attr_reader :name, :path, :spin
40
50
  attr_accessor :viewer, :parent
41
51
  #
52
+ # override this to initialize your object on system start
53
+ #
42
54
  def start!
43
- # override this to initialize your object on system start
44
55
  end
45
56
  #
57
+ # override this to initialize your object on system stop
58
+ #
46
59
  def stop!
47
- # override this to initialize your object on system stop
48
60
  end
49
61
  #
62
+ # override this to save your object state on hibernate
63
+ # #
50
64
  def hibernate!
51
- # override this to save your object state on hibernate
52
65
  {}
53
66
  end
54
67
  #
68
+ # override this to restore your object state on resume
69
+ #
55
70
  def resume! o
56
- # override this to restore your object state on resume
57
71
  end
58
72
  #
73
+ # has to be override, used by user side code
74
+ #
75
+ # @raise NoMethodError
76
+ #
59
77
  def receive_p p
60
- raise NoMethodError.new "receive_p(p) must be overridden"
78
+ raise NoMethodError.new "#{self.path} receive_p(p) must be overridden"
61
79
  end
62
80
  #
63
81
  end
@@ -23,45 +23,65 @@ module Edoors
23
23
  #
24
24
  LNK_SRC = 'edoors_lnk_src'.freeze
25
25
  LNK_DSTS = 'edoors_lnk_dsts'.freeze
26
- LNK_FIELDS = 'edoors_lnk_fields'.freeze
27
- LNK_CONDF = 'edoors_lnk_condf'.freeze
28
- LNK_CONDV = 'edoors_lnk_condv'.freeze
26
+ LNK_KEYS = 'edoors_lnk_keys'.freeze
27
+ LNK_VALUE = 'edoors_lnk_value'.freeze
29
28
  #
30
29
  class Link
31
30
  #
32
- def initialize src, dsts, fields=nil, cond_fields=nil, cond_value=nil
33
- @src = src # link source name
34
- @dsts = dsts # , separated destinations to apply to the particle on linking success
35
- @fields = fields # , separated fields to apply to the particle on linking success
36
- @cond_fields = cond_fields # , separated fields used to generate the link value with particle payload
37
- @cond_value = cond_value # value which will be compared to the particle link value to link or not
38
- @door = nil # pointer to the source
31
+ # creates a Link object from the arguments.
32
+ #
33
+ # @param [String] src link source name
34
+ # @param [Array] dsts destinations to apply to the particle on linking success
35
+ # @param [Array] keys keys to apply as link_keys to the particle on linking success
36
+ # @param [Hash] value will be used to check linking with particles
37
+ #
38
+ # @see Room#_try_links try to apply links on a Particle
39
+ # @see Particle#link_with? linking test
40
+ #
41
+ def initialize src, dsts, keys=nil, value=nil
42
+ @src = src
43
+ @dsts = dsts
44
+ @keys = keys
45
+ @value = value
46
+ @door = nil # pointer to the source set from @src by Room#add_link
39
47
  end
40
48
  #
49
+ # called by JSON#generate to serialize the Link object into JSON data
50
+ #
51
+ # @param [Array] a belongs to JSON generator
52
+ #
41
53
  def to_json *a
42
54
  {
43
- 'kls' => self.class.name,
44
- 'src' => @src,
45
- 'dsts' => @dsts,
46
- 'fields' => @fields,
47
- 'cond_fields' => @cond_fields,
48
- 'cond_value' => @cond_value
55
+ 'kls' => self.class.name,
56
+ 'src' => @src,
57
+ 'dsts' => @dsts,
58
+ 'keys' => @keys,
59
+ 'value' => @value
49
60
  }.to_json *a
50
61
  end
51
62
  #
63
+ # creates a Link object from a JSON data
64
+ #
65
+ # @param [Hash] o belongs to JSON parser
66
+ #
67
+ # @raise Edoors::Exception if the json kls attribute is wrong
68
+ #
52
69
  def self.json_create o
53
70
  raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
54
- self.new o['src'], o['dsts'], o['fields'], o['cond_fields'], o['cond_value']
71
+ self.new o['src'], o['dsts'], o['keys'], o['value']
55
72
  end
56
73
  #
57
- def self.from_particle_data p
58
- Edoors::Link.new(p.get_data(Edoors::LNK_SRC), p.get_data(Edoors::LNK_DSTS),
59
- p.get_data(Edoors::LNK_FIELDS), p.get_data(Edoors::LNK_CONDF),
60
- p.get_data(Edoors::LNK_CONDV))
74
+ # creates a Link object from the data of a particle
75
+ #
76
+ # @param [Particle] p the Particle to get Link attributes from
77
+ #
78
+ def self.from_particle p
79
+ pl = p.payload
80
+ Edoors::Link.new pl[Edoors::LNK_SRC], pl[Edoors::LNK_DSTS], pl[Edoors::LNK_KEYS], pl[Edoors::LNK_VALUE]
61
81
  end
62
82
  #
63
83
  attr_accessor :door
64
- attr_reader :src, :dsts, :fields, :cond_fields, :cond_value
84
+ attr_reader :src, :dsts, :keys, :value
65
85
  #
66
86
  end
67
87
  #
@@ -23,6 +23,33 @@ require 'time'
23
23
  module Edoors
24
24
  #
25
25
  class Particle
26
+ #
27
+ # creates a Particle object from the arguments.
28
+ #
29
+ # @param [Hash] o a customizable set of options
30
+ #
31
+ # @option o 'ts' [String]
32
+ # creation time
33
+ # @option o 'src' [String]
34
+ # Iota where it's originated from
35
+ # @option o 'dst' [String]
36
+ # Iota where it's heading to
37
+ # @option o 'room' [String]
38
+ # Room path part of the current destination
39
+ # @option o 'door' [String]
40
+ # Door path part of the current destination
41
+ # @option o 'action' [String]
42
+ # action part of the current destination
43
+ # @option o 'dsts' [String]
44
+ # fifo of path?action strings where to travel to
45
+ # @option o 'link_keys' [String]
46
+ # unordered keys used has payload keys to build link_value
47
+ # @option o 'payload' [String]
48
+ # the data carried by this particle
49
+ # @option o 'merged' [String]
50
+ # list of merged particles
51
+ #
52
+ # @see Spin#require_p require a Particle
26
53
  #
27
54
  def initialize o={}
28
55
  @ts = Time.now # creation time
@@ -31,11 +58,10 @@ module Edoors
31
58
  @room = nil # Room path part of the current destination
32
59
  @door = nil # Door path part of the current destination
33
60
  @action = nil # action part of the current destination
34
- @link_value = nil # the value computed with the link_fields values extracted from the payload
35
- # used for pearing Particles in Boards and linking in routing process
36
61
  @dsts = [] # fifo of path?action strings where to travel to
37
- @link_fields = [] # the fields used to generate the link value
38
- @payload = {} # the actual data carried by this particle
62
+ @link_keys = [] # unordered keys used has payload keys to build link_value
63
+ @link_value = {} # the payload keys and values corresponding to the link keys
64
+ @payload = {} # the data carried by this particle
39
65
  @merged = [] # list of merged particles
40
66
  #
41
67
  if not o.empty?
@@ -46,86 +72,132 @@ module Edoors
46
72
  @payload = o['payload']||{}
47
73
  @src = o['spin'].search_down o['src'] if o['src']
48
74
  @dst = o['spin'].search_down o['dst'] if o['dst']
49
- o['dsts'].each do |dst| add_dsts dst end if o['dsts']
50
- set_link_fields *o['link_fields'] if o['link_fields']
75
+ add_dsts *o['dsts'] if o['dsts']
76
+ set_link_keys *o['link_keys'] if o['link_keys']
51
77
  o['merged'].each do |particle|
52
78
  merge! Particle.json_create(particle.merge!('spin'=>o['spin']))
53
79
  end if o['merged']
54
80
  end
55
81
  end
56
82
  #
83
+ # called by JSON#generate to serialize the Particle object into JSON data
84
+ #
85
+ # @param [Array] a belongs to JSON generator
86
+ #
57
87
  def to_json *a
58
88
  {
59
- 'kls' => self.class.name,
60
- 'ts' => @ts,
61
- 'src' => (@src ? @src.path : nil ),
62
- 'dst' => (@dst ? @dst.path : nil ),
63
- 'room' => @room,
64
- 'door' => @door,
65
- 'action' => @action,
66
- 'dsts' => @dsts,
67
- 'link_fields' => @link_fields,
68
- 'payload' => @payload,
69
- 'merged' => @merged
89
+ 'kls' => self.class.name,
90
+ 'ts' => @ts,
91
+ 'src' => (@src ? @src.path : nil ),
92
+ 'dst' => (@dst ? @dst.path : nil ),
93
+ 'room' => @room,
94
+ 'door' => @door,
95
+ 'action' => @action,
96
+ 'dsts' => @dsts,
97
+ 'link_keys' => @link_keys,
98
+ 'payload' => @payload,
99
+ 'merged' => @merged
70
100
  }.to_json *a
71
101
  end
72
102
  #
103
+ # creates a Particle object from a JSON data
104
+ #
105
+ # @param [Hash] o belongs to JSON parser
106
+ #
107
+ # @raise Edoors::Exception if the json kls attribute is wrong
108
+ #
73
109
  def self.json_create o
74
110
  raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
75
111
  self.new o
76
112
  end
77
113
  #
78
- # called when released
114
+ # clears all attributes
115
+ #
116
+ # @see Spin#release_p called whe na Particle is released
117
+ #
79
118
  def reset!
80
119
  clear_merged! ( @src ? @src : ( @dst ? @dst : nil ) )
81
- @ts = @src = @dst = @room = @door = @action = @link_value = nil
120
+ @ts = @src = @dst = @room = @door = @action = nil
82
121
  @dsts.clear
83
- @link_fields.clear
122
+ @link_value.clear
123
+ @link_keys.clear
84
124
  @payload.clear
85
125
  end
86
126
  #
87
- # called when sent
127
+ # sets @src, @ts, and reset others
128
+ #
129
+ # @see Particle#apply_link! called when a Link is applied
130
+ # @see Door#_send called when a Door sends a Particle
131
+ #
88
132
  def init! src
89
133
  @src = src
90
134
  @ts = Time.now
91
135
  @dst = @room = @door = @action = nil
92
136
  end
93
137
  #
94
- attr_reader :ts, :src, :dst, :room, :door, :action, :link_value, :payload
138
+ attr_reader :ts, :src, :dst, :room, :door, :action, :payload, :link_value
95
139
  #
96
- # routing
140
+ # returns the next destination
97
141
  #
98
142
  def next_dst
99
143
  @dsts[0]
100
144
  end
101
145
  #
146
+ # clears the destination list
147
+ #
102
148
  def clear_dsts!
103
149
  @dsts.clear
104
150
  end
105
151
  #
106
- def add_dsts dsts
107
- dsts.split(Edoors::LINK_SEP).each do |dst|
108
- if dst.empty? or dst[0]==Edoors::PATH_SEP or dst[0]==Edoors::PATH_SEP or dst=~/\/\?/\
109
- or dst=~/\/{2,}/ or dst=~/\s+/ or dst==Edoors::ACT_SEP
152
+ # adds destinations to the destination list
153
+ #
154
+ # @param [Array] dsts destinations to add
155
+ #
156
+ # @raise Edoors::Exception if a destination is not acceptable
157
+ #
158
+ # The parameters are checked before beeing added.
159
+ # they must not be empty or be '?' or start with '/'
160
+ # or contain '/?' or '//' or '\s+'
161
+ #
162
+ def add_dsts *dsts
163
+ dsts.each do |dst|
164
+ if dst.empty? or dst==Edoors::ACT_SEP or dst[0]==Edoors::PATH_SEP \
165
+ or dst=~/\/\?/ or dst=~/\/{2,}/ or dst=~/\s+/
110
166
  raise Edoors::Exception.new "destination #{dst} is not acceptable"
111
167
  end
112
168
  @dsts << dst
113
169
  end
114
170
  end
115
171
  #
172
+ # adds a destination to the destination list
173
+ #
174
+ # @param [String] a the action
175
+ # @param [String] d the destination
176
+ #
116
177
  def add_dst a, d=''
117
178
  add_dsts d+Edoors::ACT_SEP+a
118
179
  end
119
180
  #
181
+ # sets the current destination
182
+ #
183
+ # @param [String] a the action
184
+ # @param [String Iota] d the destination
185
+ #
120
186
  def set_dst! a, d
121
187
  @action = a
122
188
  if d.is_a? Edoors::Iota
123
189
  @dst = d
124
190
  else
191
+ @dst = nil
125
192
  _split_path! d
126
193
  end
127
194
  end
128
195
  #
196
+ # splits the next destination into @room, @door, @action attributes
197
+ #
198
+ # the @dst attribute is set to nil
199
+ # the @room, @door, @action attributes are set to nil if not defined
200
+ #
129
201
  def split_dst!
130
202
  @dst = @room = @door = @action = nil
131
203
  return if (n = next_dst).nil?
@@ -133,6 +205,10 @@ module Edoors
133
205
  _split_path! p
134
206
  end
135
207
  #
208
+ # called by Particle#split_dst! to split the path part of the destination
209
+ #
210
+ # @param [String] p path to be splitted
211
+ #
136
212
  def _split_path! p
137
213
  i = p.rindex Edoors::PATH_SEP
138
214
  if i.nil?
@@ -146,81 +222,147 @@ module Edoors
146
222
  end
147
223
  private :_split_path!
148
224
  #
225
+ # sets the current destination and shift the head of destination list
226
+ #
227
+ # @param [Iota] dst the current destination
228
+ #
229
+ # @see Room#_route routing success
230
+ # @see Room#_send routing failure
231
+ #
149
232
  def dst_routed! dst
150
233
  @dst = dst
151
234
  @dsts.shift
152
235
  end
153
236
  #
237
+ # sets the error message, the destination and action
238
+ #
239
+ # @param [String] e error message
240
+ # @param [Iota] dst the destination, @src if nil
241
+ #
242
+ # the error message is set into @payload[[Edoors::FIELD_ERROR_MSG]
243
+ #
154
244
  def error! e, dst=nil
155
245
  @action = Edoors::ACT_ERROR
156
246
  @dst = dst||@src
157
247
  @payload[Edoors::FIELD_ERROR_MSG]=e
158
248
  end
159
249
  #
250
+ # applies the effects of the given Link
251
+ #
252
+ # @param [Link] lnk the link to apply effects
253
+ #
254
+ # updates @src with Link @src, clears the destination list
255
+ # adds the Link destinations to @dsts, sets the @link_keys
256
+ #
160
257
  def apply_link! lnk
161
258
  init! lnk.door
162
259
  clear_dsts!
163
- add_dsts lnk.dsts
164
- set_link_fields lnk.fields
260
+ add_dsts *lnk.dsts
261
+ set_link_keys *lnk.keys
165
262
  end
166
263
  #
167
- # data manipulation
264
+ # adds/updates a key value pair into payload
168
265
  #
169
- def []= k, v
170
- @payload[k]=v
171
- compute_link_value! if @link_fields.include? k
172
- end
266
+ # @param [String] k the key
267
+ # @param [Object] v the value
268
+ #
269
+ # \@link_value attribute will be updated if impacted
173
270
  #
174
- def set_data k, v
271
+ def []= k, v
272
+ @link_value[k] = v if @link_keys.include? k
175
273
  @payload[k] = v
176
- compute_link_value! if @link_fields.include? k
177
274
  end
275
+ alias :set_data :[]=
178
276
  #
179
- def [] k
180
- @payload[k]
277
+ # destroys the value paired with a key
278
+ #
279
+ # @param [String] k the key
280
+ #
281
+ # @return the associated value
282
+ #
283
+ # \@link_value attribute will be updated if impacted
284
+ #
285
+ def del_data k
286
+ @link_value.delete k if @link_keys.include? k
287
+ @payload.delete k
181
288
  end
182
289
  #
183
- def get_data k
290
+ # retrieves a data value from a key
291
+ #
292
+ # @param [String] k the key
293
+ #
294
+ def [] k
184
295
  @payload[k]
185
296
  end
186
- alias :data :get_data
297
+ #
298
+ alias :get_data :[]
299
+ alias :data :[]
300
+ #
301
+ # clones the payload of the given Particle
302
+ #
303
+ # @param [Particle] p the Particle to clone the payload of
187
304
  #
188
305
  def clone_data p
189
306
  @payload = p.payload.clone
190
307
  end
191
308
  #
192
- # link value and fields
309
+ # sets the links keys
310
+ #
311
+ # @param [Array] args list of keys to set
193
312
  #
194
- def set_link_fields *args
195
- @link_fields.clear if not @link_fields.empty?
313
+ # \@link_value attribute will be updated
314
+ #
315
+ def set_link_keys *args
316
+ @link_keys.clear if not @link_keys.empty?
196
317
  args.compact!
197
- args.each do |lfs|
198
- lfs.split(',').each do |lf|
199
- @link_fields << lf
200
- end
318
+ args.each do |lf|
319
+ @link_keys << lf
201
320
  end
202
- compute_link_value!
321
+ @link_value = @payload.select { |k,v| @link_keys.include? k }
203
322
  end
204
323
  #
205
- def compute_link_value!
206
- @link_value = @link_fields.inject('') { |s,lf| s+=@payload[lf].to_s if @payload[lf]; s }
324
+ # tries to link the Particle with the given Link
325
+ #
326
+ # @param [Link] link the link to try to link with
327
+ #
328
+ # returns true if the value of the Link is nil
329
+ # otherwise checks if the extracted key values pairs from the Particle
330
+ # payload using the Link value keys as selectors, equals the Link value
331
+ #
332
+ # @return [Boolean] true if the Link links with the Particle
333
+ #
334
+ def link_with? link
335
+ return true if link.value.nil?
336
+ link.value.keys.inject({}) { |h,k| h[k]=@payload[k] if @payload.has_key?(k); h }.eql? link.value
207
337
  end
208
338
  #
209
- # merge particles management
339
+ # merges the given Particle in
340
+ #
341
+ # @param [Particle] p the Particle to merge in
210
342
  #
211
343
  def merge! p
212
344
  @merged << p
213
345
  end
214
346
  #
347
+ # returns a merged Particle
348
+ #
349
+ # @param [Integer] i the index into the merged Particle list
350
+ #
215
351
  def merged i
216
352
  @merged[i]
217
353
  end
218
354
  #
355
+ # shifts the merged Particle list
356
+ #
219
357
  def merged_shift
220
358
  @merged.shift
221
359
  end
222
360
  #
223
- def clear_merged! r=nil
361
+ # recursively clears the merged Particle list
362
+ #
363
+ # @param [Boolean] r releases the cleared Particle if true
364
+ #
365
+ def clear_merged! r=false
224
366
  @merged.each do |p|
225
367
  p.clear_merged! r
226
368
  r.release_p p if r
@@ -228,6 +370,19 @@ module Edoors
228
370
  @merged.clear
229
371
  end
230
372
  #
373
+ # Yields each element in merged Particle list
374
+ #
375
+ def each_merged
376
+ return if not block_given?
377
+ @merged.each do |p| yield p end
378
+ end
379
+ #
380
+ # returns length of merged Pasrticle list
381
+ #
382
+ def merged_length
383
+ @merged.length
384
+ end
385
+ #
231
386
  end
232
387
  #
233
388
  end