Skip to content

Commit f099320

Browse files
committed
Spider - further work reducing surface area of time functions
All Time Management functions have now been gathered and grouped to a small section at the top of runtime.rb. Note that all the thread locals in this block of fns are *only used within this fns* and not elsewhere. This includes both reading (get) and writing (set). This should with the integration of Link support and for a global metronome.
1 parent 46ee01d commit f099320

File tree

5 files changed

+109
-103
lines changed

5 files changed

+109
-103
lines changed

app/server/ruby/lib/sonicpi/lang/core.rb

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def get_event(*args)
298298
# If we've time_warped into the future raise a timing exception
299299
if __system_thread_locals.get(:sonic_pi_spider_in_time_warp)
300300

301-
if __system_thread_locals.get(:sonic_pi_spider_time_warp_start) < __system_thread_locals.get(:sonic_pi_spider_time)
301+
if __system_thread_locals.get(:sonic_pi_spider_time_warp_start) < __get_spider_time
302302
raise TimingError, "Sadly, you may not time_warp into the future to call get, then bring the result back in time to now."
303303
end
304304
end
@@ -939,7 +939,6 @@ def clear
939939
def time_warp(times=0, params=nil, &block)
940940
__schedule_delayed_blocks_and_messages!
941941

942-
943942
raise ArgumentError, "time_warp requires a do/end block" unless block
944943
prev_ctl_deltas = __system_thread_locals.get(:sonic_pi_local_control_deltas)
945944
prev_cache = __system_thread_locals.get(:sonic_pi_spider_time_state_cache, [])
@@ -953,45 +952,37 @@ def time_warp(times=0, params=nil, &block)
953952
raise ArgumentError, "params needs to be a list-like thing" unless params.respond_to? :[]
954953
raise ArgumentError, "times needs to be a list-like thing" unless times.respond_to? :each_with_index
955954

956-
vt_orig = __get_spider_time
957-
density = __thread_locals.get(:sonic_pi_local_spider_density) || 1.0
958-
orig_sleep_mul_w_density = __get_spider_sleep_mul * density
959-
orig_beat = __get_spider_beat
955+
960956
already_in_time_warp = __system_thread_locals.get :sonic_pi_spider_in_time_warp
961957

962-
__system_thread_locals.set(:sonic_pi_spider_time_warp_start, vt_orig.freeze) unless already_in_time_warp
958+
__system_thread_locals.set(:sonic_pi_spider_time_warp_start, __get_spider_time) unless already_in_time_warp
963959
__system_thread_locals.set_local :sonic_pi_spider_in_time_warp, true
960+
__with_preserved_spider_time_and_beat do
964961

965-
times.each_with_index do |delta, idx|
966-
sleep_time = delta * orig_sleep_mul_w_density
967-
new_time = vt_orig + sleep_time
962+
times.each_with_index do |delta, idx|
968963

969-
__change_spider_time!(new_time)
970-
__change_spider_beat!(orig_beat + delta)
971-
__system_thread_locals.set_local :sonic_pi_local_control_deltas, {}
972-
__system_thread_locals.set_local(:sonic_pi_spider_time_state_cache, [])
964+
sleep delta
973965

974-
case block.arity
975-
when 0
976-
block.call
977-
when 1
978-
block.call(params[idx % params_size])
979-
when 2
980-
if had_params
981-
block.call(delta, params[idx % params_size])
966+
case block.arity
967+
when 0
968+
block.call
969+
when 1
970+
block.call(params[idx % params_size])
971+
when 2
972+
if had_params
973+
block.call(delta, params[idx % params_size])
974+
else
975+
block.call(delta, idx)
976+
end
977+
when 3
978+
block.call(t, params[idx % params_size], idx)
982979
else
983-
block.call(delta, idx)
980+
raise ArgumentError, "block for time_warp should only accept 0, 1, 2 or 3 parameters. You gave: #{block.arity}."
984981
end
985-
when 3
986-
block.call(t, params[idx % params_size], idx)
987-
else
988-
raise ArgumentError, "block for time_warp should only accept 0, 1, 2 or 3 parameters. You gave: #{block.arity}."
982+
__schedule_delayed_blocks_and_messages!
989983
end
990-
__schedule_delayed_blocks_and_messages!
991984
end
992985

993-
__change_spider_time!(vt_orig)
994-
__change_spider_beat!(orig_beat)
995986
__system_thread_locals.set_local :sonic_pi_spider_in_time_warp, already_in_time_warp
996987
__system_thread_locals.set_local :sonic_pi_local_control_deltas, prev_ctl_deltas
997988
__system_thread_locals.set_local(:sonic_pi_spider_time_state_cache, prev_cache)
@@ -3573,8 +3564,7 @@ def with_cue_logging(v, &block)
35733564
def use_bpm(bpm, &block)
35743565
raise ArgumentError, "use_bpm does not work with a block. Perhaps you meant with_bpm" if block
35753566
raise ArgumentError, "use_bpm's BPM should be a positive value. You tried to use: #{bpm}" unless bpm > 0
3576-
sleep_mul = 60.0 / bpm
3577-
__change_spider_sleep_mul!(sleep_mul)
3567+
__change_spider_bpm!(bpm)
35783568
end
35793569
doc name: :use_bpm,
35803570
introduced: Version.new(2,0,0),
@@ -3627,11 +3617,10 @@ def use_bpm(bpm, &block)
36273617
def with_bpm(bpm, &block)
36283618
raise ArgumentError, "with_bpm must be called with a do/end block. Perhaps you meant use_bpm" unless block
36293619
raise ArgumentError, "with_bpm's BPM should be a positive value. You tried to use: #{bpm}" unless bpm > 0
3630-
current_mul = __get_spider_time
3631-
sleep_mul = 60.0 / bpm
3632-
__change_spider_sleep_mul!(sleep_mul)
3620+
current_bpm = __get_spider_bpm
3621+
__change_spider_bpm!(bpm)
36333622
res = block.call
3634-
__change_spider_sleep_mul!(current_mul)
3623+
__change_spider_bpm!(curent_bpm)
36353624
res
36363625
end
36373626
doc name: :with_bpm,
@@ -3685,11 +3674,11 @@ def with_bpm(bpm, &block)
36853674
def with_bpm_mul(mul, &block)
36863675
raise ArgumentError, "with_bpm_mul must be called with a do/end block. Perhaps you meant use_bpm_mul" unless block
36873676
raise ArgumentError, "with_bpm_mul's mul should be a positive value. You tried to use: #{mul}" unless mul > 0
3688-
current_mul = __get_spider_sleep_mul
3689-
new_mul = current_mul.to_f / mul
3690-
__change_spider_sleep_mul!(new_mul)
3677+
current_bpm = __get_spider_bpm
3678+
new_bpm = current_bpm * mul.to_f
3679+
__change_spider_bpm!(new_bpm)
36913680
res = block.call
3692-
__change_spider_sleep_mul!(current_mul)
3681+
__change_spider_bpm!(current_bpm)
36933682
res
36943683
end
36953684
doc name: :with_bpm_mul,
@@ -3720,9 +3709,8 @@ def with_bpm_mul(mul, &block)
37203709
def use_bpm_mul(mul, &block)
37213710
raise ArgumentError, "use_bpm_mul must not be called with a block. Perhaps you meant with_bpm_mul" if block
37223711
raise ArgumentError, "use_bpm_mul's mul should be a positive value. You tried to use: #{mul}" unless mul > 0
3723-
current_mul = __get_spider_sleep_mul
3724-
new_mul = current_mul.to_f / mul
3725-
__change_spider_sleep_mul!(new_mul)
3712+
new_bpm = __get_spider_bpm * mul.to_f
3713+
__change_spider_bpm!(new_bpm)
37263714
end
37273715
doc name: :use_bpm_mul,
37283716
introduced: Version.new(2,3,0),
@@ -4145,27 +4133,16 @@ def sleep(beats)
41454133

41464134
# Schedule messages
41474135
__schedule_delayed_blocks_and_messages!
4148-
__change_spider_beat!(__get_spider_beat + beats)
41494136
return if beats == 0
41504137

4151-
# Grab the current virtual time
4152-
last_vt = __get_spider_time
4153-
4154-
in_time_warp = __system_thread_locals.get(:sonic_pi_spider_in_time_warp)
4155-
4156-
# Now get on with syncing the rest of the sleep time...
4157-
4158-
# Calculate the amount of time to sleep (take into account current bpm setting)
4159-
sleep_time = beats * __get_spider_sleep_mul
4160-
4161-
# Calculate the new virtual time
4162-
new_vt = last_vt + sleep_time
4138+
__change_spider_beat_and_time_by_beat_delta!(beats)
41634139

41644140
sat = current_sched_ahead_time
4165-
__change_spider_time!(new_vt)
4166-
4141+
new_vt = __get_spider_time
41674142
now = Time.now
41684143

4144+
in_time_warp = __system_thread_locals.get(:sonic_pi_spider_in_time_warp)
4145+
41694146
if now - (sat + 0.5) > new_vt
41704147
raise TimingError, "Timing Exception: thread got too far behind time"
41714148
elsif (now - sat) > new_vt
@@ -4193,9 +4170,10 @@ def sleep(beats)
41934170
end
41944171
else
41954172
if in_time_warp
4196-
# Don't sleep if within a time shift
4173+
# Don't sleep if within a time warp
4174+
#
41974175
# However, do make sure the vt hasn't got too far ahead of the real time
4198-
raise TimingError, "Timing Exception: thread got too far ahead of time" if (new_vt - 17) > now
4176+
# raise TimingError, "Timing Exception: thread got too far ahead of time" if (new_vt - 17) > now
41994177
else
42004178
Kernel.sleep new_vt - now
42014179
end
@@ -4338,14 +4316,14 @@ def sync_event(*args)
43384316
se = @event_history.sync(t, p, i, d, b, m, cue_id, arg_matcher)
43394317

43404318
__system_thread_locals.set(:sonic_pi_spider_synced, true)
4341-
__change_spider_beat!(se.beat)
43424319

4343-
__change_spider_time!(se.time)
4320+
## only need to use se for beat and time if not in :link or :metro bpm
4321+
__change_spider_time_and_beat!(se.time, se.beat)
43444322
__system_thread_locals.set_local :sonic_pi_local_last_sync, se
43454323

43464324
if bpm_sync
43474325
bpm = se.bpm <= 0 ? 60 : se.bpm
4348-
__change_spider_sleep_mul!(60.0 / bpm)
4326+
use_bpm bpm
43494327
end
43504328

43514329
run_info = ""

app/server/ruby/lib/sonicpi/lang/sound.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ def self.included(base)
138138
end
139139

140140
@life_hooks.on_exit do |job_id, payload|
141-
__system_thread_locals.set(:sonic_pi_spider_start_time, payload[:start_t])
142141
__system_thread_locals.set_local(:sonic_pi_local_thread_group, "job_remover-#{job_id}".freeze)
143142
Thread.current.priority = -10
144143
shutdown_job_mixer(job_id)

app/server/ruby/lib/sonicpi/runtime.rb

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,68 @@ def load_snippets(path=snippets_path, quiet=false)
8989
end
9090
end
9191

92+
### Start - Spider Time Management functions
93+
###
94+
def __change_spider_time_and_beat!(new_time, new_beat)
95+
__system_thread_locals.set :sonic_pi_spider_time, new_time.freeze
96+
__system_thread_locals.set(:sonic_pi_spider_beat, new_beat)
97+
end
98+
99+
def __reset_spider_time_and_beat!
100+
t = Time.now.freeze
101+
__change_spider_time_and_beat!(t, 0)
102+
__system_thread_locals.set :sonic_pi_spider_start_time, t
103+
end
104+
105+
def __change_spider_bpm!(new_bpm)
106+
__system_thread_locals.set :sonic_pi_spider_bpm, new_bpm.to_f
107+
end
108+
109+
def __reset_spider_bpm!
110+
__change_spider_bpm!(60.0)
111+
end
112+
113+
def __change_spider_beat_and_time_by_beat_delta!(beat_delta)
114+
sleep_time = beat_delta * __get_spider_sleep_mul
115+
new_time = __get_spider_time + sleep_time
116+
new_beat = __get_spider_beat + beat_delta
117+
__change_spider_time_and_beat!(new_time, new_beat)
118+
end
119+
120+
def __get_spider_time
121+
__system_thread_locals.get(:sonic_pi_spider_time)
122+
end
123+
124+
def __get_spider_schedule_time
125+
__system_thread_locals.get(:sonic_pi_spider_time) + current_sched_ahead_time
126+
end
127+
128+
def __get_spider_sleep_mul
129+
60.0 / __system_thread_locals.get(:sonic_pi_spider_bpm)
130+
end
131+
132+
def __get_spider_bpm
133+
__system_thread_locals.get(:sonic_pi_spider_bpm)
134+
end
135+
136+
def __get_spider_beat
137+
__system_thread_locals.get(:sonic_pi_spider_beat)
138+
end
139+
140+
def __get_spider_start_time
141+
__system_thread_locals.get :sonic_pi_spider_start_time
142+
end
143+
144+
def __with_preserved_spider_time_and_beat(&blk)
145+
time = __get_spider_time
146+
beat = __get_spider_beat
147+
blk.call
148+
__change_spider_time_and_beat!(time, beat)
149+
end
150+
### End - Spider Time Management functions
151+
###
152+
153+
92154
def __register_internal_cue_event(address, args)
93155
p = 0
94156
d = 0
@@ -735,8 +797,8 @@ def __set_default_system_thread_locals!
735797
end
736798

737799
def __set_default_user_thread_locals!
800+
__reset_spider_bpm!
738801
__thread_locals.set :sonic_pi_spider_arg_bpm_scaling, true
739-
__change_spider_sleep_mul!(1.0)
740802
__thread_locals.set :sonic_pi_spider_new_thread_random_gen_idx, 0
741803
__system_thread_locals.set(:sonic_pi_spider_thread_priority, 0)
742804
end
@@ -774,9 +836,7 @@ def __spider_eval(code, info={})
774836
now = Time.now.freeze
775837
start_t_prom.deliver! now
776838
## fix this for link
777-
__change_spider_time! now
778-
__system_thread_locals.set :sonic_pi_spider_start_time, now
779-
__change_spider_beat! 0
839+
__reset_spider_time_and_beat!
780840
if num_running_jobs == 1
781841
@global_start_time = now
782842
# Force a GC collection before we start making music!
@@ -888,37 +948,8 @@ def __gui_cue_log_idxs
888948
@gui_cue_log_idxs
889949
end
890950

891-
def __change_spider_time!(new_vt)
892-
__system_thread_locals.set :sonic_pi_spider_time, new_vt.freeze
893-
end
894-
895-
def __change_spider_sleep_mul!(new_sleep_mul)
896-
__system_thread_locals.set(:sonic_pi_spider_sleep_mul, new_sleep_mul)
897-
end
898-
899-
def __change_spider_beat!(new_beat)
900-
__system_thread_locals.set(:sonic_pi_spider_beat, new_beat)
901-
end
902-
903-
def __get_spider_time
904-
__system_thread_locals.get(:sonic_pi_spider_time)
905-
end
906-
907-
def __get_spider_schedule_time
908-
__system_thread_locals.get(:sonic_pi_spider_time) + current_sched_ahead_time
909-
end
910-
911-
def __get_spider_sleep_mul
912-
__system_thread_locals.get(:sonic_pi_spider_sleep_mul)
913-
end
914951

915-
def __get_spider_bpm
916-
60.0 / __get_spider_sleep_mul
917-
end
918952

919-
def __get_spider_beat
920-
__system_thread_locals.get(:sonic_pi_spider_beat)
921-
end
922953

923954

924955

app/server/ruby/lib/sonicpi/scsynthexternal.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ def send(*all_args)
5252
def send_at(ts, *all_args)
5353
address, *args = *all_args
5454
if osc_debug_mode
55-
56-
if (a = __get_spider_time) && (b = __system_thread_locals.get(:sonic_pi_spider_start_time))
55+
if (a = __get_spider_time) && (b = __get_spider_start_time)
5756
vt = a - b
58-
elsif st = __system_thread_locals.get(:sonic_pi_spider_start_time)
57+
elsif st = __get_spider_start_time
5958
vt = ts - st
6059
else
6160
vt = -1

app/server/ruby/test/setup_test.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,8 @@ def run(&blk)
100100
__system_thread_locals.set :sonic_pi_spider_silent, silent
101101
__system_thread_locals.set :sonic_pi_spider_job_info, info
102102

103-
__change_spider_time! now
104-
__change_spider_beat! 0
105-
__system_thread_locals.set :sonic_pi_spider_start_time, now
103+
__reset_spider_time_and_beat!
104+
106105
__system_thread_locals.set_local :sonic_pi_local_spider_delayed_messages, []
107106

108107
__set_default_system_thread_locals!

0 commit comments

Comments
 (0)