@@ -35,6 +35,7 @@ bool globalCallback::worker_stop = true;
3535uint32_t globalCallback::sleepIntervalMS = 50 ;
3636std::thread *globalCallback::worker_thread = nullptr ;
3737Napi::ThreadSafeFunction globalCallback::js_source_callback;
38+ Napi::ThreadSafeFunction globalCallback::js_transition_callback;
3839Napi::ThreadSafeFunction globalCallback::js_volmeter_callback;
3940bool globalCallback::m_all_workers_stop = false ;
4041std::mutex globalCallback::mtx_volmeters;
@@ -45,6 +46,9 @@ void globalCallback::Init(Napi::Env env, Napi::Object exports)
4546 exports.Set (Napi::String::New (env, " RegisterSourceCallback" ), Napi::Function::New (env, globalCallback::RegisterSourceCallback));
4647 exports.Set (Napi::String::New (env, " RemoveSourceCallback" ), Napi::Function::New (env, globalCallback::RemoveSourceCallback));
4748
49+ exports.Set (Napi::String::New (env, " RegisterTransitionCallback" ), Napi::Function::New (env, globalCallback::RegisterTransitionCallback));
50+ exports.Set (Napi::String::New (env, " RemoveTransitionCallback" ), Napi::Function::New (env, globalCallback::RemoveTransitionCallback));
51+
4852 exports.Set (Napi::String::New (env, " RegisterVolmeterCallback" ), Napi::Function::New (env, globalCallback::RegisterVolmeterCallback));
4953 exports.Set (Napi::String::New (env, " RemoveVolmeterCallback" ), Napi::Function::New (env, globalCallback::RemoveVolmeterCallback));
5054}
@@ -70,6 +74,21 @@ Napi::Value globalCallback::RemoveSourceCallback(const Napi::CallbackInfo &info)
7074 return info.Env ().Undefined ();
7175}
7276
77+ Napi::Value globalCallback::RegisterTransitionCallback (const Napi::CallbackInfo &info)
78+ {
79+ Napi::Function async_callback = info[0 ].As <Napi::Function>();
80+ js_transition_callback = Napi::ThreadSafeFunction::New (info.Env (), async_callback, " TransitionCallback" , 0 , 1 , [](Napi::Env) {});
81+
82+ return Napi::Boolean::New (info.Env (), true );
83+ }
84+
85+ Napi::Value globalCallback::RemoveTransitionCallback (const Napi::CallbackInfo &info)
86+ {
87+ js_transition_callback.Release ();
88+
89+ return info.Env ().Undefined ();
90+ }
91+
7392Napi::Value globalCallback::RegisterVolmeterCallback (const Napi::CallbackInfo &info)
7493{
7594 Napi::Function async_callback = info[0 ].As <Napi::Function>();
@@ -124,6 +143,36 @@ void globalCallback::worker()
124143 delete data;
125144 };
126145
146+ auto transitions_callback = [](Napi::Env env, Napi::Function jsCallback, TransitionInfoData *data) {
147+ try {
148+ Napi::Array result = Napi::Array::New (env, data->items .size ());
149+
150+ for (size_t i = 0 ; i < data->items .size (); i++) {
151+ Napi::Object obj = Napi::Object::New (env);
152+ obj.Set (" id" , Napi::String::New (env, data->items [i]->id ));
153+
154+ switch (data->items [i]->event ) {
155+ case TransitionInfo::START:
156+ obj.Set (" event" , Napi::String::New (env, " start" ));
157+ break ;
158+
159+ case TransitionInfo::STOP:
160+ obj.Set (" event" , Napi::String::New (env, " stop" ));
161+ break ;
162+
163+ default :
164+ // do nothing
165+ break ;
166+ }
167+
168+ result.Set (static_cast <uint32_t >(i), obj);
169+ }
170+ jsCallback.Call ({result});
171+ } catch (...) {
172+ }
173+ delete data;
174+ };
175+
127176 auto volmeter_callback = [](Napi::Env env, Napi::Function jsCallback, VolmeterDataArray *dataArray) {
128177 try {
129178 Napi::Array result = Napi::Array::New (env, dataArray->items .size ());
@@ -183,66 +232,82 @@ void globalCallback::worker()
183232 }
184233 }
185234
186- {
187- std::vector<ipc::value> response = conn->call_synchronous_helper (
188- " CallbackManager" , " GlobalQuery" , {ipc::value ((uint64_t )volmeters_ids.size ()), ipc::value (volmeters_ids)});
189- if (!response.size () || (response.size () == 1 )) {
190- goto do_sleep;
191- }
235+ std::vector<ipc::value> response = conn->call_synchronous_helper (" CallbackManager" , " GlobalQuery" ,
236+ {ipc::value ((uint64_t )volmeters_ids.size ()), ipc::value (volmeters_ids)});
237+ if (!response.size () || (response.size () == 1 )) {
238+ goto do_sleep;
239+ }
192240
193- uint32_t index = 1 ;
241+ uint32_t index = 1 ;
194242
243+ const auto sourcesSize = response[index++].value_union .ui32 ;
244+ if (sourcesSize) {
195245 SourceSizeInfoData *data = new SourceSizeInfoData{{}};
196- for (uint32_t i = 2 ; i < (response[ 1 ]. value_union . ui32 * 4 ) + 2 ; i++) {
246+ for (uint32_t i = 0 ; i < sourcesSize ; i++) {
197247 SourceSizeInfo *item = new SourceSizeInfo;
198248
199- item->name = response[i++].value_str ;
200- item->width = response[i++].value_union .ui32 ;
201- item->height = response[i++].value_union .ui32 ;
202- item->flags = response[i].value_union .ui32 ;
249+ item->name = response[index++].value_str ;
250+ item->width = response[index++].value_union .ui32 ;
251+ item->height = response[index++].value_union .ui32 ;
252+ item->flags = response[index++].value_union .ui32 ;
253+ data->items .emplace_back (item);
254+ }
255+
256+ napi_status status = js_source_callback.NonBlockingCall (data, sources_callback);
257+ if (status != napi_ok) {
258+ delete data;
259+ }
260+ }
261+
262+ const auto transitionsSize = response[index++].value_union .ui32 ;
263+ if (transitionsSize) {
264+ TransitionInfoData *data = new TransitionInfoData{{}};
265+ for (uint32_t i = 0 ; i < transitionsSize; i++) {
266+ TransitionInfo *item = new TransitionInfo;
267+
268+ item->id = response[index++].value_str ;
269+ item->event = static_cast <TransitionInfo::EventType>(response[index++].value_union .ui32 );
270+
203271 data->items .emplace_back (item);
204- index = i;
205272 }
206273
207274 if (data->items .size () > 0 ) {
208- napi_status status = js_source_callback .NonBlockingCall (data, sources_callback );
275+ napi_status status = js_transition_callback .NonBlockingCall (data, transitions_callback );
209276 if (status != napi_ok) {
210277 delete data;
211278 }
212279 }
280+ }
213281
214- index++;
215-
216- auto volmeterDataArray = new VolmeterDataArray;
217- while (volmeters_size--) {
218- VolmeterData *item = new VolmeterData{{}, {}, {}};
282+ auto volmeterDataArray = new VolmeterDataArray;
283+ while (volmeters_size--) {
284+ VolmeterData *item = new VolmeterData{{}, {}, {}};
219285
220- item->source_name = response[index++].value_str ;
286+ item->source_name = response[index++].value_str ;
221287
222- size_t channels = response[index++].value_union .i32 ;
223- bool isMuted = response[index++].value_union .i32 ;
288+ size_t channels = response[index++].value_union .i32 ;
289+ bool isMuted = response[index++].value_union .i32 ;
224290
225- if (!isMuted) {
226- item->magnitude .resize (channels);
227- item->peak .resize (channels);
228- item->input_peak .resize (channels);
229- for (size_t ch = 0 ; ch < channels; ch++) {
230- item->magnitude [ch] = response[index + ch * 3 + 0 ].value_union .fp32 ;
231- item->peak [ch] = response[index + ch * 3 + 1 ].value_union .fp32 ;
232- item->input_peak [ch] = response[index + ch * 3 + 2 ].value_union .fp32 ;
233- }
291+ if (!isMuted) {
292+ item->magnitude .resize (channels);
293+ item->peak .resize (channels);
294+ item->input_peak .resize (channels);
295+ for (size_t ch = 0 ; ch < channels; ch++) {
296+ item->magnitude [ch] = response[index + ch * 3 + 0 ].value_union .fp32 ;
297+ item->peak [ch] = response[index + ch * 3 + 1 ].value_union .fp32 ;
298+ item->input_peak [ch] = response[index + ch * 3 + 2 ].value_union .fp32 ;
299+ }
234300
235- index += static_cast <uint32_t >((3 * channels));
301+ index += static_cast <uint32_t >((3 * channels));
236302
237- volmeterDataArray->items .emplace_back (item);
238- }
303+ volmeterDataArray->items .emplace_back (item);
239304 }
305+ }
240306
241- if (js_volmeter_callback) {
242- napi_status status = js_volmeter_callback.NonBlockingCall (volmeterDataArray, volmeter_callback);
243- if (status != napi_ok) {
244- delete volmeterDataArray;
245- }
307+ if (js_volmeter_callback) {
308+ napi_status status = js_volmeter_callback.NonBlockingCall (volmeterDataArray, volmeter_callback);
309+ if (status != napi_ok) {
310+ delete volmeterDataArray;
246311 }
247312 }
248313
0 commit comments