Attempt at better managing lifecycle
This commit is contained in:
parent
56c5ee15e0
commit
671f5cae12
|
@ -188,7 +188,6 @@ radius = 0.00197651
|
|||
height = 0.0197651
|
||||
|
||||
[node name="RiggedHand" type="Node3D" node_paths=PackedStringArray("origin_hands", "rigged_hands", "spawner")]
|
||||
process_mode = 4
|
||||
script = ExtResource("1_58k8d")
|
||||
origin_hands = NodePath("HandTracking/Debug/OriginHands")
|
||||
rigged_hands = NodePath("Scene/XRToolsHands")
|
||||
|
@ -856,6 +855,7 @@ update_mode = 1
|
|||
[node name="HandTracking" type="Node3D" parent="."]
|
||||
|
||||
[node name="UltraleapHandTracking" type="UltraleapHandTracking" parent="HandTracking"]
|
||||
startup_enable_images = false
|
||||
script = ExtResource("1_r2upn")
|
||||
|
||||
[node name="UltraleapDeviceNode" type="UltraleapDeviceNode" parent="HandTracking"]
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
@tool
|
||||
extends UltraleapHandTracking
|
||||
|
||||
func _ready():
|
||||
start()
|
||||
|
||||
func on_tracking_mode_request(new_tracking_mode):
|
||||
set_tracking_mode(new_tracking_mode)
|
||||
|
|
|
@ -26,12 +26,41 @@
|
|||
using namespace godot;
|
||||
|
||||
UltraleapHandTracking::~UltraleapHandTracking() {
|
||||
if (_isRunning) {
|
||||
_isRunning = false;
|
||||
UtilityFunctions::print("Destroying UltraleapHandTracking");
|
||||
|
||||
if (is_running) {
|
||||
UtilityFunctions::print("Stopping the tracking thread");
|
||||
keep_running = false;
|
||||
messageLoop.join();
|
||||
}
|
||||
LeapCloseConnection(connectionHandle);
|
||||
LeapDestroyConnection(connectionHandle);
|
||||
|
||||
dispose_ultraleap();
|
||||
|
||||
#if ANDROID_ENABLED
|
||||
binder = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void UltraleapHandTracking::dispose_ultraleap() {
|
||||
if (opened && connectionHandle) {
|
||||
UtilityFunctions::print("Closing the connection");
|
||||
LeapCloseConnection(connectionHandle);
|
||||
opened = false;
|
||||
}
|
||||
|
||||
if (connectionHandle) {
|
||||
UtilityFunctions::print("Destroying the connection");
|
||||
LeapDestroyConnection(connectionHandle);
|
||||
connectionHandle = NULL;
|
||||
}
|
||||
|
||||
#if ANDROID_ENABLED
|
||||
if (binder != NULL) {
|
||||
if (binder->call("IsBound")) {
|
||||
binder->call("Unbind");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void UltraleapHandTracking::_bind_methods() {
|
||||
|
@ -43,8 +72,10 @@ void UltraleapHandTracking::_bind_methods() {
|
|||
);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("start"), &UltraleapHandTracking::start);
|
||||
ClassDB::bind_method(D_METHOD("stop"), &UltraleapHandTracking::stop);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_connected"), &UltraleapHandTracking::is_connected);
|
||||
ClassDB::bind_method(D_METHOD("is_started"), &UltraleapHandTracking::is_started);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_last_frame", "last_frame"), &UltraleapHandTracking::set_last_frame);
|
||||
ClassDB::bind_method(D_METHOD("get_last_frame"), &UltraleapHandTracking::get_last_frame);
|
||||
|
@ -64,6 +95,12 @@ void UltraleapHandTracking::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_service_port", "service_port"), &UltraleapHandTracking::set_service_port);
|
||||
ClassDB::bind_method(D_METHOD("get_service_port"), &UltraleapHandTracking::get_service_port);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_autostart", "enable"), &UltraleapHandTracking::set_autostart);
|
||||
ClassDB::bind_method(D_METHOD("get_autostart"), &UltraleapHandTracking::get_autostart);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_enable_images", "enable"), &UltraleapHandTracking::set_enable_images);
|
||||
ClassDB::bind_method(D_METHOD("get_enable_images"), &UltraleapHandTracking::get_enable_images);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_images_policy", "value"), &UltraleapHandTracking::set_images_policy);
|
||||
ClassDB::bind_method(D_METHOD("set_allow_pause_resume_policy", "value"), &UltraleapHandTracking::set_allow_pause_resume_policy);
|
||||
|
||||
|
@ -131,6 +168,32 @@ void UltraleapHandTracking::_bind_methods() {
|
|||
"get_service_port"
|
||||
);
|
||||
|
||||
ClassDB::add_property_group(
|
||||
"UltraleapHandTracking",
|
||||
"Startup",
|
||||
"startup"
|
||||
);
|
||||
|
||||
ClassDB::add_property(
|
||||
"UltraleapHandTracking",
|
||||
PropertyInfo(
|
||||
Variant::BOOL,
|
||||
"startup_autostart"
|
||||
),
|
||||
"set_autostart",
|
||||
"get_autostart"
|
||||
);
|
||||
|
||||
ClassDB::add_property(
|
||||
"UltraleapHandTracking",
|
||||
PropertyInfo(
|
||||
Variant::BOOL,
|
||||
"startup_enable_images"
|
||||
),
|
||||
"set_enable_images",
|
||||
"get_enable_images"
|
||||
);
|
||||
|
||||
// SIGNALS
|
||||
|
||||
ClassDB::add_signal(
|
||||
|
@ -224,19 +287,32 @@ void UltraleapHandTracking::_bind_methods() {
|
|||
}
|
||||
|
||||
void UltraleapHandTracking::start() {
|
||||
if (started) {
|
||||
UtilityFunctions::print("The tracking is already started");
|
||||
return;
|
||||
}
|
||||
|
||||
UtilityFunctions::print("Starting the tracking");
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
if (Engine::get_singleton()->has_singleton("UltraleapBinder")) {
|
||||
ALOGI("We'll try to use the binder");
|
||||
Object* binder = Engine::get_singleton()->get_singleton("UltraleapBinder");
|
||||
if (binder == NULL) {
|
||||
ALOGI("Couldn't get the service binder, stopping");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!binder->call("IsBound")) {
|
||||
ALOGI("Binding to the service");
|
||||
binder->call("Bind");
|
||||
while (!binder->call("IsBound")) {
|
||||
ALOGI("Not bound yet");
|
||||
}
|
||||
}
|
||||
|
||||
// This will freeze the app if the service doesn't bind
|
||||
while (!binder->call("IsBound")) {
|
||||
ALOGI("Not bound yet");
|
||||
}
|
||||
#endif
|
||||
|
||||
started = true;
|
||||
|
||||
LEAP_CONNECTION_CONFIG config;
|
||||
|
||||
// Set connection to multi-device aware
|
||||
|
@ -248,14 +324,14 @@ void UltraleapHandTracking::start() {
|
|||
if(connectionHandle || LeapCreateConnection(&config, &connectionHandle) == eLeapRS_Success) {
|
||||
eLeapRS result = LeapOpenConnection(connectionHandle);
|
||||
if(result == eLeapRS_Success) {
|
||||
_isRunning = true;
|
||||
opened = true;
|
||||
|
||||
{
|
||||
LEAP_ALLOCATOR allocator = { allocate, deallocate, NULL };
|
||||
LeapSetAllocator(connectionHandle, &allocator);
|
||||
}
|
||||
|
||||
if (!Engine::get_singleton()->is_editor_hint()) {
|
||||
if (!Engine::get_singleton()->is_editor_hint() && enable_images) {
|
||||
LeapSetPolicyFlags(connectionHandle, eLeapPolicyFlag_Images, 0);
|
||||
}
|
||||
|
||||
|
@ -265,6 +341,35 @@ void UltraleapHandTracking::start() {
|
|||
}
|
||||
}
|
||||
|
||||
void UltraleapHandTracking::stop() {
|
||||
if (!started) {
|
||||
UtilityFunctions::print("Tracking already stopped");
|
||||
return;
|
||||
}
|
||||
|
||||
UtilityFunctions::print("Trying to stop tracking...");
|
||||
|
||||
if (keep_running) {
|
||||
UtilityFunctions::print("Turning off flag of thread");
|
||||
keep_running = false;
|
||||
}
|
||||
|
||||
// If the polling thread is still alive, we defer calling the stop function
|
||||
// again on the next frame, and this until it's dead, then we will clean
|
||||
// the connection
|
||||
if (is_running) {
|
||||
call_deferred("stop");
|
||||
return;
|
||||
}
|
||||
|
||||
messageLoop.join();
|
||||
dispose_ultraleap();
|
||||
|
||||
started = false;
|
||||
|
||||
UtilityFunctions::print("Tracking stopped!");
|
||||
}
|
||||
|
||||
void UltraleapHandTracking::handle_connection_event(const LEAP_CONNECTION_EVENT *evt) {
|
||||
events.push({ "connection_status_changed", true });
|
||||
connected = true;
|
||||
|
@ -282,7 +387,10 @@ void UltraleapHandTracking::serviceMessageLoop() {
|
|||
LEAP_CONNECTION_MESSAGE msg;
|
||||
eLeapRS result;
|
||||
|
||||
while (_isRunning) {
|
||||
keep_running = true;
|
||||
is_running = true;
|
||||
|
||||
while (keep_running) {
|
||||
result = LeapPollConnection(connectionHandle, 100, &msg);
|
||||
|
||||
if (result != eLeapRS_Success && result != eLeapRS_Timeout) {
|
||||
|
@ -291,7 +399,7 @@ void UltraleapHandTracking::serviceMessageLoop() {
|
|||
}
|
||||
|
||||
// Polling may have taken some time, re-check exit condition
|
||||
if (!_isRunning) {
|
||||
if (!keep_running) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -358,6 +466,8 @@ void UltraleapHandTracking::serviceMessageLoop() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
is_running = false;
|
||||
}
|
||||
|
||||
UltraleapTypes::TrackingMode UltraleapHandTracking::get_tracking_mode() {
|
||||
|
@ -653,6 +763,7 @@ Ref<UltraleapDevice> UltraleapHandTracking::create_device(LEAP_DEVICE_REF ref) {
|
|||
}
|
||||
|
||||
void UltraleapHandTracking::_notification(int p_what) {
|
||||
//UtilityFunctions::print(p_what);
|
||||
if (p_what == Node::NOTIFICATION_ENTER_TREE) {
|
||||
set_process_internal(true);
|
||||
}
|
||||
|
@ -663,6 +774,19 @@ void UltraleapHandTracking::_notification(int p_what) {
|
|||
events.pop();
|
||||
}
|
||||
}
|
||||
else if (p_what == Node::NOTIFICATION_READY) {
|
||||
#if ANDROID_ENABLED
|
||||
// Get and store the binder
|
||||
if (Engine::get_singleton()->has_singleton("UltraleapBinder")) {
|
||||
binder = Engine::get_singleton()->get_singleton("UltraleapBinder");
|
||||
}
|
||||
#endif
|
||||
|
||||
// For now we will also start automatically if we're in the editor, so that we can have data for tool scripts
|
||||
if (autostart || Engine::get_singleton()->is_editor_hint()) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String UltraleapHandTracking::generate_connection_payload() {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <LeapC.h>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <atomic>
|
||||
|
||||
#include "types.h"
|
||||
#include "frame.h"
|
||||
|
@ -29,6 +30,7 @@ public:
|
|||
~UltraleapHandTracking();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
UltraleapTypes::TrackingMode default_tracking_mode = UltraleapTypes::TrackingMode::Desktop;
|
||||
|
||||
|
@ -46,6 +48,9 @@ public:
|
|||
String service_ip = String("127.0.0.1");
|
||||
uint32_t service_port = 12345;
|
||||
|
||||
bool autostart = true;
|
||||
bool enable_images = true;
|
||||
|
||||
Variant get_last_frame();
|
||||
void set_last_frame(Variant value) { return; }
|
||||
|
||||
|
@ -64,7 +69,14 @@ public:
|
|||
Variant get_service_port() { return service_port; }
|
||||
void set_service_port(Variant value) { service_port = value; }
|
||||
|
||||
Variant get_autostart() { return autostart; }
|
||||
void set_autostart(Variant value) { autostart = value; }
|
||||
|
||||
Variant get_enable_images() { return enable_images; }
|
||||
void set_enable_images(Variant value) { enable_images = value; }
|
||||
|
||||
bool is_connected() { return connected; }
|
||||
bool is_started() { return started; }
|
||||
|
||||
// Policy setters
|
||||
void set_images_policy(bool value);
|
||||
|
@ -89,12 +101,18 @@ protected:
|
|||
|
||||
private:
|
||||
bool _isRunning = false;
|
||||
|
||||
std::atomic<bool> is_running = false;
|
||||
std::atomic<bool> keep_running = false;
|
||||
|
||||
LEAP_CONNECTION connectionHandle = NULL;
|
||||
LEAP_CLOCK_REBASER clockSynchronizer;
|
||||
|
||||
std::thread messageLoop;
|
||||
|
||||
bool connected = false;
|
||||
bool started = false; /* The whole thing is started */
|
||||
bool opened = false; /* Indicate an opened connection */
|
||||
bool connected = false; /* We have confirmed connection */
|
||||
|
||||
Ref<UltraleapDevice> primary_device = NULL;
|
||||
|
||||
|
@ -105,6 +123,7 @@ private:
|
|||
std::queue<event> events;
|
||||
|
||||
void serviceMessageLoop();
|
||||
void dispose_ultraleap();
|
||||
|
||||
void handle_tracking_event(const LEAP_TRACKING_EVENT* event, uint32_t device_id);
|
||||
void handle_image_event(const LEAP_IMAGE_EVENT* event, uint32_t device_id);
|
||||
|
@ -126,6 +145,10 @@ private:
|
|||
Ref<UltraleapDevice> create_device(LEAP_DEVICE_REF ref);
|
||||
|
||||
uint32_t policy_flags = UINT32_MAX;
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
Object *binder = NULL;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue