internal LoadedAvatar(AvatarPrefab prefab)
 {
     this.prefab            = prefab.gameObject;
     fileName               = prefab.fileName;
     fullPath               = prefab.fullPath;
     descriptor             = prefab.descriptor;
     isIKAvatar             = prefab.isIKAvatar;
     supportsFingerTracking = prefab.supportsFingerTracking;
     eyeHeight              = prefab.eyeHeight;
     armSpan = prefab.armSpan;
 }
        private void HandleSuccess(string fullPath, AvatarPrefab avatarPrefab)
        {
            _logger.Info($"Successfully loaded avatar '{avatarPrefab.descriptor.name}' by '{avatarPrefab.descriptor.author}' from '{fullPath}'");

            foreach (LoadHandlers handler in _handlers[fullPath])
            {
                handler.InvokeSuccess(avatarPrefab);
            }

            _handlers.Remove(fullPath);
        }
        public AvatarInfo(AvatarPrefab avatar)
        {
            name   = avatar.descriptor.name ?? "Unknown";
            author = avatar.descriptor.author ?? "Unknown";
            icon   = avatar.descriptor.cover ? avatar.descriptor.cover : null;

            var fileInfo = new FileInfo(avatar.fullPath);

            fileName     = fileInfo.Name;
            fileSize     = fileInfo.Length;
            created      = fileInfo.CreationTimeUtc;
            lastModified = fileInfo.LastWriteTimeUtc;

            timestamp = DateTime.UtcNow;
        }
        // TODO from stream/memory
        /// <summary>
        /// Load an avatar from a file.
        /// </summary>
        /// <param name="path">Path to the .avatar file</param>
        /// <param name="success">Action to call if the avatar is loaded successfully</param>
        /// <param name="error">Action to call if the avatar isn't loaded successfully</param>
        /// <returns><see cref="IEnumerator{AsyncOperation}"/></returns>
        public IEnumerator <AsyncOperation> LoadFromFileAsync(string path, Action <AvatarPrefab> success = null, Action <Exception> error = null, Action complete = null)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            string fullPath = Path.GetFullPath(path);

            // already loading, just add handlers
            if (_handlers.ContainsKey(fullPath))
            {
                _handlers[fullPath].Add(new LoadHandlers(success, error, complete));

                yield break;
            }

            _handlers.Add(fullPath, new List <LoadHandlers> {
                new LoadHandlers(success, error, complete)
            });

            if (!File.Exists(fullPath))
            {
                HandleException(fullPath, new IOException($"File '{fullPath}' does not exist"));
                yield break;
            }

            _logger.Info($"Loading avatar from '{fullPath}'");

            AssetBundleCreateRequest assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(fullPath);

            yield return(assetBundleCreateRequest);

            if (!assetBundleCreateRequest.isDone || !assetBundleCreateRequest.assetBundle)
            {
                HandleException(fullPath, new AvatarLoadException("Could not load asset bundle"));
                yield break;
            }

            AssetBundleRequest assetBundleRequest = assetBundleCreateRequest.assetBundle.LoadAssetWithSubAssetsAsync <GameObject>(kGameObjectName);

            yield return(assetBundleRequest);

            if (!assetBundleRequest.isDone || assetBundleRequest.asset == null)
            {
                assetBundleCreateRequest.assetBundle.Unload(true);

                HandleException(fullPath, new AvatarLoadException("Could not load asset from asset bundle"));

                yield break;
            }

            assetBundleCreateRequest.assetBundle.Unload(false);

            try
            {
                GameObject   prefabObject = (GameObject)assetBundleRequest.asset;
                AvatarPrefab avatarPrefab = _container.InstantiateComponent <AvatarPrefab>(prefabObject, new object[] { fullPath });
                avatarPrefab.name = $"LoadedAvatar({avatarPrefab.descriptor.name})";

                HandleSuccess(fullPath, avatarPrefab);
            }
            catch (Exception ex)
            {
                HandleException(fullPath, ex);
            }
        }
 public void InvokeSuccess(AvatarPrefab value)
 {
     success?.Invoke(value);
     complete?.Invoke();
 }