Class installs twice when reloaded!
-
When I start SU, it will output 1 "x" releasing the middle-mouse-button, but when I reload the plugin, it will output 2 times "x"? Though a second reload doesn't produce 3 times "x"!
[ruby]class MyToolsObserver < Sketchup;;ToolsObserver def onActiveToolChanged(tools, tool_name, tool_id) if @prevOrbit puts "x" @prevOrbit=false else @prevOrbit = true if tool_name == "CameraOrbitTool" end end end unless file_loaded?(__FILE__) Sketchup.active_model.tools.add_observer(MyToolsObserver.new) file_loaded(__FILE__) end[/ruby]
Is there even a way to unload any class, module of method? Maybe there is a total reset, removing all plugins, before reloading them all again, without the need to restart SU and reloading the model...
thanks
-
I tested and the only way I could get double puts was if an observer instance was attached twice to the active_model.
-
@onidarbe said:
Is there even a way to unload any class, module of method?
Observers need to be unattached before destroying their class.
This means you need to keep track of what you attach to what objects., so you can dettach them.MyViewObserver = nil
or WITHIN your module (because it is a private method):
remove_const(:MyViewObserver)
@onidarbe said:
Maybe there is a total reset, removing all plugins, before reloading them all again, without the need to restart SU and reloading the model...
NO there is no total reset.
-
Thanks again, your always answering!
It seems
file_loaded(__FILE__)
andunless file_loaded?(__FILE__)
just doesn't work! It lets it reload a second time. And they are all using this techniek?!Isn't there any way to find which modules, classes, methods and observers have been added by all plugins?! Maybe I just need to search through the code of every *.rb file in the plugins-maps! But then I still need to know if I can undo everything. I already now that I can't remove any menu added items, although I could gray them out... But can I remove everything: methods, modules, classes, observers and variables. And I probably forget a lot of other things, considering I'm just starting to learn Ruby.
-
@onidarbe said:
It seems
file_loaded(__FILE__)
andunless file_loaded?(__FILE__)
just doesn't work!The method just caompares string elements of an array (
$loaded_files
).
It does not absolutely need to be the full pathname of the script.
I often only write the plugin module names, a colon and then the basename of the script, ie:
this_file = "#{Module.nesting[0].name}:#{File.basename(__FILE__)}" file_loaded(this_file)
If you do not like the way the
file_loaded()
from "sketchup.rb" works, you can write your OWN in a library module and mix in into each of your modules.Or you can use the built-in Ruby function
defined?( *object* )
@onidarbe said:
But can I remove everything: methods, modules, classes, observers and variables.
NO do not mess with other people's Ruby objects. Turn plugin's off via the Preferences > Extensions dialog. Then restart SketchUp.
@onidarbe said:
And I probably forget a lot of other things, considering I'm just starting to learn Ruby.
Then start with easier coding projects.
-
Thanks Dan,
With your help I found the problem with reloading plugins:
When my Sketchup starts,
file_loaded(__FILE__)
adds "c:/progra~2/sketchup/sketch~1/plugins/any_script.rb" to$loaded_files
, but when reloading the plugin it adds "c:/program files (x86)/sketchup/sketchup 2013/plugins/any_script.rb". So when SU starts it's using the shorter DOS-path though the filename isn't truncated to 8 characters, at least in my Windows 7 x64.
That's whyif !file_loaded?(__FILE__)
doesn't work!So I only need to find a way to put in the full path length on startup. Any idea?
Using only the filename or module:basename doesn't seem right to me, because shouldn't we all add the same to$loaded_files
? Buy the wayModule.nesting[0].name
gives "undefined method"! Probably because of an older Ruby version.I was playing with the as_pluginloader.rb from Alexander Schreyer. I wanted to add a "reload all plugins". That's when I figured out that many plugins don't even use
file_loaded
. So that's a bummer -
@onidarbe said:
So I only need to find a way to put in the full path length on startup. Any idea?
thisfile = File.expand_path(__FILE__) unless file_loaded?( thisfile ) # RUN ONCE CODE file_loaded( thisfile ) end
-
@onidarbe said:
BY (not Buy,) the way
Module.nesting[0].name
gives "undefined method"! Probably because of an older Ruby version.Wrong, you cannot call it from the console. From within "main" instance of
Object
it will just returnnil
. AndNilClass
does not have aname()
instance method.Module.nesting[0].name
%(#008000)[Error: #<NoMethodError: undefined method
name' for nil:NilClass>]`It must be called from within a class or module.
-
@onidarbe said:
Using only the filename or module:basename doesn't seem right to me, because shouldn't we all add the same to
$loaded_files
?You miss the point.
The arg requires a
String
(of any kind,) .. a does NOT require a real pathname, even though the API show this in the example.Only YOU will be testing the
$loaded_files
array for YOUR strings, so they can be whatever YOU need.The ACTUAL loaded file's path is stored in the Ruby global array
$LOADED_FEATURES
(aliased as$"
.)Since ALL of YOUR plugin's should be within a sub-module or YOUR OWN toplevel module (whatever you choose to name it,) ... you can instead use your OWN custom loaded files array.
See my example (from the Snippet's Index):
[Code] custom file_loaded() and file_loaded?() v2.0.0 -
ooh OK, that explains a lot. Thanks Dan!
Maybe you could also edit that post of you and add that they should never use the full path, because in windows it could be truncated!
-
@dan rathbun said:
@onidarbe said:
So I only need to find a way to put in the full path length on startup. Any idea?
thisfile = File.expand_path(__FILE__) > > unless file_loaded?( thisfile ) > > # RUN ONCE CODE > > file_loaded( thisfile ) > > end
Just tested this
File.expand_path
does not really expand those Window pathnames. -
yheah I know, tried that one already.
Need to use win32API, but I can't seem to figure out how to use that!
require "Win32API"
gives me: "parenthesize argument(s) for future version" and "no such file to load" -
@onidarbe said:
Need to use win32API, but I can't seem to figure out how to use that!
I posted the so files in the "Plugins" forum:
[Plugin Library] Win32API and Win32OLE so files@onidarbe said:
require "Win32API"
gives me: "parenthesize argument(s) for future version" and "no such file to load"Get in the habit of putting parenthesis around argument lists, like:
require("Win32API")
Do NOT put a space between method names and the opening**(**
-
aoh, I need to have that file Win32API.so in the plugin map!
thanks
Advertisement