SketchUp整蛊大赏
SketchUp 中的 ruby 控制台作为自动化操作的利器,同时也可以是“整活”的窗口。本篇介绍几个简单的整蛊代码。不过需要注意,这些“整蛊代码”的主要写作目的在于其表演性和娱乐性,而不应该关注其破坏性,更不能加以恶意。
这些代码同时也可以对“正统”的 SU Ruby 使用提供一定的思路借鉴,尤其是可以避免在编写代码过程中出纰漏而无意中整蛊了自己。
*这是“SketchUp不务正业系列”中的一篇,文中浅紫色文字为“不务正业”对“正业”的借鉴参考。
【本期目录】 | |
一、死循环 二、背景闪烁 三、莫名的响声 四、组件锁死 五、要命的保存 | 其中第1个为简陋且破坏性强的代码,不推荐使用;第2、3个通过线程实现功能;第4、5个则通过 SU Ruby 自带的监控类实现。 |
一、死循环
这是一个最简单最简陋也相当危险的代码:
while true do end
在控制台中输入以上代码会使得控制台主进程进入死循环:
此时控制台置顶,SketchUp 界面不能进行其他操作,整个程序处在未响应的状态。此时只能强制关闭程序,只要 SU 打开了模型文件,无论保存与否,这都是一个很不合适的玩笑。
类似的做法还有长时间的等待:
sleep 10000
以上代码使主进程等待10000秒,其效果也近乎等于死循环了。
正业 但是反过来说,如果自己编写的代码在考虑不周时,有可能出现死循环的状态;又或者有繁复的计算过程,在有些情况下需要大量等待时间。这些情况下如果不加以预处理,很有可能表现出来就是这样的一个整蛊效果,因此需要特别注意。
二、背景闪烁
以下是一个稍微复杂的整蛊代码:
def changeBkColor()
mod=Sketchup.active_model
mod.rendering_options["BackgroundColor"]=(rand()*0xffffff).round
end
th_1=Thread.new{
while true do
changeBkColor()
sleep(0.5)
end
}
执行以上代码会使得背景颜色以 2Hz 的频率随机变换颜色:
以上代码中第1-4行定义了一个使当前模型背景颜色随机变换一次的方法(函数),每次调用 changeBkColor 时就会根据随机函数重新设置一次背景颜色。而第6-10行新建了一个线程,规定了一个死循环,循环内每调用一次刚定义的方法(函数)就在线程内等待0.5秒,并将此线程命名为 th_1,以便在主线程中保持对它的控制。
这里同样是使用了死循环,但是由于新建了一个线程,并不会占用控制台的主进程,因此即使线程内是死循环,也不会造成程序卡死。这番操作之后如果关闭 ruby 控制台,等到被整蛊者回到屏幕前将会无所适从(当然这里假设他没有了解过 ruby 控制台的具体功能)。
这个方法和粗暴的主线程死循环比起来,显然要温和很多。不仅仅因为其不会造成卡死,更因为它可以重新打开控制台后取消这个循环:
th_1.kill
正业 这是使用线程的优势之一,可以从外部停止失控的线程。对应到正统的 SU Ruby 使用场景中,如果遇到计算过程繁杂、误操作可能造成运行时间过长的情况,可以新建线程单独管理,如果较长时间未响应则可以人工中止过程而不至于卡死。
另外也可以使用 UI 模块中的 .start_timer 和 .stop_timer 方法来实现不占用主线程的死循环,这里不额外举例了。
三、莫名的响声
以下代码具有隐藏性和硬件局限性:
th_2=Thread.new{
while true do
UI.beep if rand()>0.5
sleep 10
end
}
代码中创建了一个名为 th_2 的线程,使其每10秒就有二分之一的概率发出系统提示音。停止它的方法和上一个方法“背景闪烁”一样:
th_2.kill
以上代码中的 .beep 方法调用系统提示音,一般与弹窗一并出现,作为对用户的提醒。如果像以上代码中滥用,就会对用户造成很大的疑惑和困扰。不过,本方法被“静音玩家”所免疫。
四、组件锁死
以下代码造成的效果很具有迷惑性:
class NotIntoInstance < Sketchup::ModelObserver
def onActivePathChanged(model)
model.close_active unless model.active_path.nil?
end
end
mod_obs_1=NotIntoInstance.new
Sketchup.active_model.add_observer(mod_obs_1)
此方法定义了一个监控类,对当前模型的状态进行监控,当检测到模型打开了组编辑器,就会立刻关闭当前组件。所以运行以上代码后,无论是双击组件还是右键菜单中选择“编辑组”,表现上都是无法进入组编辑器:
当然,这个方法一样是可逆的,前提是新加入的监控类实例在控制台中留有引用(以上代码之中的 mod_obs_1 即实例的引用):
Sketchup.active_model.remove_observer(mod_obs_1)
五、要命的保存
以下是一个娱乐性很强的整蛊代码:
class AreYouARobot < Sketchup::ModelObserver
def onPreSaveModel(model)
while true do
a=rand(99)
b=rand(99)
c=a+b
res=UI.inputbox(["#{a}+#{b}="])
redo unless res.respond_to?(:[])
break if res[0] == c.to_s
end
end
end
mod_obs_2=AreYouARobot.new
Sketchup.active_model.add_observer(mod_obs_2)
运行完代码之后,每一次保存都需要进行一次“100以内加法”的验证码测试,如果输入错误则会重新跳出验证码,如果不正确输入计算结果,就会造成实际上的死循环:
此功能同样通过监控类实现,因此复原功能也是通过移除监控:
Sketchup.active_model.remove_observer(mod_obs_2)
以上五个整蛊代码除了第一种“死循环”具有很强的破坏性,另外四个方法有相应的功能复原手段。具体来说:第2、3个是通过多线程实现的后台运行,因此功能复原使用的是中止进程;而第4、5个则是通过 SU Ruby 中自带的监控类实现,因此对应的复原是使用移除监控的方法。
正业 这两类方法也是比较好的后台运行思路,既可以暗自地起到“整蛊”的作用,也可以实时地检测自定义工具、自定义功能的触发条件。正如本系列创作的初衷,虽然名为“不务正业”,但怪异旁门的方法也能够给“正统”的使用方式以参考借鉴。
(都看到这了,点个赞呗)
本篇文章是“SketchUp不务正业系列”的其中一篇,编号为SU-2021-S01,更多与SketchUp Ruby有关的其他文章可以点击公众号菜单中的“SU Ruby”选项获得文章的目录。