public NativePluginRunner(string apiKey, Transform parentForStreamedObjects, ConfigParams config)
        {
            m_textureLoadHandler = new TextureLoadHandler();
            m_materialRepository = new MaterialRepository(config.MaterialsDirectory, config.OverrideLandmarkMaterial, m_textureLoadHandler);
            m_mapGameObjectScene = new MapGameObjectScene(m_materialRepository, parentForStreamedObjects, config.Collisions);
            m_streamingUpdater   = new StreamingUpdater();

            var nativeConfig = config.GetNativeConfig();
            var pathString   = GetStreamingAssetsDir();

            Initialize(Screen.width, Screen.height, Screen.dpi,
                       apiKey,
                       pathString,
                       ref nativeConfig,
                       new MeshUploader.AllocateUnpackedMeshCallback(MeshUploader.AllocateUnpackedMesh),
                       new MeshUploader.UploadUnpackedMeshCallback(MeshUploader.UploadUnpackedMesh),
                       new MapGameObjectScene.AddMeshCallback(MapGameObjectScene.AddMesh),
                       new MapGameObjectScene.DeleteMeshCallback(MapGameObjectScene.DeleteMesh),
                       new MapGameObjectScene.VisibilityCallback(MapGameObjectScene.SetVisible),
                       new CameraApi.CameraEventCallback(CameraApi.OnCameraEvent),
                       new AssertHandler.HandleAssertCallback(AssertHandler.HandleAssert),
                       new TextureLoadHandler.AllocateTextureBufferCallback(TextureLoadHandler.AllocateTextureBuffer),
                       new TextureLoadHandler.BeginUploadTextureBufferCallback(TextureLoadHandler.BeginUploadTextureBuffer),
                       new TextureLoadHandler.ReleaseTextureCallback(TextureLoadHandler.ReleaseTexture),
                       config.CoverageTreeManifestUrl,
                       config.ThemeManifestUrl
                       );

            API = GetAppInterface();
            Debug.Assert(API != IntPtr.Zero);

            m_isRunning = true;
        }
        internal NativePluginRunner(
            string apiKey,
            TextureLoadHandler textureLoadHandler,
            MaterialRepository materialRepository,
            MapGameObjectScene mapGameObjectScene,
            ConfigParams config,
            IndoorMapScene indoorMapScene,
            IndoorMapsApiInternal indoorMapsApiInternal,
            IndoorMapMaterialService indoorMapMaterialService,
            LabelServiceInternal labelServiceInternal,
            PositionerApiInternal positionerApiInternal,
            CameraApiInternal cameraApiInternal,
            BuildingsApiInternal buildingsApiInternal,
            PrecacheApiInternal precacheApiInternal)
        {
            m_threadService      = new ThreadService();
            m_textureLoadHandler = textureLoadHandler;
            m_materialRepository = materialRepository;
            m_mapGameObjectScene = mapGameObjectScene;
            m_streamingUpdater   = new StreamingUpdater();

            var nativeConfig = config.GetNativeConfig();
            var pathString   = GetStreamingAssetsDir();
            var pathBytes    = GetNullTerminatedUTF8Bytes(pathString);

            var indoorMapsApiHandle            = indoorMapsApiInternal.GetHandle();
            var indoorMapMaterialServiceHandle = indoorMapMaterialService.GetHandle();

            var apiCallbacks = new ApiCallbacks(
                indoorMapsApiHandle,
                indoorMapMaterialServiceHandle,
                indoorMapScene.GetHandle(),
                cameraApiInternal.GetHandle(),
                buildingsApiInternal.GetHandle(),
                m_threadService.GetHandle(),
                textureLoadHandler.GetHandle(),
                mapGameObjectScene.GetHandle(),
                labelServiceInternal.GetHandle(),
                positionerApiInternal.GetHandle(),
                precacheApiInternal.GetHandle());

            Initialize(Screen.width, Screen.height, Screen.dpi,
                       apiKey,
                       pathBytes,
                       ref nativeConfig,
                       ref apiCallbacks,
                       config.CoverageTreeManifestUrl,
                       config.ThemeManifestUrl
                       );

            API = GetAppInterface();
            Debug.Assert(API != IntPtr.Zero);

            m_isRunning = true;
        }
        public NativePluginRunner(string apiKey, TextureLoadHandler textureLoadHandler, MaterialRepository materialRepository, MapGameObjectScene mapGameObjectScene, ConfigParams config)
        {
            // Initialize singleton - this is creepy and should be scheduled as debt
            // Deliberately not assigning it to keep warnings out of the Unity console
            new ThreadService();

            m_textureLoadHandler = textureLoadHandler;
            m_materialRepository = materialRepository;
            m_mapGameObjectScene = mapGameObjectScene;
            m_streamingUpdater   = new StreamingUpdater();

            var nativeConfig = config.GetNativeConfig();
            var pathString   = GetStreamingAssetsDir();

            Initialize(Screen.width, Screen.height, Screen.dpi,
                       apiKey,
                       pathString,
                       ref nativeConfig,
                       new MeshUploader.AllocateUnpackedMeshCallback(MeshUploader.AllocateUnpackedMesh),
                       new MeshUploader.UploadUnpackedMeshCallback(MeshUploader.UploadUnpackedMesh),
                       new MapGameObjectScene.AddMeshCallback(MapGameObjectScene.AddMesh),
                       new MapGameObjectScene.DeleteMeshCallback(MapGameObjectScene.DeleteMesh),
                       new MapGameObjectScene.VisibilityCallback(MapGameObjectScene.SetVisible),
                       new CameraApi.CameraEventCallback(CameraApi.OnCameraEvent),
                       new AssertHandler.HandleAssertCallback(AssertHandler.HandleAssert),
                       new TextureLoadHandler.AllocateTextureBufferCallback(TextureLoadHandler.AllocateTextureBuffer),
                       new TextureLoadHandler.BeginUploadTextureBufferCallback(TextureLoadHandler.BeginUploadTextureBuffer),
                       new TextureLoadHandler.ReleaseTextureCallback(TextureLoadHandler.ReleaseTexture),
                       new ThreadService.CreateThreadDelegate(ThreadService.CreateThread),
                       new ThreadService.JoinThreadDelegate(ThreadService.JoinThread),
                       config.CoverageTreeManifestUrl,
                       config.ThemeManifestUrl
                       );

            API = GetAppInterface();
            Debug.Assert(API != IntPtr.Zero);

            m_isRunning = true;
        }