module Vizkit::PluginHelper
Helper functions for the plugin - system of vizkit. The plugin system handles plugins for vizkit 3d and vizkit.rb (for example widgets for displaying data coming from orocos tasks)
Public Class Methods
Converts a string into the corresponding class object. @note It is also aware of typelib classes.
@param [String] class_name the name of the class. @return [Class] the corresponding class object or nil
if no class can be found.
# File lib/vizkit/plugin.rb, line 150 def self.class_from_string(class_name) return unless class_name return class_name unless class_name.respond_to? :to_str if class_name.include?("/") typekit = begin Orocos.load_typekit_for(class_name, false) rescue nil end if Orocos.registry.include?(class_name) Orocos.registry.get class_name else Vizkit.info "Typelib Type #{class_name} cannot be found" nil end else #check if its a ruby const begin m = Kernel class_name.split("::").each do |name| m = m.const_get(name) end m rescue NameError # Converts ruby Typelib Classes to Typelib names # to load the typekit and try again temp = to_typelib_name(class_name) if temp class_from_string(temp) else nil end end end end
Generates an array of strings consisting the class and all super class names of the given class object.
@param [Class] klass the class @param [true,false] include_super if false no super class names are included @return [Array<String>] an array of the class and all superclass names
# File lib/vizkit/plugin.rb, line 100 def self.classes(klass,include_super=true) return Array.new unless klass && klass.name raise ArgumentError, "#{klass} is not a class" unless klass.respond_to? :name arry = if include_super && klass.respond_to?(:superclass) && klass.superclass && (klass <=> klass.superclass) != 0 Array(klass.name) + classes(klass.superclass) else Array(klass.name) end # add opaque type if intermediate or m_type if Orocos.registry.include?(klass.name) && Orocos.default_loader.intermediate_type?(klass) type = Orocos.default_loader.opaque_type_for(klass) if type.respond_to? :intermediate Array(type.type.name) + arry else Array(type.name) + arry end else arry end end
Maps an object to an array of strings
@see ::register_map_obj @param [String] klass_name the class name of the object which can be different from the real class name @param [Object] object the object that will be passed to the code block registered via ::register_map_obj @return [Array<String>] an array of names which can be used to find a plugin able to handle the object
# File lib/vizkit/plugin.rb, line 43 def self.map_obj(klass_name,object=nil) return Array.new unless @map_obj return Array.new unless klass_name if !object normalize_obj(klass_name,false) else return Array.new unless @map_obj.has_key?(klass_name) Array(@map_obj[klass_name].call(object)) end end
Normalizes the object to its class names. It is also aware of objects where the class name is replaced by other names like plugins and objects for which a mapping was registered.
@see ::register_map_obj @note This is used to find all strings for these a plugin might be registered @note There will be no BasicObject for ruby1.8. @note all m types are converted to the corresponding opaque type (this will not work if Orocos is not initialized therefore no m types should be used for registering widgets!) @return [Array<String>] an array of names. @example
normalize_obj(123) => ["Fixnum", "Integer", "Numeric", "Object", "BasicObject"]
normalize_obj("/base/samples/frame/Frame") => ["/base/samples/frame/Frame", "Typelib::CompoundType", "Typelib::Type", "Object", "BasicObject"]
normalize_obj(Types.base.samples.frame.Frame) => ["/base/samples/frame/Frame", "Typelib::CompoundType", "Typelib::Type", "Object", "BasicObject"]
normalize_obj(Types.base.samples.frame.Frame.new) => ["/base/samples/frame/Frame", "Typelib::CompoundType", "Typelib::Type", "Object", "BasicObject"]
# File lib/vizkit/plugin.rb, line 70 def self.normalize_obj(object,include_super=true) return Array.new unless object names = if object.respond_to? :superclass classes object,include_super elsif object.respond_to? :to_str result = normalize_obj(class_from_string(object),include_super) result << object if result.empty? result elsif object.respond_to? :plugin_spec klasses = classes(object.class,include_super) klasses.shift Array(object.plugin_spec.plugin_name) + klasses else klasses = classes(object.class,include_super) klasses.shift if object.is_a? Qt::Object Array(object.class_name) + klasses else Array(object.class.name) + klasses end end (map_obj(names.first,object)+names).compact end
Registers a code block which will be executed to map objects to an array of strings. This mechanism is used to customize the mapping of objects to searchable strings and goes hand in hand with ::normalize_obj
@see ::normalize_obj @note The code block will be called for the class object and class instances @param [Array<Object>] objects n objects or an array of objects for which the given
code block shall be invoked.
@param [CodeBlock] block the code block @example
PluginHelper.register_map_obj(Float) do |obj|
["Mystring1","MyString2"]
end
Plugin.map_obj(123.2) => ["Mystring1","MyString2"]
Plugin.map_obj("Float",123.2) => ["Mystring1","MyString2"]
Plugin.map_obj("Float") => ["Mystring1","MyString2"]
Plugin.map_obj(Float) => ["Mystring1","MyString2"]
# File lib/vizkit/plugin.rb, line 30 def self.register_map_obj(*objects,&block) @map_obj ||= Hash.new objects.each do |object| @map_obj[normalize_obj(object,false).first] = block end end
Converts a ruby Typelib class name to a Typelib class name. This is needed to load the typekit before converting the string into a corresponding class object.
@param [String] class_name the name of the ruby class @return [String] the name of the typelib class or nil
if the given string does not match a ruby class name of a typelib class.
@example
to_typelib_name("Types.base.Angle" => "/base/Angle"
# File lib/vizkit/plugin.rb, line 133 def self.to_typelib_name(class_name) class_name =~ /^Types(::.*::)(\w*)/ if $1 && $2 temp2 = $2 temp = $1.gsub(/::/,"/") temp.downcase + temp2 else nil end end