Project

General

Profile

« Previous | Next » 

Revision 1c89625f

Added by Marc Dequènes over 13 years ago

  • ID 1c89625f86dc33b7cff7f63ceb1e73da27eeb073

[evol] work on cyborg server protocol and API #5 (refs #31)

View differences:

bin/mapmaker
include SimpleServer
def interface
MapMakerInterface
MapMakerInterface.instance
end
end
lib/cyborghood/cyborg/interface.rb
base.extend(ClassMethods)
end
module ClassMethods
def decompose_command(cmd)
object, method = cmd.split('.', 2)
if method
begin
klass = object.split('::').inject(self) {|scope, const_name| scope.const_get(const_name)}
rescue
return
end
def find_node_action(node_name)
next_node_name, other_nodes_names = node_name.split('.', 2)
next_node_klass = api_klasses[next_node_name]
if next_node_klass.nil?
if api_methods.include? next_node_name
next_node_method = self.method(next_node_name)
return next_node_method if other_nodes_names.nil?
next_node = next_node_method.call
else
if object.index("::")
return
else
klass = self
method = cmd
end
return
end
[klass, method]
else
next_node = next_node_klass.instance
return next_node.method('api_nodes') if other_nodes_names.nil?
end
def has_node?(cmd)
klass, method = self.decompose_command(cmd)
return false if klass.nil?
return true if method.nil?
inst = klass.instance
inst.api_methods.include?(method)
end
next_node.find_node_action(other_nodes_names)
end
module ClassMethods
attr_accessor :exported_methods
attr_accessor :auto_export_public_instance_methods
......
self.class.auto_export_public_instance_methods = true
end
def api_modules
@modules ||= self.class.constants.select do |c|
def api_klasses
list = self.class.constants.collect do |c|
cc = self.class.const_get(c)
cc.class == Class and cc.ancestors.include? CyborgServerInterface
end
(cc.class == Class and cc.ancestors.include? CyborgServerInterface) ? [c, cc] : nil
end.compact
Hash[list]
end
def api_methods
......
methods & self.methods
end
def api_nodes
(api_klasses.keys + api_methods).sort
end
# preliminary incoming message handling
def call(cmd, data)
klass, method = self.class.decompose_command(cmd)
return "551 unknown object" if klass.nil?
inst = klass.instance
unless inst.api_methods.include?(method)
return "551 this object has no such method"
end
action = find_node_action(cmd)
return "551 unknown node" if action.nil?
if data.nil?
formated_data = []
......
begin
formated_data = YAML.load(data) unless data.nil?
rescue
return "552 unreadable data for arguments"
return "552 unreadable YAML data for arguments"
end
return "552 wrong format for arguments" unless formated_data.is_a? Array
......
begin
# preliminary outgoing message handling
inst.send(method, *formated_data).to_yaml
action.call(*formated_data).to_yaml
rescue
return "550 method call failed"
return "550 method call failed: " + $!
end
end
end
lib/cyborghood/cyborg/server.rb
if flags.index '?'
send_line "250+ ok"
send_line({'exists?' => @interface.has_node?(cmd)}.to_yaml)
send_line({'exists?' => @interface.find_node_action(cmd)}.to_yaml)
return
end
......
def receive_command(cmd, data = nil)
logger.debug "Executing command '#{cmd}' [#{identifier}]"
send_line @interface.instance.call(cmd, data)
send_line @interface.call(cmd, data)
end
def receive_error(msg)
......
end
def interface
EmptyInterface
EmptyInterface.instance
end
end
end

Also available in: Unified diff