edoors-ruby 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|