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.
- data/Changelog +17 -1
- data/Gemfile.lock +1 -1
- data/examples/board.json +52 -0
- data/examples/board.rb +133 -0
- data/examples/data.json +8 -0
- data/examples/hello_world.json +4 -5
- data/examples/hello_world.rb +2 -2
- data/examples/links.json +96 -0
- data/examples/links.rb +121 -0
- data/lib/edoors.rb +9 -9
- data/lib/edoors/board.rb +40 -1
- data/lib/edoors/door.rb +62 -5
- data/lib/edoors/iota.rb +23 -5
- data/lib/edoors/link.rb +42 -22
- data/lib/edoors/particle.rb +207 -52
- data/lib/edoors/room.rb +92 -16
- data/lib/edoors/spin.rb +93 -6
- data/lib/version.rb +1 -1
- data/spec/board_spec.rb +39 -8
- data/spec/door_spec.rb +3 -3
- data/spec/{spot_spec.rb → iota_spec.rb} +20 -0
- data/spec/link_spec.rb +10 -13
- data/spec/particle_spec.rb +61 -21
- data/spec/room_spec.rb +28 -10
- data/spec/spin_spec.rb +15 -5
- data/test/test_iotas.rb +5 -6
- metadata +17 -26
data/lib/edoors.rb
CHANGED
@@ -22,18 +22,18 @@ require 'version'
|
|
22
22
|
#
|
23
23
|
module Edoors
|
24
24
|
#
|
25
|
-
PATH_SEP
|
26
|
-
|
27
|
-
ACT_SEP = '?'.freeze
|
25
|
+
PATH_SEP = '/'.freeze
|
26
|
+
ACT_SEP = '?'.freeze
|
28
27
|
#
|
29
|
-
ACT_GET
|
30
|
-
ACT_ERROR
|
28
|
+
ACT_GET = 'get'.freeze
|
29
|
+
ACT_ERROR = 'error'.freeze
|
31
30
|
#
|
32
|
-
SYS_ACT_HIBERNATE
|
33
|
-
SYS_ACT_ADD_LINK
|
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
|
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
|
#
|
data/lib/edoors/board.rb
CHANGED
@@ -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
|
data/lib/edoors/door.rb
CHANGED
@@ -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
|
-
|
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.
|
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
|
-
|
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
|
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
|
145
|
+
_send p, true, a, d
|
89
146
|
end
|
90
147
|
#
|
91
148
|
end
|
data/lib/edoors/iota.rb
CHANGED
@@ -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
|
data/lib/edoors/link.rb
CHANGED
@@ -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
|
-
|
27
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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'
|
44
|
-
'src'
|
45
|
-
'dsts'
|
46
|
-
'
|
47
|
-
'
|
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['
|
71
|
+
self.new o['src'], o['dsts'], o['keys'], o['value']
|
55
72
|
end
|
56
73
|
#
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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, :
|
84
|
+
attr_reader :src, :dsts, :keys, :value
|
65
85
|
#
|
66
86
|
end
|
67
87
|
#
|
data/lib/edoors/particle.rb
CHANGED
@@ -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
|
-
@
|
38
|
-
@
|
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']
|
50
|
-
|
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'
|
60
|
-
'ts'
|
61
|
-
'src'
|
62
|
-
'dst'
|
63
|
-
'room'
|
64
|
-
'door'
|
65
|
-
'action'
|
66
|
-
'dsts'
|
67
|
-
'
|
68
|
-
'payload'
|
69
|
-
'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
|
-
#
|
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 =
|
120
|
+
@ts = @src = @dst = @room = @door = @action = nil
|
82
121
|
@dsts.clear
|
83
|
-
@
|
122
|
+
@link_value.clear
|
123
|
+
@link_keys.clear
|
84
124
|
@payload.clear
|
85
125
|
end
|
86
126
|
#
|
87
|
-
#
|
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, :
|
138
|
+
attr_reader :ts, :src, :dst, :room, :door, :action, :payload, :link_value
|
95
139
|
#
|
96
|
-
#
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
260
|
+
add_dsts *lnk.dsts
|
261
|
+
set_link_keys *lnk.keys
|
165
262
|
end
|
166
263
|
#
|
167
|
-
#
|
264
|
+
# adds/updates a key value pair into payload
|
168
265
|
#
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
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
|
-
|
180
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
309
|
+
# sets the links keys
|
310
|
+
#
|
311
|
+
# @param [Array] args list of keys to set
|
193
312
|
#
|
194
|
-
|
195
|
-
|
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 |
|
198
|
-
|
199
|
-
@link_fields << lf
|
200
|
-
end
|
318
|
+
args.each do |lf|
|
319
|
+
@link_keys << lf
|
201
320
|
end
|
202
|
-
|
321
|
+
@link_value = @payload.select { |k,v| @link_keys.include? k }
|
203
322
|
end
|
204
323
|
#
|
205
|
-
|
206
|
-
|
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
|
-
#
|
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
|
-
|
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
|