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(); };
|
handle->on_state_changed = [&]{ this->call_state_changed(); };
|
||||||
|
|
||||||
this->call_state_changed = Nan::async_callback([&]{
|
this->call_state_changed = Nan::async_callback([&]{
|
||||||
Nan::HandleScope scope;
|
Nan::HandleScope scope{};
|
||||||
this->_call_state_changed();
|
this->call_state_changed_();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceClientWrap::_call_state_changed() {
|
void VoiceClientWrap::call_state_changed_() {
|
||||||
auto handle = this->_handle.lock();
|
auto handle = this->_handle.lock();
|
||||||
if(!handle) {
|
if(!handle) {
|
||||||
log_warn(category::voice_connection, tr("State changed on invalid 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 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)
|
const auto was_playing = this->currently_playing_;
|
||||||
this->_currently_playing = false;
|
if(state == VoiceClient::state::stopped) {
|
||||||
if(state == VoiceClient::state::playing)
|
this->currently_playing_ = false;
|
||||||
this->_currently_playing = true;
|
} else 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);
|
|
||||||
}
|
}
|
||||||
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();
|
auto callback = Nan::Get(this->handle(), Nan::New<v8::String>("callback_stopped").ToLocalChecked()).ToLocalChecked();
|
||||||
if(callback->IsFunction())
|
if(callback->IsFunction()) {
|
||||||
callback.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr);
|
(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();
|
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] = {
|
v8::Local<v8::Value> argv[1] = {
|
||||||
Nan::New<v8::Number>(state)
|
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(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) {
|
VoiceClient::VoiceClient(const std::shared_ptr<VoiceConnection>&, uint16_t client_id) : client_id_(client_id) {
|
||||||
this->execute_lock_timeout = std::chrono::microseconds{500};
|
this->execute_lock_timeout = std::chrono::microseconds{500};
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceClient::~VoiceClient() {
|
VoiceClient::~VoiceClient() {
|
||||||
if(v8::Isolate::GetCurrent())
|
if(v8::Isolate::GetCurrent()) {
|
||||||
this->finalize_js_object();
|
this->finalize_js_object();
|
||||||
else {
|
} else {
|
||||||
assert(this->js_handle_.IsEmpty());
|
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_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));
|
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 = [weak_this](size_t sample_count){ /* this callback will never be called when the client has been deallocated */
|
||||||
client->output_source->on_underflow = [client_ptr](size_t sample_count){ /* this callback will never be called when the client has been deallocated */
|
auto client = weak_this.lock();
|
||||||
if(client_ptr->state_ == state::stopping) {
|
if(!client) {
|
||||||
client_ptr->set_state(state::stopped);
|
return false;
|
||||||
} 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);
|
if(client->state_ == state::stopping) {
|
||||||
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->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 {
|
} else {
|
||||||
if(client_ptr->state_ != state::buffering) {
|
if(client->state_ != state::buffering) {
|
||||||
log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples. Buffer again."), client_ptr->client_id_, sample_count);
|
log_warn(category::audio, tr("Client {} has a audio buffer underflow for {} samples. Buffer again."), client->client_id_, sample_count);
|
||||||
client_ptr->set_state(state::buffering);
|
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;
|
return false;
|
||||||
};
|
};
|
||||||
client->output_source->on_overflow = [client_ptr](size_t count){
|
client->output_source->on_overflow = [weak_this](size_t count){
|
||||||
log_warn(category::audio, tr("Client {} has a audio buffer overflow of {}."), client_ptr->client_id_, 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_wrap = new VoiceClientWrap(this->ref());
|
||||||
auto object = Nan::NewInstance(Nan::New(VoiceClientWrap::constructor()), 0, nullptr).ToLocalChecked();
|
auto object = Nan::NewInstance(Nan::New(VoiceClientWrap::constructor()), 0, nullptr).ToLocalChecked();
|
||||||
Nan::TryCatch tc;
|
Nan::TryCatch tc{};
|
||||||
object_wrap->do_wrap(object);
|
object_wrap->do_wrap(object);
|
||||||
if(tc.HasCaught()) {
|
if(tc.HasCaught()) {
|
||||||
tc.ReThrow();
|
tc.ReThrow();
|
||||||
|
@ -181,8 +181,8 @@ namespace tc::connection {
|
|||||||
return my_constructor;
|
return my_constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceClientWrap(const std::shared_ptr<VoiceClient>&);
|
explicit VoiceClientWrap(const std::shared_ptr<VoiceClient>&);
|
||||||
virtual ~VoiceClientWrap();
|
~VoiceClientWrap() override;
|
||||||
|
|
||||||
void do_wrap(const v8::Local<v8::Object>&);
|
void do_wrap(const v8::Local<v8::Object>&);
|
||||||
private:
|
private:
|
||||||
@ -194,8 +194,8 @@ namespace tc::connection {
|
|||||||
|
|
||||||
std::weak_ptr<VoiceClient> _handle;
|
std::weak_ptr<VoiceClient> _handle;
|
||||||
|
|
||||||
bool _currently_playing = false;
|
bool currently_playing_{false};
|
||||||
Nan::callback_t<> call_state_changed;
|
Nan::callback_t<> call_state_changed;
|
||||||
void _call_state_changed();
|
void call_state_changed_();
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user