I’m trying to use the rs.sleep() function in order to create a time interval between operation for batch rendering purpose.
But when I try to use the rs.sleep() function in a loop, it only works at the end of the whole loop.
For instance I tried the simple script but everything is printed in the same time instead of one line each 2000ms
The problem is that the GHPython component doesn’t recompute at each loop iteration! Instead it runs your script once internally, keeping track of your desired pauses, and then returns the result(s) at the script end. It only updates itself, if it gets externally triggered, by you or an input parameter changing.
What you are trying to do isn’t possible, unless you explicitly control the way the component gets updated:
from scriptcontext import sticky
import Grasshopper as gh
import time
def update_component():
"""Updates this component, similar to using a Grasshopper timer."""
# written by Anders Deleuran (andersholdendeleuran.com)
def call_back(e):
"""Defines a callback action"""
ghenv.Component.ExpireSolution(False)
# Get the Grasshopper document
ghDoc = ghenv.Component.OnPingDocument()
# Schedule this component to expire
ghDoc.ScheduleSolution(1, \
gh.Kernel.GH_Document.GH_ScheduleDelegate(call_back))
message_parts = "This is a slow message!".split(" ")
if Reset and "Count" in sticky.keys():
sticky.pop("Count", None)
ghenv.Component.Message = "Reset"
if Run:
if not "Count" in sticky.keys():
count = 0
sticky["Count"] = count
update_component()
else:
count = sticky["Count"]
if count < len(message_parts)-1:
count += 1
sticky["Count"] = count
ghenv.Component.Message = "Running"
update_component()
else:
ghenv.Component.Message = "Finished"
print "{}: {}".format(count, message_parts[count])
time.sleep(0.5)
Just wondering. Is it possible to make it wait for a external (from another component) condition to be met in order to proceed to the next loop, instead of the timer? (sleep).
By the way, here follows a small amendment where the boolean toggle is not necessary:
import scriptcontext as sc
import Grasshopper as gh
import time
def update_component():
"""Updates this component, similar to using a Grasshopper timer."""
# written by Anders Deleuran (andersholdendeleuran.com)
def call_back(e):
"""Defines a callback action"""
ghenv.Component.ExpireSolution(False)
# Get the Grasshopper document
ghDoc = ghenv.Component.OnPingDocument()
# Schedule this component to expire
ghDoc.ScheduleSolution(1, \
gh.Kernel.GH_Document.GH_ScheduleDelegate(call_back))
#Resets the sticky dictionary
if Reset and "list_index" in sc.sticky.keys():
sc.sticky.pop("list_index", None)
ghenv.Component.Message = "Reset"
sc.sticky["run_timed_loop"] = True
if sc.sticky.Contains("run_timed_loop"):
if sc.sticky["run_timed_loop"]:
#after reseting, if the sticky dictionary is empty, start counting and putting
if not "list_index" in sc.sticky.keys():
count = 0
sc.sticky["list_index"] = count
update_component()
#filter when starts counting (index > 0)
else:
count = sc.sticky["list_index"]
#loop over all list but the last item
if count < len(list)-1:
count += 1
sc.sticky["list_index"] = count
ghenv.Component.Message = "Running"
update_component()
# list last item
else:
ghenv.Component.Message = "Finished"
sc.sticky["run_timed_loop"] = False
item = list[count]
time.sleep(time_to_delay)
Python sleep() will pause for an hour, day or whatever if given the proper value. It does not allow other processes take place (in same script) however. A better way is to use an event which will create an event on timeout.
Have a look at threading.Timer. It runs your function in a new thread without using sleep().
from threading import Timer
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
The second method to delay would be using the implicit wait method:
driver.implicitly_wait(5)
The third method is more useful when you have to wait until a particular action is completed or until an element is found: