瀏覽代碼

Merge pull request #33992 from bruvzg/ios_modular_build

iOS modular build and export implementation.
Rémi Verschelde 5 年之前
父節點
當前提交
e64a663c59

+ 8 - 0
main/main.cpp

@@ -65,6 +65,7 @@
 #include "scene/resources/packed_scene.h"
 #include "servers/arvr_server.h"
 #include "servers/audio_server.h"
+#include "servers/camera_server.h"
 #include "servers/physics_2d_server.h"
 #include "servers/physics_server.h"
 #include "servers/register_server_types.h"
@@ -97,6 +98,7 @@ static MessageQueue *message_queue = NULL;
 
 // Initialized in setup2()
 static AudioServer *audio_server = NULL;
+static CameraServer *camera_server = NULL;
 static ARVRServer *arvr_server = NULL;
 static PhysicsServer *physics_server = NULL;
 static Physics2DServer *physics_2d_server = NULL;
@@ -1318,6 +1320,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 	register_platform_apis();
 	register_module_types();
 
+	camera_server = CameraServer::create();
+
 	initialize_physics();
 	register_server_singletons();
 
@@ -2142,6 +2146,10 @@ void Main::cleanup() {
 		memdelete(audio_server);
 	}
 
+	if (camera_server) {
+		memdelete(camera_server);
+	}
+
 	OS::get_singleton()->finalize();
 	finalize_physics();
 

+ 6 - 0
misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj

@@ -19,6 +19,7 @@
 		1FE926A11FBBF86D00F53A6F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FE9268F1FBBF77F00F53A6F /* CoreAudio.framework */; };
 		E360193721F32F38009258C1 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E360193621F32F37009258C1 /* CoreVideo.framework */; };
 		DEADBEEF2F582BE20003B888 /* $binary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.a */; };
+		$modules_buildfile
 		1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; };
 		1FF4C1851F584E3F00A41E41 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FF4C1841F584E3F00A41E41 /* GameKit.framework */; };
 		1FF4C1871F584E5600A41E41 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FF4C1861F584E5600A41E41 /* StoreKit.framework */; };
@@ -45,6 +46,7 @@
 		1FE926951FBBF7C400F53A6F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
 		1FE926961FBBF7D400F53A6F /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
 		DEADBEEF1F582BE20003B888 /* $binary.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot; path = "$binary.a"; sourceTree = "<group>"; };
+		$modules_fileref
 		1FF4C1841F584E3F00A41E41 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
 		1FF4C1861F584E5600A41E41 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
 		1FF4C1881F584E7600A41E41 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
@@ -89,6 +91,7 @@
 				D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */,
 				D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */,
 				DEADBEEF2F582BE20003B888 /* $binary.a */,
+				$modules_buildphase
 				$additional_pbx_frameworks_build
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -138,6 +141,7 @@
 				D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */,
 				D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */,
 				DEADBEEF1F582BE20003B888 /* $binary.a */,
+				$modules_buildgrp
 				$additional_pbx_frameworks_refs
 			);
 			name = Frameworks;
@@ -427,6 +431,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
+					"$(PROJECT_DIR)",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = $identifier;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -452,6 +457,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
+					"$(PROJECT_DIR)",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = $identifier;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 5 - 3
modules/arkit/SCsub

@@ -5,6 +5,8 @@ Import('env_modules')
 
 env_arkit = env_modules.Clone()
 
-# Add source files
-env_arkit.add_source_files(env.modules_sources, "*.cpp")
-env_arkit.add_source_files(env.modules_sources, "*.mm")
+# (iOS) Build as separate static library
+modules_sources = []
+env_arkit.add_source_files(modules_sources, "*.cpp")
+env_arkit.add_source_files(modules_sources, "*.mm")
+mod_lib = env_modules.add_library('#bin/libgodot_arkit_module' + env['LIBSUFFIX'], modules_sources)

+ 0 - 1
modules/arkit/arkit_interface.mm

@@ -28,7 +28,6 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 
-#include "camera_ios.h"
 #include "core/os/input.h"
 #include "core/os/os.h"
 #include "scene/resources/surface_tool.h"

+ 22 - 0
modules/camera/SCSub

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_camera = env_modules.Clone()
+
+if env["platform"] == "iphone":
+    # (iOS) Build as separate static library
+    modules_sources = []
+    env_camera.add_source_files(modules_sources, "register_types.cpp")
+    env_camera.add_source_files(modules_sources, "camera_ios.mm")
+    mod_lib = env_modules.add_library('#bin/libgodot_camera_module' + env['LIBSUFFIX'], modules_sources)
+
+elif env["platform"] == "windows":
+    env_camera.add_source_files(env.modules_sources, "register_types.cpp")
+    env_camera.add_source_files(env.modules_sources, "camera_win.cpp")
+
+elif env["platform"] == "osx":
+    env_camera.add_source_files(env.modules_sources, "register_types.cpp")
+    env_camera.add_source_files(env.modules_sources, "camera_osx.mm")
+

+ 0 - 0
platform/iphone/camera_ios.h → modules/camera/camera_ios.h


+ 1 - 1
platform/iphone/camera_ios.mm → modules/camera/camera_ios.mm

@@ -359,7 +359,7 @@ void CameraIOS::update_feeds() {
 	// this way of doing things is deprecated but still works,
 	// rewrite to using AVCaptureDeviceDiscoverySession
 
-	AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera, AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
+	AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera, AVCaptureDeviceTypeBuiltInWideAngleCamera, nil] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
 
 	// remove devices that are gone..
 	for (int i = feeds.size() - 1; i >= 0; i--) {

+ 0 - 0
platform/osx/camera_osx.h → modules/camera/camera_osx.h


+ 0 - 0
platform/osx/camera_osx.mm → modules/camera/camera_osx.mm


+ 0 - 0
platform/windows/camera_win.cpp → modules/camera/camera_win.cpp


+ 0 - 0
platform/windows/camera_win.h → modules/camera/camera_win.h


+ 5 - 0
modules/camera/config.py

@@ -0,0 +1,5 @@
+def can_build(env, platform):
+     return platform == 'iphone' or platform == 'osx' or platform == 'windows'
+
+def configure(env):
+    pass

+ 56 - 0
modules/camera/register_types.cpp

@@ -0,0 +1,56 @@
+/*************************************************************************/
+/*  register_types.cpp                                                   */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "register_types.h"
+
+#if defined(WINDOWS_ENABLED)
+#include "camera_win.h"
+#endif
+#if defined(IPHONE_ENABLED)
+#include "camera_ios.h"
+#endif
+#if defined(OSX_ENABLED)
+#include "camera_osx.h"
+#endif
+
+void register_camera_types() {
+#if defined(WINDOWS_ENABLED)
+	CameraServer::make_default<CameraWindows>();
+#endif
+#if defined(IPHONE_ENABLED)
+	CameraServer::make_default<CameraIOS>();
+#endif
+#if defined(OSX_ENABLED)
+	CameraServer::make_default<CameraOSX>();
+#endif
+}
+
+void unregister_camera_types() {
+}

+ 32 - 0
modules/camera/register_types.h

@@ -0,0 +1,32 @@
+/*************************************************************************/
+/*  register_types.h                                                     */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+void register_camera_types();
+void unregister_camera_types();

+ 0 - 5
platform/android/os_android.cpp

@@ -175,9 +175,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
 	input = memnew(InputDefault);
 	input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
 
-	///@TODO implement a subclass for Android and instantiate that instead
-	camera_server = memnew(CameraServer);
-
 	//power_manager = memnew(PowerAndroid);
 
 	return OK;
@@ -196,8 +193,6 @@ void OS_Android::delete_main_loop() {
 
 void OS_Android::finalize() {
 
-	memdelete(camera_server);
-
 	memdelete(input);
 }
 

+ 0 - 3
platform/android/os_android.h

@@ -39,7 +39,6 @@
 #include "main/input_default.h"
 //#include "power_android.h"
 #include "servers/audio_server.h"
-#include "servers/camera_server.h"
 #include "servers/visual/rasterizer.h"
 
 class GodotJavaWrapper;
@@ -79,8 +78,6 @@ private:
 
 	VisualServer *visual_server;
 
-	CameraServer *camera_server;
-
 	mutable String data_dir_cache;
 
 	//AudioDriverAndroid audio_driver_android;

+ 0 - 4
platform/haiku/os_haiku.cpp

@@ -133,8 +133,6 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p
 	window->Show();
 	visual_server->init();
 
-	camera_server = memnew(CameraServer);
-
 	AudioDriverManager::initialize(p_audio_driver);
 
 	return OK;
@@ -150,8 +148,6 @@ void OS_Haiku::finalize() {
 	visual_server->finish();
 	memdelete(visual_server);
 
-	memdelete(camera_server);
-
 	memdelete(input);
 
 #if defined(OPENGL_ENABLED)

+ 0 - 2
platform/haiku/os_haiku.h

@@ -38,7 +38,6 @@
 #include "haiku_direct_window.h"
 #include "main/input_default.h"
 #include "servers/audio_server.h"
-#include "servers/camera_server.h"
 #include "servers/visual_server.h"
 
 class OS_Haiku : public OS_Unix {
@@ -50,7 +49,6 @@ private:
 	VisualServer *visual_server;
 	VideoMode current_video_mode;
 	int video_driver_index;
-	CameraServer *camera_server;
 
 #ifdef MEDIA_KIT_ENABLED
 	AudioDriverMediaKit driver_media_kit;

+ 0 - 1
platform/iphone/SCsub

@@ -14,7 +14,6 @@ iphone_lib = [
     'in_app_store.mm',
     'icloud.mm',
     'ios.mm',
-    'camera_ios.mm',
 ]
 
 env_ios = env.Clone()

+ 54 - 1
platform/iphone/export/export.cpp

@@ -63,6 +63,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
 		String architectures;
 		String linker_flags;
 		String cpp_code;
+		String modules_buildfile;
+		String modules_fileref;
+		String modules_buildphase;
+		String modules_buildgrp;
 	};
 
 	struct ExportArchitecture {
@@ -178,6 +182,7 @@ public:
 		return list;
 	}
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
+	virtual void add_module_code(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid);
 
 	virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
 
@@ -263,6 +268,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
 	r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
 
 	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/arkit"), false));
+	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/camera"), false));
+
 	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/game_center"), true));
 	r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false));
@@ -311,6 +318,14 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
 	for (int i = 0; i < lines.size(); i++) {
 		if (lines[i].find("$binary") != -1) {
 			strnew += lines[i].replace("$binary", p_config.binary_name) + "\n";
+		} else if (lines[i].find("$modules_buildfile") != -1) {
+			strnew += lines[i].replace("$modules_buildfile", p_config.modules_buildfile) + "\n";
+		} else if (lines[i].find("$modules_fileref") != -1) {
+			strnew += lines[i].replace("$modules_fileref", p_config.modules_fileref) + "\n";
+		} else if (lines[i].find("$modules_buildphase") != -1) {
+			strnew += lines[i].replace("$modules_buildphase", p_config.modules_buildphase) + "\n";
+		} else if (lines[i].find("$modules_buildgrp") != -1) {
+			strnew += lines[i].replace("$modules_buildgrp", p_config.modules_buildgrp) + "\n";
 		} else if (lines[i].find("$name") != -1) {
 			strnew += lines[i].replace("$name", p_config.pkg_name) + "\n";
 		} else if (lines[i].find("$info") != -1) {
@@ -837,6 +852,22 @@ Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<Edit
 	return enabled_archs;
 }
 
+void EditorExportPlatformIOS::add_module_code(const Ref<EditorExportPreset> &p_preset, EditorExportPlatformIOS::IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid) {
+	if ((bool)p_preset->get("capabilities/" + p_name)) {
+		//add module static library
+		print_line("ADDING MODULE: " + p_name);
+
+		p_config_data.modules_buildfile += p_gid + " /* libgodot_" + p_name + "_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = " + p_fid + " /* libgodot_" + p_name + "_module.a */; };\n\t\t";
+		p_config_data.modules_fileref += p_fid + " /* libgodot_" + p_name + "_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot_" + p_name + "_module ; path = \"libgodot_" + p_name + "_module.a\"; sourceTree = \"<group>\"; };\n\t\t";
+		p_config_data.modules_buildphase += p_gid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t";
+		p_config_data.modules_buildgrp += p_fid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t";
+	} else {
+		//add stub function for disabled module
+		p_config_data.cpp_code += "void register_" + p_name + "_types() { /*stub*/ };\n";
+		p_config_data.cpp_code += "void unregister_" + p_name + "_types() { /*stub*/ };\n";
+	}
+}
+
 Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
 	ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
 
@@ -934,7 +965,11 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
 		_get_additional_plist_content(),
 		String(" ").join(_get_preset_architectures(p_preset)),
 		_get_linker_flags(),
-		_get_cpp_code()
+		_get_cpp_code(),
+		"",
+		"",
+		"",
+		""
 	};
 
 	DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir);
@@ -949,6 +984,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
 		return ERR_CANT_OPEN;
 	}
 
+	add_module_code(p_preset, config_data, "arkit", "F9B95E6E2391205500AF0000", "F9C95E812391205C00BF0000");
+	add_module_code(p_preset, config_data, "camera", "F9B95E6E2391205500AF0001", "F9C95E812391205C00BF0001");
+
+	//export rest of the files
 	int ret = unzGoToFirstFile(src_pkg_zip);
 	Vector<uint8_t> project_file_data;
 	while (ret == UNZ_OK) {
@@ -988,6 +1027,20 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
 			is_execute = true;
 #endif
 			file = "godot_ios.a";
+		} else if (file.begins_with("libgodot_arkit")) {
+			if ((bool)p_preset->get("capabilities/arkit") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) {
+				file = "libgodot_arkit_module.a";
+			} else {
+				ret = unzGoToNextFile(src_pkg_zip);
+				continue; //ignore!
+			}
+		} else if (file.begins_with("libgodot_camera")) {
+			if ((bool)p_preset->get("capabilities/camera") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) {
+				file = "libgodot_camera_module.a";
+			} else {
+				ret = unzGoToNextFile(src_pkg_zip);
+				continue; //ignore!
+			}
 		}
 		if (file == project_file) {
 			project_file_data = data;

+ 0 - 7
platform/iphone/os_iphone.cpp

@@ -164,8 +164,6 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p
 
 	input = memnew(InputDefault);
 
-	camera_server = memnew(CameraIOS);
-
 #ifdef GAME_CENTER_ENABLED
 	game_center = memnew(GameCenter);
 	Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center));
@@ -361,11 +359,6 @@ void OSIPhone::finalize() {
 	if (main_loop) // should not happen?
 		memdelete(main_loop);
 
-	if (camera_server) {
-		memdelete(camera_server);
-		camera_server = NULL;
-	}
-
 	visual_server->finish();
 	memdelete(visual_server);
 	//	memdelete(rasterizer);

+ 0 - 3
platform/iphone/os_iphone.h

@@ -37,7 +37,6 @@
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
 #include "drivers/unix/os_unix.h"
 
-#include "camera_ios.h"
 #include "game_center.h"
 #include "icloud.h"
 #include "in_app_store.h"
@@ -62,8 +61,6 @@ private:
 
 	AudioDriverCoreAudio audio_driver;
 
-	CameraServer *camera_server;
-
 #ifdef GAME_CENTER_ENABLED
 	GameCenter *game_center;
 #endif

+ 0 - 3
platform/javascript/os_javascript.cpp

@@ -970,8 +970,6 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
 	VisualServer *visual_server = memnew(VisualServerRaster());
 	input = memnew(InputDefault);
 
-	camera_server = memnew(CameraServer);
-
 	EMSCRIPTEN_RESULT result;
 #define EM_CHECK(ev)                         \
 	if (result != EMSCRIPTEN_RESULT_SUCCESS) \
@@ -1106,7 +1104,6 @@ void OS_JavaScript::delete_main_loop() {
 
 void OS_JavaScript::finalize() {
 
-	memdelete(camera_server);
 	memdelete(input);
 }
 

+ 0 - 3
platform/javascript/os_javascript.h

@@ -35,7 +35,6 @@
 #include "drivers/unix/os_unix.h"
 #include "main/input_default.h"
 #include "servers/audio_server.h"
-#include "servers/camera_server.h"
 #include "servers/visual/rasterizer.h"
 
 #include <emscripten/html5.h>
@@ -67,8 +66,6 @@ class OS_JavaScript : public OS_Unix {
 	int64_t sync_wait_time;
 	int64_t last_sync_check_time;
 
-	CameraServer *camera_server;
-
 	static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
 
 	static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);

+ 0 - 1
platform/osx/SCsub

@@ -13,7 +13,6 @@ files = [
     'dir_access_osx.mm',
     'joypad_osx.cpp',
     'power_osx.cpp',
-    'camera_osx.mm',
 ]
 
 prog = env.add_program('#bin/godot', files)

+ 0 - 3
platform/osx/os_osx.h

@@ -33,7 +33,6 @@
 
 #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
 
-#include "camera_osx.h"
 #include "core/os/input.h"
 #include "crash_handler_osx.h"
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
@@ -74,8 +73,6 @@ public:
 	//Rasterizer *rasterizer;
 	VisualServer *visual_server;
 
-	CameraServer *camera_server;
-
 	List<String> args;
 	MainLoop *main_loop;
 

+ 0 - 7
platform/osx/os_osx.mm

@@ -1632,8 +1632,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
 	visual_server->init();
 	AudioDriverManager::initialize(p_audio_driver);
 
-	camera_server = memnew(CameraOSX);
-
 	input = memnew(InputDefault);
 	joypad_osx = memnew(JoypadOSX);
 
@@ -1663,11 +1661,6 @@ void OS_OSX::finalize() {
 
 	delete_main_loop();
 
-	if (camera_server) {
-		memdelete(camera_server);
-		camera_server = NULL;
-	}
-
 	memdelete(joypad_osx);
 	memdelete(input);
 

+ 0 - 4
platform/server/os_server.cpp

@@ -88,8 +88,6 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
 	visual_server = memnew(VisualServerRaster);
 	visual_server->init();
 
-	camera_server = memnew(CameraServer);
-
 	AudioDriverManager::initialize(p_audio_driver);
 
 	input = memnew(InputDefault);
@@ -119,8 +117,6 @@ void OS_Server::finalize() {
 
 	memdelete(input);
 
-	memdelete(camera_server);
-
 	memdelete(power_manager);
 
 	ResourceLoader::remove_resource_format_loader(resource_loader_dummy);

+ 0 - 1
platform/server/os_server.h

@@ -71,7 +71,6 @@ class OS_Server : public OS_Unix {
 #endif
 
 	CrashHandler crash_handler;
-	CameraServer *camera_server;
 
 	int video_driver_index;
 

+ 0 - 5
platform/uwp/os_uwp.cpp

@@ -303,9 +303,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
 
 	visual_server->init();
 
-	///@TODO implement a subclass for UWP and instantiate that instead
-	camera_server = memnew(CameraServer);
-
 	input = memnew(InputDefault);
 
 	joypad = ref new JoypadUWP(input);
@@ -404,8 +401,6 @@ void OS_UWP::finalize() {
 
 	memdelete(input);
 
-	memdelete(camera_server);
-
 	joypad = nullptr;
 }
 

+ 0 - 3
platform/uwp/os_uwp.h

@@ -41,7 +41,6 @@
 #include "main/input_default.h"
 #include "power_uwp.h"
 #include "servers/audio_server.h"
-#include "servers/camera_server.h"
 #include "servers/visual/rasterizer.h"
 #include "servers/visual_server.h"
 
@@ -93,8 +92,6 @@ private:
 	VisualServer *visual_server;
 	int pressrc;
 
-	CameraServer *camera_server;
-
 	ContextEGL_UWP *gl_context;
 	Windows::UI::Core::CoreWindow ^ window;
 

+ 0 - 1
platform/windows/SCsub

@@ -8,7 +8,6 @@ import platform_windows_builders
 
 common_win = [
     "godot_windows.cpp",
-    "camera_win.cpp",
     "context_gl_windows.cpp",
     "crash_handler_windows.cpp",
     "os_windows.cpp",

+ 0 - 3
platform/windows/os_windows.cpp

@@ -1494,8 +1494,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
 
 	power_manager = memnew(PowerWindows);
 
-	camera_server = memnew(CameraWindows);
-
 	AudioDriverManager::initialize(p_audio_driver);
 
 	TRACKMOUSEEVENT tme;
@@ -1649,7 +1647,6 @@ void OS_Windows::finalize() {
 
 	memdelete(joypad);
 	memdelete(input);
-	memdelete(camera_server);
 	touch_state.clear();
 
 	cursors_cache.clear();

+ 0 - 2
platform/windows/os_windows.h

@@ -31,7 +31,6 @@
 #ifndef OS_WINDOWS_H
 #define OS_WINDOWS_H
 
-#include "camera_win.h"
 #include "context_gl_windows.h"
 #include "core/os/input.h"
 #include "core/os/os.h"
@@ -175,7 +174,6 @@ class OS_Windows : public OS {
 	ContextGL_Windows *gl_context;
 #endif
 	VisualServer *visual_server;
-	CameraWindows *camera_server;
 	int pressrc;
 	HINSTANCE hInstance; // Holds The Instance Of The Application
 	HWND hWnd;

+ 0 - 5
platform/x11/os_x11.cpp

@@ -596,9 +596,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
 
 	AudioDriverManager::initialize(p_audio_driver);
 
-	///@TODO implement a subclass for Linux and instantiate that instead
-	camera_server = memnew(CameraServer);
-
 	input = memnew(InputDefault);
 
 	window_has_focus = true; // Set focus to true at init
@@ -832,8 +829,6 @@ void OS_X11::finalize() {
 
 	memdelete(input);
 
-	memdelete(camera_server);
-
 	cursors_cache.clear();
 	visual_server->finish();
 	memdelete(visual_server);

+ 0 - 3
platform/x11/os_x11.h

@@ -42,7 +42,6 @@
 #include "main/input_default.h"
 #include "power_x11.h"
 #include "servers/audio_server.h"
-#include "servers/camera_server.h"
 #include "servers/visual/rasterizer.h"
 #include "servers/visual_server.h"
 //#include "servers/visual/visual_server_wrap_mt.h"
@@ -150,8 +149,6 @@ class OS_X11 : public OS_Unix {
 	void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
 	void flush_mouse_motion();
 
-	CameraServer *camera_server;
-
 	MouseMode mouse_mode;
 	Point2i center;
 

+ 2 - 0
servers/camera_server.cpp

@@ -35,6 +35,8 @@
 ////////////////////////////////////////////////////////
 // CameraServer
 
+CameraServer::CreateFunc CameraServer::create_func = NULL;
+
 void CameraServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_feed", "index"), &CameraServer::get_feed);
 	ClassDB::bind_method(D_METHOD("get_feed_count"), &CameraServer::get_feed_count);

+ 19 - 0
servers/camera_server.h

@@ -59,17 +59,36 @@ public:
 		FEED_IMAGES = 2
 	};
 
+	typedef CameraServer *(*CreateFunc)();
+
 private:
 protected:
+	static CreateFunc create_func;
+
 	Vector<Ref<CameraFeed> > feeds;
 
 	static CameraServer *singleton;
 
 	static void _bind_methods();
 
+	template <class T>
+	static CameraServer *_create_builtin() {
+		return memnew(T);
+	}
+
 public:
 	static CameraServer *get_singleton();
 
+	template <class T>
+	static void make_default() {
+		create_func = _create_builtin<T>;
+	}
+
+	static CameraServer *create() {
+		CameraServer *server = create_func ? create_func() : memnew(CameraServer);
+		return server;
+	};
+
 	// Right now we identify our feed by it's ID when it's used in the background.
 	// May see if we can change this to purely relying on CameraFeed objects or by name.
 	int get_free_id();