File indexing completed on 2024-05-12 04:43:04

0001 /***************************************************************************
0002  *   Copyright (C) 2018 by Emmanuel Lepage Vallee                          *
0003  *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org>             *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 3 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0017  **************************************************************************/
0018 #ifndef KQUICKITEMVIEWS_CONTINUITY_P_H
0019 #define KQUICKITEMVIEWS_CONTINUITY_P_H
0020 
0021 namespace StateTracker {
0022 
0023 class Index;
0024 
0025 /**
0026  * This bare-bone state tracker helps to track the continuity between the
0027  * ELEMENTS WITH THE SAME PARENT.
0028  *
0029  * The use case for this is to prevent the O(N) operation of the list of
0030  * elements to check if there is missing holes in them. This could be done with
0031  * simple artmetic on the row of the last child, first child and the number of
0032  * children, but this would not handle the corner cases where there multiple
0033  * "holes". It would also not allow to know where the hole(s) are without
0034  * looping.
0035  *
0036  * This may seem overkill to waste memory tracking this, but there is 2 reasons
0037  * why it isn't such a bad idea:
0038  *
0039  *  * Some ViewportStategies need to know this in every frame (fps) of a scroll
0040  *    operation with tight frame duration deadlines.
0041  *  * If the viewport loads a full list model, the "N" of "O(N)" can be very
0042  *    large.
0043  *
0044  * @todo This should, once fully implemented, go hand in hand with
0045  *  StateTracker::Proximity to avoid useless rowCount other overhead in
0046  *  StateTracker::Content and make methods such as `isActive` reliable.
0047  *
0048  * @todo Slicing a StateTracker::Continuity is currently rather expensive. This
0049  *  can be brought down to "O(N*log(N))" by using double pointers to create
0050  *  "pages" of a size representative of the total number of elements. However
0051  *  this will take more memory and has an overhead in itself. It wont be done
0052  *  unless it is proven to be significantly faster for real-world models.
0053  */
0054 class Continuity final
0055 {
0056     friend class Index; // Factory, call private API
0057 
0058 public:
0059     Index *first() const;
0060     Index *last () const;
0061 
0062     int size() const;
0063 
0064 private:
0065     explicit Continuity(Index *first);
0066 
0067     StateTracker::Index *m_pFirst {nullptr};
0068     StateTracker::Index *m_pLast  {nullptr};
0069 
0070     static void split(StateTracker::Index *at);
0071     static void merge(StateTracker::Index *one, StateTracker::Index *two);
0072     static void remove(Index *i);
0073     static void setContinuity(Index *i, Continuity *c);
0074     static Continuity *select(StateTracker::Index *i);
0075 };
0076 
0077 }
0078 
0079 #endif