mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 21:21:17 +01:00
# Description In the text input branch I realized I needed to re-use RectanglesToContour and that it would be called often when moving selection ranged cursors. The existing implementation closely matches our Dart one which is not very memory efficient, mostly due to it just being Dart. # Details - Try to store re-used containers on the RectanglesToContour class so allocation can happen less frequently when re-using the RectanglesToContour. - Try to avoid any forced heap allocation (although some is still bound to happen). - We had a lot of Vectors of Vectors. In almost all cases these got simplified to linear vectors or vectors of structs/classes. Because each vector does its own heap allocation, vector<vector<vector<...>>> can cause a lot of memory re-alloc when adding/removing elements. - The boolean inclusion vector got converted to a bitset which is also stored on the class so it can be re-used. - Nuke Rect as we have the same functionality in AABB. - Massaged the API a bit to have names match the updated API a little more closely. I'll add more comments inline below... Diffs= 5c4e83502f Make RectanglesToContour more memory efficient (particularly for re-runs). (#9438) Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
105 lines
2.5 KiB
C++
105 lines
2.5 KiB
C++
/*
|
|
* Copyright 2022 Rive
|
|
*/
|
|
|
|
#ifndef _RIVE_SPAN_HPP_
|
|
#define _RIVE_SPAN_HPP_
|
|
|
|
#include "rive/rive_types.hpp"
|
|
|
|
#include <initializer_list>
|
|
#include <type_traits>
|
|
#include <iterator>
|
|
|
|
/*
|
|
* Span : cheap impl of std::span (which is C++20)
|
|
*
|
|
* Inspired by Skia's SkSpan
|
|
*/
|
|
|
|
namespace rive
|
|
{
|
|
|
|
template <typename T> class Span
|
|
{
|
|
T* m_Ptr;
|
|
size_t m_Size;
|
|
|
|
public:
|
|
Span() : m_Ptr(nullptr), m_Size(0) {}
|
|
Span(T* ptr, size_t size) : m_Ptr(ptr), m_Size(size)
|
|
{
|
|
assert(ptr <= ptr + size);
|
|
}
|
|
|
|
// Handle Span<foo> --> Span<const foo>
|
|
template <typename U,
|
|
typename = typename std::enable_if<
|
|
std::is_same<const U, T>::value>::type>
|
|
constexpr Span(const Span<U>& that) : Span(that.data(), that.size())
|
|
{}
|
|
template <typename Container>
|
|
constexpr Span(Container& c) : Span(c.data(), c.size())
|
|
{}
|
|
|
|
T& operator[](size_t index) const
|
|
{
|
|
assert(index < m_Size);
|
|
return m_Ptr[index];
|
|
}
|
|
|
|
constexpr T* data() const { return m_Ptr; }
|
|
constexpr size_t size() const { return m_Size; }
|
|
constexpr bool empty() const { return m_Size == 0; }
|
|
|
|
constexpr T* begin() const { return m_Ptr; }
|
|
constexpr T* end() const { return m_Ptr + m_Size; }
|
|
|
|
constexpr T& front() const { return (*this)[0]; }
|
|
constexpr T& back() const { return (*this)[m_Size - 1]; }
|
|
|
|
// returns byte-size of the entire span
|
|
constexpr size_t size_bytes() const { return m_Size * sizeof(T); }
|
|
|
|
constexpr size_t count() const { return m_Size; }
|
|
|
|
Span<T> subset(size_t offset, size_t size) const
|
|
{
|
|
assert(offset <= m_Size);
|
|
assert(size <= m_Size - offset);
|
|
return {m_Ptr + offset, size};
|
|
}
|
|
|
|
// Makes rive::Span std::Container compatible
|
|
// https://en.cppreference.com/w/cpp/named_req/Container
|
|
typedef typename std::remove_cv<T>::type value_type;
|
|
typedef T& reference;
|
|
typedef T const& const_reference;
|
|
typedef T* iterator;
|
|
typedef T const* const_iterator;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef size_t size_type;
|
|
|
|
bool operator!=(const Span<T>& that) const
|
|
{
|
|
return m_Ptr != that.m_Ptr || m_Size != that.m_Size;
|
|
}
|
|
bool operator==(const Span<T>& that) const
|
|
{
|
|
return m_Ptr == that.m_Ptr && m_Size == that.m_Size;
|
|
}
|
|
};
|
|
|
|
template <typename T> Span<T> make_span(T* ptr, size_t size)
|
|
{
|
|
return Span<T>(ptr, size);
|
|
}
|
|
|
|
template <typename T, size_t N> Span<T> make_span(T (&ptr)[N])
|
|
{
|
|
return Span<T>(ptr, N);
|
|
}
|
|
} // namespace rive
|
|
|
|
#endif
|