34
34
35
35
#include < cstdlib>
36
36
37
- EM_ASYNC_JS (void , godot_js_camera_get_cameras, (void *context, CameraLibrary_OnGetCamerasCallback p_callback_ptr), {
38
- await GodotCamera.api .getCameras (context, p_callback_ptr);
39
- });
40
-
41
- EM_ASYNC_JS (void , godot_js_camera_get_capabilities, (void *context, const char *p_device_id_ptr, CameraLibrary_OnGetCapabilitiesCallback p_callback_ptr), {
42
- await GodotCamera.api .getCameraCapabilities (p_device_id_ptr, context, p_callback_ptr);
43
- });
44
-
45
37
CameraDriverWeb *CameraDriverWeb::singleton = nullptr ;
46
38
Array CameraDriverWeb::_camera_info_key;
47
39
@@ -53,121 +45,105 @@ CameraDriverWeb *CameraDriverWeb::get_singleton() {
53
45
return singleton;
54
46
}
55
47
56
- void CameraDriverWeb::_on_get_cameras_callback (void *context, const char *json_ptr) {
48
+ // Helper to extract 'max' from a capability dictionary or use direct value
49
+ int CameraDriverWeb::_get_max_or_direct (const Variant &p_val) {
50
+ if (p_val.get_type () == Variant::DICTIONARY) {
51
+ Dictionary d = p_val;
52
+ if (d.has (KEY_MAX)) {
53
+ return d[KEY_MAX];
54
+ }
55
+ } else if (p_val.get_type () == Variant::INT) {
56
+ return p_val;
57
+ } else if (p_val.get_type () == Variant::FLOAT) {
58
+ return static_cast <int >(p_val.operator float ());
59
+ }
60
+ return 0 ;
61
+ }
62
+
63
+ void CameraDriverWeb::_on_get_cameras_callback (void *context, void *callback, const char *json_ptr) {
57
64
if (!json_ptr) {
58
65
print_error (" CameraDriverWeb::_on_get_cameras_callback: json_ptr is null" );
59
66
return ;
60
67
}
61
68
String json_string = String::utf8 (json_ptr);
62
69
Variant json_variant = JSON::parse_string (json_string);
63
70
64
- if (json_variant.get_type () == Variant::DICTIONARY) {
65
- Dictionary json_dict = json_variant;
66
- Variant v_error = json_dict[KEY_ERROR];
67
- if (v_error.get_type () == Variant::STRING) {
68
- String error_str = v_error;
69
- ERR_PRINT (vformat (" Camera error from JS: %s" , error_str));
70
- return ;
71
- }
72
- Variant v_devices = json_dict.get (KEY_CAMERAS, Variant ());
73
- if (v_devices.get_type () != Variant::ARRAY) {
74
- ERR_PRINT (" Camera error: 'cameras' is not an array or missing." );
75
- return ;
76
- }
77
- Array devices_array = v_devices;
78
- Vector<CameraInfo> *camera_info = reinterpret_cast <Vector<CameraInfo> *>(context);
79
- camera_info->clear ();
80
- for (int i = 0 ; i < devices_array.size (); i++) {
81
- Variant device_variant = devices_array.get (i);
82
- if (device_variant.get_type () == Variant::DICTIONARY) {
83
- Dictionary device_dict = device_variant;
84
- if (device_dict.has_all (_camera_info_key)) {
85
- CameraInfo info;
86
- info.index = device_dict[KEY_INDEX];
87
- info.device_id = device_dict[KEY_ID];
88
- info.label = device_dict[KEY_LABEL];
89
- camera_info->push_back (info);
90
- } else {
91
- WARN_PRINT (" Camera info entry missing required keys (index, id, label)." );
92
- }
93
- }
94
- }
95
- } else {
71
+ if (json_variant.get_type () != Variant::DICTIONARY) {
96
72
ERR_PRINT (" CameraDriverWeb::_on_get_cameras_callback: Failed to parse JSON response or response is not a Dictionary." );
73
+ return ;
97
74
}
98
- }
99
75
100
- void CameraDriverWeb::_on_get_capabilities_callback (void *context, const char *json_ptr) {
101
- if (!json_ptr) {
102
- ERR_PRINT (" CameraDriverWeb::_on_get_capabilities_callback: json_ptr is null" );
76
+ Dictionary json_dict = json_variant;
77
+ Variant v_error = json_dict[KEY_ERROR];
78
+ if (v_error.get_type () == Variant::STRING) {
79
+ String error_str = v_error;
80
+ ERR_PRINT (vformat (" Camera error from JS: %s" , error_str));
103
81
return ;
104
82
}
105
- String json_string = String::utf8 (json_ptr);
106
- Variant json_variant = JSON::parse_string (json_string);
107
83
108
- if (json_variant.get_type () == Variant::DICTIONARY) {
109
- Dictionary json_dict = json_variant;
110
- Variant v_error = json_dict[KEY_ERROR];
111
- if (v_error.get_type () == Variant::STRING) {
112
- String error_str = v_error;
113
- ERR_PRINT (vformat (" Camera capabilities error from JS: %s" , error_str));
114
- return ;
84
+ Variant v_devices = json_dict.get (KEY_CAMERAS, Variant ());
85
+ if (v_devices.get_type () != Variant::ARRAY) {
86
+ ERR_PRINT (" Camera error: 'cameras' is not an array or missing." );
87
+ return ;
88
+ }
89
+
90
+ Array devices_array = v_devices;
91
+ Vector<CameraInfo> camera_info;
92
+ for (int i = 0 ; i < devices_array.size (); i++) {
93
+ Variant device_variant = devices_array.get (i);
94
+ if (device_variant.get_type () != Variant::DICTIONARY) {
95
+ continue ;
115
96
}
116
- Variant v_caps_data = json_dict.get (KEY_CAPABILITIES, Variant ());
97
+
98
+ Dictionary device_dict = device_variant;
99
+ if (!device_dict.has_all (_camera_info_key)) {
100
+ WARN_PRINT (" Camera info entry missing required keys (index, id, label)." );
101
+ continue ;
102
+ }
103
+
104
+ CameraInfo info;
105
+ info.index = device_dict[KEY_INDEX];
106
+ info.device_id = device_dict[KEY_ID];
107
+ info.label = device_dict[KEY_LABEL];
108
+
109
+ Variant v_caps_data = device_dict.get (KEY_CAPABILITIES, Variant ());
117
110
if (v_caps_data.get_type () != Variant::DICTIONARY) {
118
- ERR_PRINT (" Camera capabilities error: 'capabilities' data is not a dictionary or missing." );
119
- return ;
111
+ WARN_PRINT (" Camera info entry has no capabilities or capabilities are not a dictionary." );
112
+ camera_info.push_back (info);
113
+ continue ;
120
114
}
115
+
121
116
Dictionary caps_dict = v_caps_data;
122
- Vector<CapabilityInfo> *capabilities = reinterpret_cast <Vector<CapabilityInfo> *>(context);
123
- capabilities->clear ();
124
-
125
- if (caps_dict.has (KEY_WIDTH) && caps_dict.has (KEY_HEIGHT)) {
126
- Variant v_width_val = caps_dict.get (KEY_WIDTH, Variant ());
127
- Variant v_height_val = caps_dict.get (KEY_HEIGHT, Variant ());
128
- int width = 0 ;
129
- int height = 0 ;
130
-
131
- // Helper to extract 'max' from a capability dictionary or use direct value
132
- auto get_max_or_direct = [](const Variant &p_val) -> int {
133
- if (p_val.get_type () == Variant::DICTIONARY) {
134
- Dictionary d = p_val;
135
- if (d.has (KEY_MAX)) {
136
- return d[KEY_MAX];
137
- }
138
- } else if (p_val.get_type () == Variant::INT) {
139
- return p_val;
140
- } else if (p_val.get_type () == Variant::FLOAT) {
141
- return static_cast <int >(p_val.operator float ());
142
- }
143
- return 0 ;
144
- };
145
-
146
- width = get_max_or_direct (v_width_val);
147
- height = get_max_or_direct (v_height_val);
148
-
149
- if (width > 0 && height > 0 ) {
150
- CapabilityInfo info;
151
- info.width = width;
152
- info.height = height;
153
- capabilities->push_back (info);
154
- } else {
155
- WARN_PRINT (" Could not extract valid width/height from capabilities structure." );
156
- }
157
- } else {
117
+ if (!caps_dict.has (KEY_WIDTH) || !caps_dict.has (KEY_HEIGHT)) {
158
118
WARN_PRINT (" Capabilities object does not directly contain top-level width/height keys." );
119
+ camera_info.push_back (info);
120
+ continue ;
159
121
}
160
- } else {
161
- ERR_PRINT (" CameraDriverWeb::_on_get_capabilities_callback: Failed to parse JSON response or response is not a Dictionary." );
122
+
123
+ Variant v_width_val = caps_dict.get (KEY_WIDTH, Variant ());
124
+ Variant v_height_val = caps_dict.get (KEY_HEIGHT, Variant ());
125
+
126
+ int width = _get_max_or_direct (v_width_val);
127
+ int height = _get_max_or_direct (v_height_val);
128
+
129
+ if (width <= 0 || height <= 0 ) {
130
+ WARN_PRINT (" Could not extract valid width/height from capabilities structure." );
131
+ continue ;
132
+ }
133
+
134
+ CapabilityInfo capability;
135
+ capability.width = width;
136
+ capability.height = height;
137
+ info.capability = capability;
138
+ camera_info.push_back (info);
162
139
}
163
- }
164
140
165
- void CameraDriverWeb::get_cameras (Vector<CameraInfo> *r_camera_info) {
166
- godot_js_camera_get_cameras (( void *)r_camera_info, &_on_get_cameras_callback );
141
+ CameraDriverWeb_OnGetCamerasCallback on_get_cameras_callback = reinterpret_cast <CameraDriverWeb_OnGetCamerasCallback>(callback);
142
+ on_get_cameras_callback (context, const_cast <Vector<CameraInfo> &>(camera_info) );
167
143
}
168
144
169
- void CameraDriverWeb::get_capabilities (Vector<CapabilityInfo> *r_capabilities, const String &p_device_id ) {
170
- godot_js_camera_get_capabilities ( (void *)r_capabilities, p_device_id. utf8 (). get_data (), &_on_get_capabilities_callback );
145
+ void CameraDriverWeb::get_cameras ( void *context, CameraDriverWeb_OnGetCamerasCallback callback ) {
146
+ godot_js_camera_get_cameras (context, (void *)callback, &_on_get_cameras_callback );
171
147
}
172
148
173
149
void CameraDriverWeb::get_pixel_data (void *context, const String &p_device_id, const int width, const int height, CameraLibrary_OnGetPixelDataCallback p_callback, CameraLibrary_OnDeniedCallback p_denied_callback) {
0 commit comments