9
9
10
10
module SonicPi
11
11
class MockStudio
12
+
13
+ end
14
+
15
+ class MockTauAPI
16
+ def tau_ready?
17
+ true
18
+ end
19
+
20
+ def block_until_tau_ready!
21
+ end
22
+
23
+ def link_current_time
24
+ Time . now . to_i
25
+ end
26
+
27
+ def link_current_time_and_beat ( quantise_beat = true )
28
+ [ Time . now . to_i , 0 ]
29
+ end
30
+
31
+ def link_temp
32
+ 120
33
+ end
34
+
35
+ def link_is_enabled?
36
+ true
37
+ end
38
+
39
+ def link_num_peers
40
+ 0
41
+ end
42
+
43
+ def link_get_beat_at_time ( time , quantum = 4 )
44
+ 0
45
+ end
46
+
47
+ def link_get_clock_time_at_beat ( beat , quantum = 4 )
48
+ Time . now . to_i
49
+ end
50
+
51
+ def link_get_beat_at_clock_time ( clock_time , quantum = 4 )
52
+ 0
53
+ end
12
54
end
13
55
14
56
class MockLang
@@ -21,64 +63,146 @@ class MockLang
21
63
include ActiveSupport
22
64
def initialize
23
65
@mod_sound_studio = MockStudio . new
24
-
25
66
@msg_queue = Queue . new
26
67
__set_default_user_thread_locals!
27
-
28
-
29
68
@system_init_thread_id = ThreadId . new ( -1 )
30
69
31
-
32
70
@settings = Config ::Settings . new ( "/bogus/path/to/default/to/empty/settings.txt" )
33
71
@version = Version . new ( 0 , 0 , 0 , "test" )
34
72
@server_version = Version . new ( 1 , 0 , 0 , "final" )
73
+
74
+
35
75
@life_hooks = LifeCycleHooks . new
36
- @msg_queue = Queue . new
37
76
@cue_events = IncomingEvents . new
38
- @sync_counter = Counter . new
39
77
@job_counter = Counter . new ( -1 ) # Start counting jobs from 0
40
78
@job_subthreads = { }
41
79
@job_main_threads = { }
42
80
@named_subthreads = { }
43
81
@job_subthread_mutex = Mutex . new
82
+ @osc_cue_server_mutex = Mutex . new
44
83
@user_jobs = Jobs . new
45
- @user_methods = [ ]
46
84
@global_start_time = Time . now
47
85
@session_id = SecureRandom . uuid
48
86
@snippets = { }
87
+ @system_state = EventHistory . new
88
+ @user_state = EventHistory . new
89
+ @event_history = EventHistory . new
90
+ @system_init_thread_id = ThreadId . new ( -1 )
49
91
@gui_cue_log_idxs = Counter . new
50
- @system_state = EventHistory . new ( @job_subthreads , @job_subthread_mutex )
51
- @user_state = EventHistory . new ( @job_subthreads , @job_subthread_mutex )
52
- @event_history = EventHistory . new ( @job_subthreads , @job_subthread_mutex )
53
- @system_state . set 0 , 0 , @system_init_thread_id , 0 , 0 , 60 , :sched_ahead_time , 0.5
54
- @register_cue_event_lambda = lambda do |t , p , i , d , b , m , address , args , sched_ahead_time = 0 |
92
+ @gui_heartbeats = { }
93
+ @gui_last_heartbeat = nil
55
94
56
- address , _sym = *address if address . is_a? ( Array )
95
+ @register_cue_event_lambda = lambda do |t , p , i , d , b , m , address , args , sched_ahead_time = 0 |
96
+ t = t . to_r
97
+ sym = nil
98
+ address , sym = *address if address . is_a? ( Array )
57
99
58
100
gui_log_id = @gui_cue_log_idxs . next
59
- a = args . freeze
60
-
61
- @event_history . set ( t , p , i , d , b , m , address . freeze , a )
101
+ args = args . __sp_make_thread_safe
102
+ address = address . to_s . freeze
103
+ @event_history . set ( t , p , i , d , b , m , address , args )
62
104
@cue_events . async_event ( "/spider_thread_sync/#{ address } " , {
63
105
:time => t ,
64
- :cue_splat_map_or_arr => a ,
106
+ :cue_splat_map_or_arr => args ,
65
107
:cue => address } )
66
108
67
109
sched_ahead_sync_t = t + sched_ahead_time
68
- sleep_time = sched_ahead_sync_t . to_f - Time . now . to_f
110
+
111
+ sleep_time = sched_ahead_sync_t - Time . now . to_r
69
112
if sleep_time > 0
70
113
Thread . new do
71
- Kernel . sleep ( sleep_time ) if sleep_time > 0
72
- __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => address , :args => a . inspect } )
114
+ Kernel . sleep ( sleep_time )
115
+ __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => address , :args => args . inspect } )
116
+ __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => sym , :args => args . inspect } ) if sym
73
117
end
74
118
else
75
- __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => address , :args => a . inspect } )
119
+ __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => address , :args => args . inspect } )
120
+ __msg_queue . push ( { :type => :incoming , :time => t . to_s , :id => gui_log_id , :address => sym , :args => args . inspect } ) if sym
121
+ end
122
+ end
123
+
124
+ external_osc_cue_handler = lambda do |time , ip , port , address , args |
125
+ address = "/#{ address } " unless address . start_with? ( "/" )
126
+ address = "/osc:#{ host } :#{ port } #{ address } "
127
+ p = 0
128
+ d = 0
129
+ b = 0
130
+ m = 60
131
+ @register_cue_event_lambda . call ( Time . now , p , @system_init_thread_id , d , b , m , address , args , 0 )
132
+ end
133
+
134
+ internal_cue_handler = lambda do |path , args |
135
+ p = 0
136
+ d = 0
137
+ b = 0
138
+ m = 60
139
+ @register_cue_event_lambda . call ( Time . now , p , @system_init_thread_id , d , b , m , address , args , 0 )
140
+ end
141
+
142
+ updated_midi_ins_handler = lambda do |ins |
143
+ desc = ins . join ( "\n " )
144
+ __msg_queue . push ( { :type => :midi_in_ports , :val => desc } )
145
+ end
146
+
147
+ updated_midi_outs_handler = lambda do |outs |
148
+ desc = outs . join ( "\n " )
149
+ __msg_queue . push ( { :type => :midi_out_ports , :val => desc } )
150
+ end
151
+
152
+ # @tau_api = TauAPI.new(ports,
153
+ # {
154
+ # external_osc_cue: external_osc_cue_handler,
155
+ # internal_cue: internal_cue_handler,
156
+ # updated_midi_ins: updated_midi_ins_handler,
157
+ # updated_midi_outs: updated_midi_outs_handler
158
+ # })
159
+
160
+ @tau_api = MockTauAPI . new
161
+
162
+ begin
163
+ @gitsave = GitSave . new ( Paths . project_path )
164
+ rescue
165
+ @gitsave = nil
166
+ end
167
+
168
+ @save_queue = SizedQueue . new ( 20 )
169
+
170
+ @save_t = Thread . new do
171
+ __system_thread_locals . set_local ( :sonic_pi_local_thread_group , :save_loop )
172
+ Kernel . loop do
173
+ event = @save_queue . pop
174
+ id , content = *event
175
+ filename = id + '.spi'
176
+ path = File . expand_path ( "#{ Paths . project_path } /#{ filename } " )
177
+ content = filter_for_save ( content )
178
+ begin
179
+ File . open ( path , 'w' ) { |f | f . write ( content ) }
180
+ @gitsave . save! ( filename , content , "#{ @version } -- #{ @session_id } -- " )
181
+ rescue Exception => e
182
+ log "Exception saving buffer #{ filename } :\n #{ e . inspect } "
183
+ ##TODO: remove this and ensure that git saving actually works
184
+ ##instead of cowardly hiding the issue!
185
+ end
76
186
end
187
+ end
188
+
189
+ @system_state . set 0 , 0 , ThreadId . new ( -2 ) , 0 , 0 , 60 , :sched_ahead_time , default_sched_ahead_time
190
+
191
+ __info "Welcome to Sonic Pi #{ version } " , 1
77
192
193
+ __info "Running on Ruby v#{ RUBY_VERSION } "
194
+
195
+ __info "Initialised Erlang OSC Scheduler"
196
+
197
+ if safe_mode?
198
+ __info "!!WARNING!! - file permissions issue:\n Unable to write to folder #{ Paths . home_dir_path } \n Booting in SAFE MODE.\n Buffer auto-saving is disabled, please save your work manually." , 1
78
199
end
79
200
201
+ log "Unable to initialise git repo at #{ Paths . project_path } " unless @gitsave
202
+ load_snippets ( Paths . snippets_path , true )
80
203
end
81
204
205
+
82
206
def __error ( e , m = nil )
83
207
raise e
84
208
end
@@ -92,7 +216,7 @@ def run(&blk)
92
216
job = Thread . new do
93
217
Thread . current . abort_on_exception = true
94
218
95
- reg_job 0 , Thread . current
219
+ register_job! 0 , Thread . current
96
220
__system_thread_locals . set_local :sonic_pi_local_thread_group , "job-#{ id } "
97
221
__system_thread_locals . set_local :sonic_pi_spider_thread_id_path , ThreadId . new ( id )
98
222
__system_thread_locals . set :sonic_pi_spider_job_id , id
0 commit comments