public SetVersionResultContract GetSetVersion(string setId, string versionId)
        {
            SetVersionResultContract result = new SetVersionResultContract();

            LoaderResults setData = this.loadedSetData.Get();

            if (setData == null)
            {
                throw new NotFoundException("setData");
            }

            SetVersion setVersion = setData.FindSetVersion(setId, versionId);

            result.Set          = setVersion.Name;
            result.Version      = setVersion.Version;
            result.DetailLevels =
                setVersion.DetailLevels.Values.Select(
                    l =>
                    new LevelOfDetailContract
            {
                Name             = l.Name,
                SetSize          = new Vector3Contract(l.SetSize),
                ModelBounds      = new BoundingBoxContract(l.ModelBounds),
                WorldBounds      = new BoundingBoxContract(l.WorldBounds),
                TextureSetSize   = new Vector2Contract(l.TextureSetSize),
                WorldCubeScaling = new Vector3Contract(l.WorldToCubeRatio),
                VertexCount      = l.VertexCount
            }).ToArray();

            return(result);
        }
        public Task <StorageStream> GetModelStream(string setId, string versionId, string detail, string xpos, string ypos, string zpos, string format)
        {
            LoaderResults setData = this.loadedSetData.Get();

            if (setData == null)
            {
                throw new NotFoundException("setData");
            }

            SetVersion setVersion = setData.FindSetVersion(setId, versionId);
            SetVersionLevelOfDetail lod;

            if (!setVersion.DetailLevels.TryGetValue(detail, out lod))
            {
                throw new NotFoundException("detailLevel");
            }

            ModelFormats modelFormat;

            if (format == null)
            {
                modelFormat = ModelFormats.Ebo;
            }
            else if (!ModelFormats.TryParse(format, true, out modelFormat))
            {
                throw new NotFoundException("format");
            }

            string modelPath = lod.ModelTemplate.ToString();

            modelPath = ExpandCoordinatePlaceholders(modelPath, xpos, ypos, zpos, modelFormat);

            return(this.GetStorageStreamForPath(modelPath));
        }
        public IEnumerable <SetResultContract> EnumerateSets()
        {
            LoaderResults setData = this.loadedSetData.Get();

            if (setData == null)
            {
                return(new SetResultContract[] { });
            }

            return(setData.Sets.Keys.Select(s => new SetResultContract {
                Name = s
            }));
        }
            public static bool TrySave(LoaderResults results)
            {
                try
                {
                    using (FileStream stream = new FileStream(LKGSerializer.filename, FileMode.Create, FileAccess.ReadWrite))
                        using (GZipStream gzip = new GZipStream(stream, CompressionMode.Compress))
                            using (StreamWriter writer = new StreamWriter(gzip))
                            {
                                serializer.Serialize(writer, results);
                            }
                }
                catch (Exception ex)
                {
                    System.ArgumentException argEx = new System.ArgumentException("Failed to serialize results/writer", ex);
                    throw argEx;
                }

                return(true);
            }
        public IEnumerable <VersionResultContract> EnumerateSetVersions(string setId)
        {
            LoaderResults setData = this.loadedSetData.Get();

            if (setData == null)
            {
                throw new NotFoundException("setData");
            }

            Dictionary <string, SetVersion> setVersions;

            if (!setData.Sets.TryGetValue(setId, out setVersions))
            {
                return(new VersionResultContract[] { });
            }

            return(setVersions.Values.Select(v => new VersionResultContract {
                Name = v.Version
            }));
        }
            public static bool TryLoad(out LoaderResults results)
            {
                results = null;

                if (!File.Exists(LKGSerializer.filename))
                {
                    return(false);
                }

                using (FileStream stream = new FileStream(LKGSerializer.filename, FileMode.Open, FileAccess.Read))
                    using (GZipStream gzip = new GZipStream(stream, CompressionMode.Decompress))
                        using (StreamReader streamReader = new StreamReader(gzip))
                            using (JsonTextReader reader = new JsonTextReader(streamReader))
                            {
                                results = serializer.Deserialize <LoaderResults>(reader);
                            }


                return(true);
            }
        private void LoaderThread()
        {
            TimeSpan pollingPeriod = TimeSpan.FromMilliseconds(500);
            TimeSpan reload        = TimeSpan.FromMinutes(30);
            DateTime next          = DateTime.MinValue;


            LoaderResults lkg;

            if (LKGSerializer.TryLoad(out lkg))
            {
                this.loadedSetData.Set(lkg);
                this.onLoad.Set();
            }

            while (!this.onExit.WaitOne(0))
            {
                if (DateTime.Now > next)
                {
                    LoaderResults results = this.LoadMetadata().Result;
                    if (results.Errors.Length == 0)
                    {
                        // materialize data as last known good in temp directory
                        LKGSerializer.TrySave(results);
                        this.loadedSetData.Set(results);
                        this.onLoad.Set();
                    }
                    else
                    {
                        this.LastLoaderResults = results;
                    }

                    this.onLoadComplete.Set();
                    next = DateTime.Now + reload;
                }
                else
                {
                    Thread.Sleep(pollingPeriod);
                }
            }
        }
        public Task <StorageStream> GetTextureStream(string setId, string versionId, string detail, string xpos, string ypos)
        {
            LoaderResults setData = this.loadedSetData.Get();

            if (setData == null)
            {
                throw new NotFoundException("setData");
            }

            SetVersion setVersion = setData.FindSetVersion(setId, versionId);
            SetVersionLevelOfDetail lod;

            if (!setVersion.DetailLevels.TryGetValue(detail, out lod))
            {
                throw new NotFoundException("detailLevel");
            }

            string texturePath = lod.TextureTemplate.ToString();

            texturePath = texturePath.Replace(X_PLACEHOLDER, xpos);
            texturePath = texturePath.Replace(Y_PLACEHOLDER, ypos);
            return(this.GetStorageStreamForPath(texturePath));
        }
        public async Task <LoaderResults> LoadMetadata()
        {
            LoaderResults results = new LoaderResults();

            List <LoaderException> exceptions = new List <LoaderException>();
            Dictionary <string, Dictionary <string, SetVersion> > sets =
                new Dictionary <string, Dictionary <string, SetVersion> >(StringComparer.InvariantCultureIgnoreCase);

            SetContract[] setsMetadata   = null;
            Uri           storageRootUri = null;

            try
            {
                storageRootUri = new Uri(this.storageRoot, UriKind.Relative);

                setsMetadata = await this.Deserialize <SetContract[]>(storageRootUri);

                if (setsMetadata == null)
                {
                    throw new SerializationException("Deserialization Failed");
                }
            }
            catch (Exception ex)
            {
                exceptions.Add(new LoaderException("Sets", this.storageRoot, ex));
                results.Errors = exceptions.ToArray();
                results.Sets   = sets;
                return(results);
            }

            List <SetVersion> setVersions = new List <SetVersion>();

            foreach (SetContract set in setsMetadata)
            {
                try
                {
                    foreach (SetVersionContract version in set.Versions)
                    {
                        Uri setMetadataUri = new Uri(storageRootUri, version.Url);

                        Trace.WriteLine(String.Format("Set: {0}, Url {1}", set.Name, setMetadataUri));
                        SetMetadataContract setMetadata = await this.Deserialize <SetMetadataContract>(setMetadataUri);

                        if (setMetadata == null)
                        {
                            throw new SerializationException("Set metadata deserialization Failed");
                        }

                        Trace.WriteLine(String.Format("Discovered set {0}/{1} at {2}", set.Name, version.Name, version.Url));

                        Uri material = new Uri(setMetadataUri, setMetadata.Mtl);

                        SetVersion currentSet = new SetVersion {
                            SourceUri = setMetadataUri, Name = set.Name, Version = version.Name, Material = material
                        };

                        List <SetVersionLevelOfDetail> detailLevels = await this.ExtractDetailLevels(setMetadata, setMetadataUri);

                        currentSet.DetailLevels = new SortedDictionary <string, SetVersionLevelOfDetail>(detailLevels.ToDictionary(d => d.Name, d => d, StringComparer.OrdinalIgnoreCase));
                        setVersions.Add(currentSet);
                    }
                }
                catch (Exception ex)
                {
                    exceptions.Add(new LoaderException("Set", storageRootUri.ToString(), ex));
                }
            }

            sets = setVersions.GroupBy(s => s.Name).ToDictionary(s => s.Key, this.GenerateVersionMap, StringComparer.OrdinalIgnoreCase);

            results.Errors = exceptions.ToArray();
            results.Sets   = sets;

            return(results);
        }