class RSence::HValue

HValue is the model for client-server synchronized values. A value contains its payload {#data} and enough meta-data to define its behavior.

Attributes

data[R]

The payload data. Use {#set} to change.

is_valid[RW]

The validity of the data. Defaults to false, when the data comes from the client. @return [Boolean] True, when set by the server. False when initially set by the client. Also false, unless all responders return true.

members[R]

@private List of responders

meta[RW]

Value meta-data. The third constructor parameter

sync[R]

@private Is true when changed by the server. Causes the ValueManager to send its client-side representation.

val_id[R]

@private The unique ID of the value.

valid[RW]

The validity of the data. Defaults to false, when the data comes from the client. @return [Boolean] True, when set by the server. False when initially set by the client. Also false, unless all responders return true.

valid?[RW]

The validity of the data. Defaults to false, when the data comes from the client. @return [Boolean] True, when set by the server. False when initially set by the client. Also false, unless all responders return true.

value_id[R]

@private The unique ID of the value.

Public Class Methods

new( msg, data, meta = { :name => nil } ) click to toggle source

Creates a new client-server automatically synchronized data wrapper object. @param [Message] msg Just pass on the msg from the scope you call from. @param [#to_json] data Any data that can be converted to JSON. @param [Hash] meta Has no effect yet.

# File lib/rsence/value.rb, line 81
def initialize( msg, data, meta = { :name => nil } )
  
  ## Get an unique integer id for the value
  if RSence.args[:debug] and meta[:name] and not msg.valuemanager.id_exists?( msg, meta[:name] )
    @value_id   = meta[:name]
  else
    @value_id = msg.valuemanager.ses_unique_id( msg )
  end
  
  @meta = meta
  
  ## set the data of the hvalue
  set( msg, data, true )
  
  ## the @sync flag is raised, when the client data is older than the server data
  @sync  = false
  
  ## the @is_valid flag is lowered, when the client data is newer than the server data
  @is_valid = true
  
  ## Bind the value to the value manager and report it to the client
  add( msg )
  
  ## storage for validator bindings
  @members = {}
  
end

Public Instance Methods

add( msg ) click to toggle source

@private Method for binding the value to the session data.

# File lib/rsence/value.rb, line 49
def add( msg )
  
  # get the value storage from the session data
  session_values = msg.session[:values][:by_id]
  
  ## Store the object here
  session_values[ @value_id ] = self
  
  ## Sends the client-side description
  restore( msg )
  
  ## Set the valid flag, so we know that the value is initially in sync
  @is_valid = true
end
add_to_sync( msg ) click to toggle source

@private Adds the value to the sync array.

# File lib/rsence/value.rb, line 200
def add_to_sync( msg )
  ## add the id to the values to be synchronized (to client)
  sync_ids = msg.session[:values][:sync]
  unless sync_ids.include?( @value_id )
    sync_ids.push( @value_id )
  end
end
bind( plugin_name, method_name ) click to toggle source

Binds the value to a responder. The responder is an instance of {Plugins::Plugin__ Plugin} or {Plugins::GUIPlugin__ GUIPlugin}. Responders are called once, when the client requests the data to be changed. Responders must return true, if they accept the change. Otherwise the data is treated as invalid. Responders must respond to exactly two parameters: ( (Message) msg, (HValue) value )

@param [Symbol] plugin_name The name of the registered plugin to call with the method_name @param [Symbol] method_name The name of the method of the registered plugin plugin_name to call. @return [true]

# File lib/rsence/value.rb, line 117
def bind( plugin_name, method_name )
  plugin_name = plugin_name.to_sym unless plugin_name.class == Symbol
  method_name = method_name.to_sym unless method_name.class == Symbol
  @members[plugin_name] = [] unless @members.has_key?( plugin_name )
  @members[plugin_name].push( method_name ) unless @members[plugin_name].include?( method_name )
  return true
end
bound?( plugin_name, method_name ) click to toggle source

Checks, if the plugin_name and method_name pairing is already bound with the bind method. Returns true or false.

# File lib/rsence/value.rb, line 126
def bound?( plugin_name, method_name )
  plugin_name = plugin_name.to_sym unless plugin_name.class == Symbol
  method_name = method_name.to_sym unless method_name.class == Symbol
  return false unless @members.has_key?(plugin_name)
  return @members[plugin_name].include?(method_name)
end
die( msg=false )
Alias for: die!
die!( msg=false ) click to toggle source

Destructor method. If msg is supplied, deletes the client representation too. @param [false, Message] A {Message} instance. When supplied, deletes the client representation.

# File lib/rsence/value.rb, line 259
def die!( msg=false )
  
  release_all
  
  # get the value storage from the session data
  session_values = msg.session[:values][:by_id]
  
  ## Store the object here
  session_values.delete( @value_id )
  
  if msg and not @is_new_to_client
    msg.reply_value( :del, @value_id )
  end
end
Also aliased as: die
from_client( msg, data ) click to toggle source

@private Handle updates from the client.

# File lib/rsence/value.rb, line 178
def from_client( msg, data )
  # only process changes, if different from the one already stored.
  if @data != data
    
    # puts "data sync from client: #{@data.inspect} -> #{data.inspect} (#{@meta[:name]})"

    ## set takes care of the setting..
    @data = data
    
    ## change the valid state, because the value was set by the client!
    @is_valid = false
    
    ## add the id to the values to be checked
    check_ids = msg.session[:values][:check]
    unless check_ids.include?( @value_id )
      check_ids.push( @value_id )
    end
  end
  
end
inspect() click to toggle source
# File lib/rsence/value.rb, line 275
def inspect
  "#<RSence::HValue value_id:#{@value_id.inspect}, valid: #{@is_valid.inspect}, sync: #{@sync.inspect}, is_new_to_client: #{@is_new_to_client.inspect}, meta: #{@meta.inspect[0..100]}, data: #{@data.inspect[0..100]} ...>"
end
release( plugin_name=false, method_name=false ) click to toggle source

Releases the responder of the value, both params as in bind, but optional method_name can be omitted, matching all methods bound to the plugin_name. @param [Symbol] plugin_name The name of the plugin acting as a responder to the value. @param [Symbol] method_name The name of the method of the plugin acting as a responder to the value. @return [Boolean] Returns true, if successful, false if not bound or other error.

# File lib/rsence/value.rb, line 137
def release( plugin_name=false, method_name=false )
  plugin_name = plugin_name.to_sym if plugin_name.class == String
  method_name = method_name.to_sym if method_name.class == String
  return release_all if not plugin_name and not method_name
  return false unless @members.has_key?( plugin_name )
  if not method_name
    @members.delete( plugin_name )
  else 
    @members[plugin_name].slice!(@members[plugin_name].index( method_name )) if @members[plugin_name].include?(method_name)
    if @members[plugin_name].empty?
      @members.delete( plugin_name )
    end
  end
  return true
end
Also aliased as: unbind
release_all() click to toggle source

Releases all responders. @return [true]

# File lib/rsence/value.rb, line 155
def release_all
  @members = {}
  return true
end
restore( msg ) click to toggle source

@private (Re-)Send the client-size representation

# File lib/rsence/value.rb, line 65
def restore( msg )
  
  ## Tags itself as a new value from the client's point of view
  @is_new_to_client = true
  
  add_to_sync( msg )
  
end
set( msg, data, dont_tell_client=false ) click to toggle source

Sets the data of the value, the change will be synced with the client. @param [Message] msg The {Message} instance. @param [#to_json] data Any data that can be mapped to JSON and handled by the client. @param [Boolean] dont_tell_client Doesn’t notify the client about the change, if true.

# File lib/rsence/value.rb, line 212
def set( msg, data, dont_tell_client=false )
  
  @data   = data
  
  # won't tell the client about the change, usually not needed
  unless dont_tell_client
    ## update the flags
    @sync  = false
    @is_valid = true
    
    add_to_sync( msg )
  end
end
set_key( msg, key, data, dont_tell_client=false ) click to toggle source

Sets the key of the hash data of the value, the change will be synced with the client. @param [Message] msg The {Message} instance. @param [String] key The key of data to change @param [#to_json] data Any data that can be mapped to JSON and handled by the client. @param [Boolean] dont_tell_client Doesn’t notify the client about the change, if true.

# File lib/rsence/value.rb, line 231
def set_key( msg, key, data, dont_tell_client=false )
  
  @data[key] = data
  
  # won't tell the client about the change, usually not needed
  unless dont_tell_client
    ## update the flags
    @sync  = false
    @is_valid = true
    
    add_to_sync( msg )
  end
end
tell( msg ) click to toggle source

@private Tell all bound instances that the value is changed.

# File lib/rsence/value.rb, line 164
def tell( msg )
  invalid_count = 0
  @members.each_key do |plugin_name|
    @members[plugin_name].each do |method_name|
      invalid_count += 1 unless msg.plugins.run_plugin( plugin_name, method_name, msg, self ) 
    end
  end
  if invalid_count == 0
    @is_valid = true
    msg.session[:values][:check].delete( @value_id )
  end
end
to_client( msg ) click to toggle source

@private Tell the client that the value changed.

# File lib/rsence/value.rb, line 246
def to_client( msg )
  if @is_new_to_client
    ## Initialize a new client value
    msg.reply_value( :new, @value_id, @data )
    @is_new_to_client = false
  else
    ## Sets the client value
    msg.reply_value( :set, @value_id, @data )
  end
end
unbind( plugin_name=false, method_name=false )

@deprecated Use {#release} as the opposite to bind.

Alias for: release
val_id=(new_id)

@private

Alias for: value_id=
value_id=(new_id) click to toggle source

@private

# File lib/rsence/value.rb, line 39
def value_id=(new_id)
  @value_id = new_id
end
Also aliased as: val_id=