1 // Aseprite Document Library 2 // Copyright (c) 2017 David Capello 3 // 4 // This file is released under the terms of the MIT license. 5 // Read LICENSE.txt for more information. 6 7 #ifndef DOC_KEYFRAMES_H_INCLUDED 8 #define DOC_KEYFRAMES_H_INCLUDED 9 #pragma once 10 11 #include "base/disable_copying.h" 12 #include "doc/frame.h" 13 14 #include <vector> 15 16 namespace doc { 17 18 template<typename T> 19 class Keyframes { 20 public: 21 class Key { 22 public: Key(const frame_t frame,T * value)23 Key(const frame_t frame, T* value) : m_frame(frame), m_value(value) { } frame()24 frame_t frame() const { return m_frame; } value()25 T* value() const { return m_value; } setFrame(const frame_t frame)26 void setFrame(const frame_t frame) { m_frame = frame; } setValue(T * value)27 void setValue(T* value) { m_value = value; } 28 private: 29 frame_t m_frame; 30 T* m_value; 31 }; 32 33 typedef std::vector<Key> List; 34 typedef typename List::iterator iterator; 35 typedef typename List::const_iterator const_iterator; 36 37 class Range { 38 public: 39 class RangeIterator { 40 public: RangeIterator(const iterator & it,const iterator & end,const frame_t frame)41 RangeIterator(const iterator& it, 42 const iterator& end, const frame_t frame) 43 : m_it(it), m_end(end), m_frame(frame) { 44 if (it != end) { 45 m_next = it; 46 ++m_next; 47 } 48 else 49 m_next = end; 50 } 51 RangeIterator& operator++() { 52 ++m_frame; 53 if (m_next != m_end && 54 m_next->frame() == m_frame) { 55 m_it = m_next; 56 ++m_next; 57 } 58 return *this; 59 } 60 bool operator!=(const RangeIterator& other) { 61 return (m_frame != other.m_frame+1); 62 } 63 T* operator*() { 64 if (m_it != m_end) 65 return m_it->value(); 66 else 67 return nullptr; 68 } 69 private: 70 iterator m_it, m_next; 71 const iterator m_end; 72 frame_t m_frame; 73 }; Range(const iterator & fromIt,const iterator & endIt,const frame_t from,const frame_t to)74 Range(const iterator& fromIt, 75 const iterator& endIt, 76 const frame_t from, 77 const frame_t to) 78 : m_fromIt(fromIt), m_endIt(endIt) 79 , m_from(from), m_to(to) { 80 } begin()81 RangeIterator begin() const { 82 return RangeIterator(m_fromIt, m_endIt, m_from); 83 } end()84 RangeIterator end() const { 85 return RangeIterator(m_fromIt, m_endIt, m_to); 86 } empty()87 bool empty() const { 88 return (m_fromIt == m_endIt || 89 m_to < m_fromIt->frame()); 90 } countKeys()91 size_t countKeys() const { 92 size_t count = 0; 93 auto it = m_fromIt; 94 for (; it!=m_endIt; ++it) { 95 if (it->frame() > m_to) 96 break; 97 ++count; 98 } 99 return count; 100 } 101 private: 102 const iterator m_fromIt, m_endIt; 103 const frame_t m_from, m_to; 104 }; 105 Keyframes()106 Keyframes() { } 107 insert(const frame_t frame,T * value)108 void insert(const frame_t frame, T* value) { 109 auto it = getIterator(frame); 110 if (it == end()) 111 m_keys.push_back(Key(frame, value)); 112 else if (it->frame() == frame) 113 it->setValue(value); 114 else { 115 ++it; 116 m_keys.insert(it, Key(frame, value)); 117 } 118 } 119 remove(const frame_t frame)120 T* remove(const frame_t frame) { 121 auto it = getIterator(frame); 122 if (it != end()) { 123 T* value = it->value(); 124 m_keys.erase(it); 125 return value; 126 } 127 else 128 return nullptr; 129 } 130 131 T* operator[](const frame_t frame) { 132 auto it = getIterator(frame); 133 if (it != end() && 134 it->value() && 135 frame >= it->frame()) 136 return it->value(); 137 else 138 return nullptr; 139 } 140 begin()141 iterator begin() { return m_keys.begin(); } end()142 iterator end() { return m_keys.end(); } begin()143 const_iterator begin() const { return m_keys.begin(); } end()144 const_iterator end() const { return m_keys.end(); } 145 size()146 std::size_t size() const { return m_keys.size(); } empty()147 bool empty() const { return m_keys.empty(); } 148 getIterator(const frame_t frame)149 iterator getIterator(const frame_t frame) { 150 auto 151 it = m_keys.begin(), 152 end = m_keys.end(); 153 auto next = it; 154 for (; it != end; it=next) { 155 ++next; 156 if (((frame >= it->frame()) && 157 (next == end || frame < next->frame())) || 158 (frame < it->frame())) { 159 return it; 160 } 161 } 162 return end; 163 } 164 fromFrame()165 frame_t fromFrame() const { 166 if (!m_keys.empty()) 167 return m_keys.front().frame(); 168 else 169 return -1; 170 } 171 toFrame()172 frame_t toFrame() const { 173 if (!m_keys.empty()) 174 return m_keys.back().frame(); 175 else 176 return -1; 177 } 178 range(const frame_t from,const frame_t to)179 Range range(const frame_t from, 180 const frame_t to) { 181 return Range(getIterator(from), end(), from, to); 182 } 183 184 private: 185 List m_keys; 186 187 // Disable operator= 188 DISABLE_COPYING(Keyframes); 189 }; 190 191 } // namespace doc 192 193 #endif 194