Fixed the client icon stucking
This commit is contained in:
		
							parent
							
								
									0a6c68f940
								
							
						
					
					
						commit
						aa19e52978
					
				| @ -77,12 +77,12 @@ void VoiceClientWrap::do_wrap(const v8::Local<v8::Object> &object) { | ||||
| 	handle->on_state_changed = [&]{ this->call_state_changed(); }; | ||||
| 
 | ||||
| 	this->call_state_changed = Nan::async_callback([&]{ | ||||
| 		Nan::HandleScope scope; | ||||
| 		this->_call_state_changed(); | ||||
| 		Nan::HandleScope scope{}; | ||||
| 		this->call_state_changed_(); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| void VoiceClientWrap::_call_state_changed() { | ||||
| void VoiceClientWrap::call_state_changed_() { | ||||
| 	auto handle = this->_handle.lock(); | ||||
| 	if(!handle) { | ||||
| 		log_warn(category::voice_connection, tr("State changed on invalid handle!")); | ||||
| @ -90,23 +90,25 @@ void VoiceClientWrap::_call_state_changed() { | ||||
| 	} | ||||
| 
 | ||||
| 	auto state = handle->state(); | ||||
| 	auto call_playback_callback = state == VoiceClient::state::playing && !this->_currently_playing; | ||||
| 	auto call_stopped_callback = state == VoiceClient::state::stopped && this->_currently_playing; | ||||
| 
 | ||||
| 	if(state == VoiceClient::state::stopped) | ||||
| 		this->_currently_playing = false; | ||||
| 	if(state == VoiceClient::state::playing) | ||||
| 		this->_currently_playing = true; | ||||
| 
 | ||||
| 	if(call_playback_callback) { | ||||
| 		auto callback = Nan::Get(this->handle(), Nan::New<v8::String>("callback_playback").ToLocalChecked()).ToLocalChecked(); | ||||
| 		if(callback->IsFunction()) | ||||
| 			callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr); | ||||
| 	const auto was_playing = this->currently_playing_; | ||||
| 	if(state == VoiceClient::state::stopped) { | ||||
| 		this->currently_playing_ = false; | ||||
| 	} else if(state == VoiceClient::state::playing) { | ||||
| 		this->currently_playing_ = true; | ||||
| 	} | ||||
| 	if(call_stopped_callback) { | ||||
| 
 | ||||
| 	if(!was_playing && this->currently_playing_) { | ||||
| 		auto callback = Nan::Get(this->handle(), Nan::New<v8::String>("callback_playback").ToLocalChecked()).ToLocalChecked(); | ||||
| 		if(callback->IsFunction()) { | ||||
| 			(void) callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr); | ||||
| 		} | ||||
| 	} | ||||
| 	if(was_playing && !this->currently_playing_) { | ||||
| 		auto callback = Nan::Get(this->handle(), Nan::New<v8::String>("callback_stopped").ToLocalChecked()).ToLocalChecked(); | ||||
| 		if(callback->IsFunction()) | ||||
| 			callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr); | ||||
| 		if(callback->IsFunction()) { | ||||
| 			(void) callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	auto callback = Nan::Get(this->handle(), Nan::New<v8::String>("callback_state_changed").ToLocalChecked()).ToLocalChecked(); | ||||
| @ -114,7 +116,7 @@ void VoiceClientWrap::_call_state_changed() { | ||||
| 		v8::Local<v8::Value> argv[1] = { | ||||
| 			Nan::New<v8::Number>(state) | ||||
| 		}; | ||||
| 		callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 1, argv); | ||||
| 		(void) callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 1, argv); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -207,16 +209,16 @@ NAN_METHOD(VoiceClientWrap::_get_stream) { | ||||
| 
 | ||||
| VoiceClientWrap::VoiceClientWrap(const std::shared_ptr<VoiceClient>& client) : _handle(client) { } | ||||
| 
 | ||||
| VoiceClientWrap::~VoiceClientWrap() {} | ||||
| VoiceClientWrap::~VoiceClientWrap() = default; | ||||
| 
 | ||||
| VoiceClient::VoiceClient(const std::shared_ptr<VoiceConnection>&, uint16_t client_id) : client_id_(client_id) { | ||||
| 	this->execute_lock_timeout = std::chrono::microseconds{500}; | ||||
| } | ||||
| 
 | ||||
| VoiceClient::~VoiceClient() { | ||||
| 	if(v8::Isolate::GetCurrent()) | ||||
| 	if(v8::Isolate::GetCurrent()) { | ||||
| 		this->finalize_js_object(); | ||||
| 	else { | ||||
| 	} else { | ||||
| 		assert(this->js_handle_.IsEmpty()); | ||||
| 	} | ||||
| 
 | ||||
| @ -242,28 +244,37 @@ void VoiceClient::initialize() { | ||||
|         client->output_source->set_max_buffered_samples((size_t) ceil(client->output_source->sample_rate * 0.5)); | ||||
|         client->output_source->set_min_buffered_samples((size_t) ceil(client->output_source->sample_rate * 0.04)); | ||||
| 
 | ||||
|         const auto client_ptr = &*client; | ||||
|         client->output_source->on_underflow = [client_ptr](size_t sample_count){ /* this callback will never be called when the client has been deallocated */ | ||||
|             if(client_ptr->state_ == state::stopping) { | ||||
|                 client_ptr->set_state(state::stopped); | ||||
|             } else if(client_ptr->state_ != state::stopped) { | ||||
|                 if(client_ptr->_last_received_packet + chrono::seconds{1} < chrono::system_clock::now()) { | ||||
|                     client_ptr->set_state(state::stopped); | ||||
|                     log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples and not received any data for one second. Stopping replay."), client_ptr->client_id_, sample_count); | ||||
|         client->output_source->on_underflow = [weak_this](size_t sample_count){ /* this callback will never be called when the client has been deallocated */ | ||||
| 			auto client = weak_this.lock(); | ||||
| 			if(!client) { | ||||
| 				return false; | ||||
| 			} | ||||
| 
 | ||||
|             if(client->state_ == state::stopping) { | ||||
| 				client->set_state(state::stopped); | ||||
|             } else if(client->state_ != state::stopped) { | ||||
|                 if(client->_last_received_packet + chrono::seconds{1} < chrono::system_clock::now()) { | ||||
| 					client->set_state(state::stopped); | ||||
|                     log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples and not received any data for one second. Stopping replay."), client->client_id_, sample_count); | ||||
|                 } else { | ||||
|                     if(client_ptr->state_ != state::buffering) { | ||||
|                         log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples. Buffer again."), client_ptr->client_id_, sample_count); | ||||
|                         client_ptr->set_state(state::buffering); | ||||
|                     if(client->state_ != state::buffering) { | ||||
|                         log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples. Buffer again."), client->client_id_, sample_count); | ||||
| 						client->set_state(state::buffering); | ||||
|                     } | ||||
| 
 | ||||
|                     audio::decode_event_loop->schedule(static_pointer_cast<event::EventEntry>(client_ptr->ref())); | ||||
|                     audio::decode_event_loop->schedule(static_pointer_cast<event::EventEntry>(client)); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return false; | ||||
|         }; | ||||
|         client->output_source->on_overflow = [client_ptr](size_t count){ | ||||
|             log_warn(category::audio, tr("Client {} has a audio buffer overflow of {}."), client_ptr->client_id_, count); | ||||
|         client->output_source->on_overflow = [weak_this](size_t count){ | ||||
| 			auto client = weak_this.lock(); | ||||
| 			if(!client) { | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
|             log_warn(category::audio, tr("Client {} has a audio buffer overflow of {}."), client->client_id_, count); | ||||
|         }; | ||||
|     }); | ||||
| } | ||||
| @ -281,7 +292,7 @@ void VoiceClient::initialize_js_object() { | ||||
| 
 | ||||
| 	auto object_wrap = new VoiceClientWrap(this->ref()); | ||||
| 	auto object = Nan::NewInstance(Nan::New(VoiceClientWrap::constructor()), 0, nullptr).ToLocalChecked(); | ||||
| 	Nan::TryCatch tc; | ||||
| 	Nan::TryCatch tc{}; | ||||
| 	object_wrap->do_wrap(object); | ||||
| 	if(tc.HasCaught()) { | ||||
| 		tc.ReThrow(); | ||||
|  | ||||
| @ -181,8 +181,8 @@ namespace tc::connection { | ||||
|                 return my_constructor; | ||||
|             } | ||||
| 
 | ||||
|             VoiceClientWrap(const std::shared_ptr<VoiceClient>&); | ||||
|             virtual ~VoiceClientWrap(); | ||||
|             explicit VoiceClientWrap(const std::shared_ptr<VoiceClient>&); | ||||
|             ~VoiceClientWrap() override; | ||||
| 
 | ||||
|             void do_wrap(const v8::Local<v8::Object>&); | ||||
|         private: | ||||
| @ -194,8 +194,8 @@ namespace tc::connection { | ||||
| 
 | ||||
|             std::weak_ptr<VoiceClient> _handle; | ||||
| 
 | ||||
|             bool _currently_playing = false; | ||||
|             bool currently_playing_{false}; | ||||
|             Nan::callback_t<> call_state_changed; | ||||
|             void _call_state_changed(); | ||||
|             void call_state_changed_(); | ||||
|     }; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user