Esempio n. 1
0
        /// <summary>
        /// Returns a range of elements from the source, if the elements are not local it will fetch them from the interwebs
        /// This can take multiple web calls to get the list, so this can be slow. If there aren't enough elements remaining
        /// we will return as many as we can get.
        /// THIS IS NOT THREAD SAFE
        /// </summary>
        /// <param name="bottom">The bottom range, inclusive</param>
        /// <param name="top">Teh top of the range, exclusive</param>
        /// <returns></returns>
        public async Task <List <Element <T> > > FetchElements(int bottom, int top)
        {
            if (top <= bottom)
            {
                throw new Exception("top can't be larger than bottom!");
            }

            int santyCheckCount = 0;

            while (true)
            {
                // See if we now have what they asked for, OR the list has elements but we don't have an after.
                // (this is the case when we have hit the end of the list)
                // #bug!?!? At some point I changed the children count in the after check to santyCheckCount == 0, but I can't remember why
                // and it breaks lists that have ends. There is some bug where something doesn't try to refresh or something...
                if (m_currentElementList.Children.Count >= top ||
                    (m_currentElementList.Children.Count != 0 && m_currentElementList.After == null) ||
                    (santyCheckCount > 25))
                {
                    // Return what they asked for capped at the list size
                    int length     = top - bottom;
                    int listLength = m_currentElementList.Children.Count - bottom;
                    length = Math.Min(length, listLength);

                    // Set what the top was we returned.
                    m_lastTopGet = bottom + length;
                    return(m_currentElementList.Children.GetRange(bottom, length));
                }

                // Figure out how many we need still.
                int numberNeeded = top - m_currentElementList.Children.Count;

                // Make the request.
                string webResult = await MakeRequest(numberNeeded, m_currentElementList.After);

                RootElement <T> root = null;

                // Special case, see the comment on the bool var
                if (m_hasEmptyArrayRoot)
                {
                    // Fix up the json returned.
                    string        namedRootJson = "{\"root\": " + webResult + "}";
                    ArrayRoot <T> arrayRoot     = await Task.Run(() => JsonConvert.DeserializeObject <ArrayRoot <T> >(namedRootJson));

                    if (m_takeFirstArrayRoot)
                    {
                        // Used for forcing a post to load in flipview.
                        root = arrayRoot.Root[0];
                    }
                    else
                    {
                        // Used for comments to ignore the post header
                        root = arrayRoot.Root[1];
                    }
                }
                else
                {
                    // Parse the Json
                    root = await Task.Run(() => JsonConvert.DeserializeObject <RootElement <T> >(webResult));
                }

                // Copy the new contents into the current cache
                m_currentElementList.Children.AddRange(root.Data.Children);

                // Update the before and after
                m_currentElementList.After  = root.Data.After;
                m_currentElementList.Before = root.Data.Before;
                santyCheckCount++;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Returns a range of elements from the source, if the elements are not local it will fetch them from the interwebs
        /// This can take multiple web calls to get the list, so this can be slow. If there aren't enough elements remaining
        /// we will return as many as we can get.
        /// THIS IS NOT THREAD SAFE
        /// </summary>
        /// <param name="bottom">The bottom range, inclusive</param>
        /// <param name="top">Teh top of the range, exclusive</param>
        /// <returns></returns>
        public async Task <List <Element <T> > > FetchElements(int bottom, int top)
        {
            if (top <= bottom)
            {
                throw new Exception("top can't be larger than bottom!");
            }

            int santyCheckCount = 0;

            while (true)
            {
                // See if we now have what they asked for, OR the list has elements but we don't have an after.
                // (this is the case when we have hit the end of the list)
                // #bug!?!? At some point I changed the children count in the after check to santyCheckCount == 0, but I can't remember why
                // and it breaks lists that have ends. There is some bug where something doesn't try to refresh or something...
                if (m_currentElementList.Children.Count >= top ||
                    (m_currentElementList.Children.Count != 0 && m_currentElementList.After == null) ||
                    (santyCheckCount > 25))
                {
                    // Return what they asked for capped at the list size
                    int length     = top - bottom;
                    int listLength = m_currentElementList.Children.Count - bottom;
                    length = Math.Min(length, listLength);

                    // Set what the top was we returned.
                    m_lastTopGet = bottom + length;
                    return(m_currentElementList.Children.GetRange(bottom, length));
                }

                // Figure out how many we need still.
                int numberNeeded = top - m_currentElementList.Children.Count;

                // Make the request.
                IHttpContent webResult = await MakeRequest(numberNeeded, m_currentElementList.After);

                // This will hold the root
                RootElement <T> root = null;

                // Get the input stream and json reader.
                // NOTE!! We are really careful not to use a string here so we don't have to allocate a huge string.
                IInputStream inputStream = await webResult.ReadAsInputStreamAsync();

                using (StreamReader reader = new StreamReader(inputStream.AsStreamForRead()))
                    using (JsonReader jsonReader = new JsonTextReader(reader))
                    {
                        // Check if we have an array root or a object root
                        if (m_isArrayRoot)
                        {
                            // Parse the Json as an object
                            JsonSerializer          serializer = new JsonSerializer();
                            List <RootElement <T> > arrayRoot  = await Task.Run(() => serializer.Deserialize <List <RootElement <T> > >(jsonReader));

                            // Use which ever list element we want.
                            if (m_takeFirstArrayRoot)
                            {
                                root = arrayRoot[0];
                            }
                            else
                            {
                                root = arrayRoot[1];
                            }
                        }
                        else
                        {
                            // Parse the Json as an object
                            JsonSerializer serializer = new JsonSerializer();
                            root = await Task.Run(() => serializer.Deserialize <RootElement <T> >(jsonReader));
                        }
                    }

                // Copy the new contents into the current cache
                m_currentElementList.Children.AddRange(root.Data.Children);

                // Update the before and after
                m_currentElementList.After  = root.Data.After;
                m_currentElementList.Before = root.Data.Before;
                santyCheckCount++;
            }
        }