Class: Edoors::Particle

Inherits:
Object
  • Object
show all
Defined in:
lib/edoors/particle.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(o = {}) ⇒ Particle

creates a Particle object from the arguments.

Parameters:

  • o (Hash) (defaults to: {})

    a customizable set of options

Options Hash (o):

  • creation ('ts'String)

    time

  • Iota ('src'String)

    where it's originated from

  • Iota ('dst'String)

    where it's heading to

  • Room ('room'String)

    path part of the current destination

  • Door ('door'String)

    path part of the current destination

  • action ('action'String)

    part of the current destination

  • fifo ('dsts'String)

    of path?action strings where to travel to

  • unordered ('link_keys'String)

    keys used has payload keys to build link_value

  • the ('payload'String)

    data carried by this particle

  • list ('merged'String)

    of merged particles

See Also:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/edoors/particle.rb', line 54

def initialize o={}
    @ts = Time.now      # creation time
    @src = nil          # Iota where it's originated from
    @dst = nil          # Iota where it's heading to
    @room = nil         # Room path part of the current destination
    @door = nil         # Door path part of the current destination
    @action = nil       # action part of the current destination
    @dsts = []          # fifo of path?action strings where to travel to
    @link_keys = []     # unordered keys used has payload keys to build link_value
    @link_value = {}    # the payload keys and values corresponding to the link keys
    @payload = {}       # the data carried by this particle
    @merged = []        # list of merged particles
    #
    if not o.empty?
        @ts = Time.parse(o['ts']) if o['ts']
        @room = o['room']
        @door = o['door']
        @action = o['action']
        @payload = o['payload']||{}
        @src = o['spin'].search_down o['src'] if o['src']
        @dst = o['spin'].search_down o['dst'] if o['dst']
        add_dsts *o['dsts'] if o['dsts']
        set_link_keys *o['link_keys'] if o['link_keys']
        o['merged'].each do |particle|
            merge! Particle.json_create(particle.merge!('spin'=>o['spin']))
        end if o['merged']
    end
end

Instance Attribute Details

#actionObject (readonly)

Returns the value of attribute action.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def action
  @action
end

#doorObject (readonly)

Returns the value of attribute door.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def door
  @door
end

#dstObject (readonly)

Returns the value of attribute dst.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def dst
  @dst
end

Returns the value of attribute link_value.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def link_value
  @link_value
end

#payloadObject (readonly)

Returns the value of attribute payload.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def payload
  @payload
end

#roomObject (readonly)

Returns the value of attribute room.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def room
  @room
end

#srcObject (readonly)

Returns the value of attribute src.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def src
  @src
end

#tsObject (readonly)

Returns the value of attribute ts.



138
139
140
# File 'lib/edoors/particle.rb', line 138

def ts
  @ts
end

Class Method Details

.json_create(o) ⇒ Object

creates a Particle object from a JSON data

Parameters:

  • o (Hash)

    belongs to JSON parser

Raises:

  • Edoors::Exception if the json kls attribute is wrong



109
110
111
112
# File 'lib/edoors/particle.rb', line 109

def self.json_create o
    raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
    self.new o
end

Instance Method Details

#[](k) ⇒ Object Also known as: get_data, data

retrieves a data value from a key

Parameters:

  • k (String)

    the key



294
295
296
# File 'lib/edoors/particle.rb', line 294

def [] k
    @payload[k]
end

#[]=(k, v) ⇒ Object Also known as: set_data

adds/updates a key value pair into payload

@link_value attribute will be updated if impacted

Parameters:

  • k (String)

    the key

  • v (Object)

    the value



271
272
273
274
# File 'lib/edoors/particle.rb', line 271

def []=  k, v
    @link_value[k] = v if @link_keys.include? k
    @payload[k] = v
end

#add_dst(a, d = '') ⇒ Object

adds a destination to the destination list

Parameters:

  • a (String)

    the action

  • d (String) (defaults to: '')

    the destination



177
178
179
# File 'lib/edoors/particle.rb', line 177

def add_dst a, d=''
    add_dsts d+Edoors::ACT_SEP+a
end

#add_dsts(*dsts) ⇒ Object

adds destinations to the destination list

The parameters are checked before beeing added. they must not be empty or be '?' or start with '/' or contain '/?' or '//' or '\s+'

Parameters:

  • dsts (Array)

    destinations to add

Raises:

  • Edoors::Exception if a destination is not acceptable



162
163
164
165
166
167
168
169
170
# File 'lib/edoors/particle.rb', line 162

def add_dsts *dsts
    dsts.each do |dst|
        if dst.empty? or dst==Edoors::ACT_SEP or dst[0]==Edoors::PATH_SEP \
            or dst=~/\/\?/ or dst=~/\/{2,}/ or dst=~/\s+/
            raise Edoors::Exception.new "destination #{dst} is not acceptable"
        end
        @dsts << dst
    end
end

#apply_link!(lnk) ⇒ Object

applies the effects of the given Link

updates @src with Link @src, clears the destination list adds the Link destinations to @dsts, sets the @link_keys

Parameters:

  • lnk (Link)

    the link to apply effects



257
258
259
260
261
262
# File 'lib/edoors/particle.rb', line 257

def apply_link! lnk
    init! lnk.door
    clear_dsts!
    add_dsts *lnk.dsts
    set_link_keys *lnk.keys
end

#clear_dsts!Object

clears the destination list



148
149
150
# File 'lib/edoors/particle.rb', line 148

def clear_dsts!
    @dsts.clear
end

#clear_merged!(r = false) ⇒ Object

recursively clears the merged Particle list

Parameters:

  • r (Boolean) (defaults to: false)

    releases the cleared Particle if true



365
366
367
368
369
370
371
# File 'lib/edoors/particle.rb', line 365

def clear_merged! r=false
    @merged.each do |p|
        p.clear_merged! r
        r.release_p p if r
    end
    @merged.clear
end

#clone_data(p) ⇒ Object

clones the payload of the given Particle

Parameters:

  • p (Particle)

    the Particle to clone the payload of



305
306
307
# File 'lib/edoors/particle.rb', line 305

def clone_data p
    @payload = p.payload.clone
end

#del_data(k) ⇒ Object

destroys the value paired with a key

@link_value attribute will be updated if impacted

Parameters:

  • k (String)

    the key

Returns:

  • the associated value



285
286
287
288
# File 'lib/edoors/particle.rb', line 285

def del_data k
    @link_value.delete k if @link_keys.include? k
    @payload.delete k
end

#dst_routed!(dst) ⇒ Object

sets the current destination and shift the head of destination list

Parameters:

  • dst (Iota)

    the current destination

See Also:

  • routing success
  • routing failure


232
233
234
235
# File 'lib/edoors/particle.rb', line 232

def dst_routed! dst
    @dst = dst
    @dsts.shift
end

#each_mergedObject

Yields each element in merged Particle list



375
376
377
378
# File 'lib/edoors/particle.rb', line 375

def each_merged
    return if not block_given?
    @merged.each do |p| yield p end
end

#error!(e, dst = nil) ⇒ Object

sets the error message, the destination and action

the error message is set into @payload[[Edoors::FIELD_ERROR_MSG]

Parameters:

  • e (String)

    error message

  • dst (Iota) (defaults to: nil)

    the destination, @src if nil



244
245
246
247
248
# File 'lib/edoors/particle.rb', line 244

def error! e, dst=nil
    @action = Edoors::ACT_ERROR
    @dst = dst||@src
    @payload[Edoors::FIELD_ERROR_MSG]=e
end

#init!(src) ⇒ Object

sets @src, @ts, and reset others

See Also:



132
133
134
135
136
# File 'lib/edoors/particle.rb', line 132

def init! src
    @src = src
    @ts = Time.now
    @dst = @room = @door = @action = nil
end

tries to link the Particle with the given Link

returns true if the value of the Link is nil otherwise checks if the extracted key values pairs from the Particle payload using the Link value keys as selectors, equals the Link value

Parameters:

  • link (Link)

    the link to try to link with

Returns:

  • (Boolean)

    true if the Link links with the Particle



334
335
336
337
# File 'lib/edoors/particle.rb', line 334

def link_with? link
    return true if link.value.nil?
    link.value.keys.inject({}) { |h,k| h[k]=@payload[k] if @payload.has_key?(k); h }.eql? link.value
end

#merge!(p) ⇒ Object

merges the given Particle in

Parameters:

  • p (Particle)

    the Particle to merge in



343
344
345
# File 'lib/edoors/particle.rb', line 343

def merge! p
    @merged << p
end

#merged(i) ⇒ Object

returns a merged Particle

Parameters:

  • i (Integer)

    the index into the merged Particle list



351
352
353
# File 'lib/edoors/particle.rb', line 351

def merged i
    @merged[i]
end

#merged_lengthObject

returns length of merged Pasrticle list



382
383
384
# File 'lib/edoors/particle.rb', line 382

def merged_length
    @merged.length
end

#merged_shiftObject

shifts the merged Particle list



357
358
359
# File 'lib/edoors/particle.rb', line 357

def merged_shift
    @merged.shift
end

#next_dstObject

returns the next destination



142
143
144
# File 'lib/edoors/particle.rb', line 142

def next_dst
    @dsts[0]
end

#reset!Object

clears all attributes



118
119
120
121
122
123
124
125
# File 'lib/edoors/particle.rb', line 118

def reset!
    clear_merged! ( @src ? @src : ( @dst ? @dst : nil ) )
    @ts = @src = @dst = @room = @door = @action = nil
    @dsts.clear
    @link_value.clear
    @link_keys.clear
    @payload.clear
end

#set_dst!(a, d) ⇒ Object

sets the current destination

Parameters:

  • a (String)

    the action

  • d (String Iota)

    the destination



186
187
188
189
190
191
192
193
194
# File 'lib/edoors/particle.rb', line 186

def set_dst! a, d
    @action = a
    if d.is_a? Edoors::Iota
        @dst = d
    else
        @dst = nil
        _split_path! d
    end
end

sets the links keys

@link_value attribute will be updated

Parameters:

  • args (Array)

    list of keys to set



315
316
317
318
319
320
321
322
# File 'lib/edoors/particle.rb', line 315

def set_link_keys *args
    @link_keys.clear if not @link_keys.empty?
    args.compact!
    args.each do |lf|
        @link_keys << lf
    end
    @link_value = @payload.select { |k,v| @link_keys.include? k }
end

#split_dst!Object

splits the next destination into @room, @door, @action attributes

the @dst attribute is set to nil the @room, @door, @action attributes are set to nil if not defined



201
202
203
204
205
206
# File 'lib/edoors/particle.rb', line 201

def split_dst!
    @dst = @room = @door = @action = nil
    return if (n = next_dst).nil?
    p, @action = n.split Edoors::ACT_SEP
    _split_path! p
end

#to_json(*a) ⇒ Object

called by JSON#generate to serialize the Particle object into JSON data

Parameters:

  • a (Array)

    belongs to JSON generator



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/edoors/particle.rb', line 87

def to_json *a
    {
        'kls'       => self.class.name,
        'ts'        => @ts,
        'src'       => (@src ? @src.path : nil ),
        'dst'       => (@dst ? @dst.path : nil ),
        'room'      => @room,
        'door'      => @door,
        'action'    => @action,
        'dsts'      => @dsts,
        'link_keys' => @link_keys,
        'payload'   => @payload,
        'merged'    => @merged
    }.to_json *a
end