If the data file is JSON, then it is better to convert the JSON data directly to a Ruby hash inside your module.
Here is a template (updated to ver 1.0.1
) …
GeorgeGrot_RobotHand_1-0-1.rbz (2.2 KB)
You’ll need to add the code to the "robot.rb"
file …
# encoding: UTF-8
#
# "GeorgeGrot_RobotHand/robot.rb"
#
module GeorgeGrot
module RobotHand
def move_robot
# use @data to move robot
end
# Add more methods to control robot here ...
end
end
The extension registrar file that goes in the “Plugins” folder looks like …
GeorgeGrot_RobotHand.rb
# encoding: UTF-8
#
# "GeorgeGrot_RobotHand.rb"
#
module GeorgeGrot
module RobotHand
EXTENSION = SketchupExtension.new(
'Robot Hand', 'GeorgeGrot_RobotHand/loader.rb'
)
EXTENSION.instance_eval {
self.description='Animated robot hand model.'
self.version='1.0.1'
self.copyright='(c) 2020'
self.creator='George Grot'
}
Sketchup.register_extension(EXTENSION, true)
end
end
The loader file looks like …
GeorgeGrot_RobotHand/loader.rb
# encoding: UTF-8
#
# "GeorgeGrot_RobotHand/loader.rb"
#
require 'json'
require(File.join(__dir__,'main'))
require(File.join(__dir__,'robot'))
module GeorgeGrot
module RobotHand
# AppObserver callbacks:
def onQuit
stop_listener()
Sketchup.remove_observer(self)
end
if !@loaded
# Create commands and menu items:
submenu = UI.menu('Extensions').add_submenu(SUBMENU_NAME)
submenu.add_item(MENU_START) {
start_listener()
}
submenu.add_item(MENU_STOP) {
stop_listener()
}
submenu.add_separator
submenu.add_item(MENU_DATAFILE) {
choose_datafile()
}
# Init @filepath from previous session:
@filepath = Sketchup.read_default(OPTS_KEY,'datafile',"")
# Attach this module to SketchUp as an AppObserver:
Sketchup.add_observer(self)
@loaded = true
end
end
end
The main file looks like …
GeorgeGrot_RobotHand/main.rb
# encoding: UTF-8
#
# "GeorgeGrot_RobotHand/main.rb"
#
module GeorgeGrot
module RobotHand
extend self
# CONSTANTS
WIN ||= Sketchup.platform == :platform_win
OPTS_KEY ||= Module::nesting[0].name.gsub('::','_')
DATAFILE_DIALOG_CAPTION ||= "Choose datafile ..."
DATAFILE_TYPE ||= 'JSON'
DATAFILE_EXTN ||= "*.#{DATAFILE_TYPE.downcase}"
OPNAME ||= 'Move Robot'
SUBMENU_NAME ||= 'GeorgeGrot: RobotHand'
MENU_START ||= 'Start Listener'
MENU_STOP ||= 'Stop Listener'
MENU_DATAFILE ||= 'Choose Datafile...'
# Module variables:
@data ||= {}
@filepath ||= ""
@last_mod_time = Time.now
@interval = 5.0 # seconds
def choose_datafile
dir = File.join(ENV['HOME'],'Documents')
path = UI.openpanel(
DATAFILE_DIALOG_CAPTION ,
File.exist?(dir) ? dir : ENV['HOME'] ,
WIN ? "#{DATAFILE_TYPE} Files|#{DATAFILE_EXTN}||" : DATAFILE_EXTN
)
if path
@filepath = path.gsub(/(\\\\|\\)/,'/')
Sketchup.write_default(OPTS_KEY,'datafile',@filepath)
else
false
end
end
def file_changed?
File.mtime(@filepath).to_i > @last_mod_time
end
def get_mod_time
@last_mod_time = File.mtime(@filepath).to_i
end
def import_data
json = File.read(@filepath)
@data = JSON.parse(json)
rescue => error
UI.messagebox(error.message)
end
def process_data
stop_listener()
get_mod_time()
import_data()
model = Sketchup.active_model
model.start_operation(OPNAME)
###
#
move_robot()
#
###
model.commit_operation
start_listener()
end
def start_listener()
result = choose_datafile() if @filepath.empty? || !File.exist?(@filepath)
return if !result
get_mod_time()
@listener = UI.start_timer(@interval,true) {
process_data() if file_changed?()
}
end
def stop_listener
UI.stop_timer(@listener) if @listener
@listener = nil
end
end
end
Oops … I see an error in process_data()
method, in file “main.rb”.
It is missing a line …
model = Sketchup.active_model
EDIT (again) There is also a call to get_mod_time()
missing, see below.
UPDATED examples above to ver 1.0.1