add Array, a lightweight std::vector<>-like class
This commit is contained in:
parent
fe2769e377
commit
1f751d654f
|
|
@ -7,6 +7,7 @@
|
|||
<ClInclude Include="..\..\src\core\ActionTween.h" />
|
||||
<ClInclude Include="..\..\src\core\ActionManager.h" />
|
||||
<ClInclude Include="..\..\src\core\Animation.h" />
|
||||
<ClInclude Include="..\..\src\core\Array.h" />
|
||||
<ClInclude Include="..\..\src\core\audio.h" />
|
||||
<ClInclude Include="..\..\src\core\Canvas.h" />
|
||||
<ClInclude Include="..\..\src\core\closure.hpp" />
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@
|
|||
<ClInclude Include="..\..\src\math\Matrix.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\Array.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\Animation.cpp">
|
||||
|
|
|
|||
|
|
@ -182,9 +182,13 @@ namespace easy2d
|
|||
|
||||
void Sequence::Add(Array<ActionPtr> const& actions)
|
||||
{
|
||||
for (const auto &action : actions)
|
||||
if (actions_.empty())
|
||||
actions_ = actions;
|
||||
else
|
||||
{
|
||||
this->Add(action);
|
||||
actions_.reserve(actions_.size() + actions.size());
|
||||
for (const auto& action : actions)
|
||||
Add(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ namespace easy2d
|
|||
{
|
||||
Action::Update(target, dt);
|
||||
|
||||
size_t done_num = 0;
|
||||
int done_num = 0;
|
||||
for (const auto& action : actions_)
|
||||
{
|
||||
if (action->IsDone())
|
||||
|
|
@ -291,9 +295,13 @@ namespace easy2d
|
|||
|
||||
void Spawn::Add(Array<ActionPtr> const& actions)
|
||||
{
|
||||
for (const auto &action : actions)
|
||||
if (actions_.empty())
|
||||
actions_ = actions;
|
||||
else
|
||||
{
|
||||
this->Add(action);
|
||||
actions_.reserve(actions_.size() + actions.size());
|
||||
for (const auto& action : actions)
|
||||
Add(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ namespace easy2d
|
|||
E2D_ASSERT(dynamic_cast<Sprite*>(target) && "Animation only supports Sprites");
|
||||
|
||||
const auto& frames = frames_->GetFrames();
|
||||
size_t size = frames.size();
|
||||
size_t index = std::min(static_cast<size_t>(math::Floor(size * step)), size - 1);
|
||||
int size = frames.size();
|
||||
int index = std::min(static_cast<int>(math::Floor(size * step)), size - 1);
|
||||
|
||||
static_cast<Sprite*>(target)->Load(frames[index]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "macros.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
//
|
||||
// Array
|
||||
// Lightweight std::vector<>-like class
|
||||
//
|
||||
template<typename _Ty, typename _Alloc = std::allocator<_Ty>>
|
||||
class Array : _Alloc
|
||||
{
|
||||
public:
|
||||
using value_type = _Ty;
|
||||
using allocator_type = _Alloc;
|
||||
using iterator = value_type*;
|
||||
using const_iterator = const value_type*;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
inline Array() { size_ = capacity_ = 0; data_ = nullptr; }
|
||||
inline Array(std::initializer_list<_Ty> const& list) { size_ = capacity_ = 0; data_ = nullptr; operator=(list); }
|
||||
inline Array(const Array<_Ty>& src) { size_ = capacity_ = 0; data_ = nullptr; operator=(src); }
|
||||
inline Array(Array<_Ty>&& src) { size_ = capacity_ = 0; data_ = nullptr; operator=(src); }
|
||||
inline ~Array() { if (data_) _destroy_all(); }
|
||||
|
||||
inline Array<_Ty>& operator=(const Array<_Ty>& src) { if (&src == this) { return *this; } clear(); reserve(src.size_); std::uninitialized_copy(src.begin(), src.end(), begin()); size_ = src.size_; return *this; }
|
||||
inline Array<_Ty>& operator=(Array<_Ty>&& src) { clear(); size_ = src.size_; capacity_ = src.capacity_; data_ = src.data_; src.data_ = src.size_ = src.capacity_ = 0; return *this; }
|
||||
inline Array<_Ty>& operator=(std::initializer_list<_Ty> const& list) { clear(); reserve((int)list.size()); std::uninitialized_copy(list.begin(), list.end(), begin()); size_ = (int)list.size(); return *this; }
|
||||
|
||||
inline bool empty() const { return size_ == 0; }
|
||||
inline int size() const { return size_; }
|
||||
inline int size_in_bytes() const { return size_ * ((int)sizeof(_Ty)); }
|
||||
inline int capacity() const { return capacity_; }
|
||||
inline reference operator[](int i) { if (i < 0 || i >= size_) throw std::out_of_range("vector subscript out of range"); return data_[i]; }
|
||||
inline const_reference operator[](int i) const { if (i < 0 || i >= size_) throw std::out_of_range("vector subscript out of range"); return data_[i]; }
|
||||
|
||||
inline void clear() { if (data_) { _destroy_all(); } }
|
||||
inline iterator begin() { return iterator(data_); }
|
||||
inline const_iterator begin() const { return const_iterator(data_); }
|
||||
inline const_iterator cbegin() const { return begin(); }
|
||||
inline iterator end() { return iterator(data_ + size_); }
|
||||
inline const_iterator end() const { return const_iterator(data_ + size_); }
|
||||
inline const_iterator cend() const { return end(); }
|
||||
inline reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
inline const_reverse_iterator crbegin() const { return rbegin(); }
|
||||
inline reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
inline const_reverse_iterator crend() const { return rend(); }
|
||||
inline reference front() { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; }
|
||||
inline const_reference front() const { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; }
|
||||
inline reference back() { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; }
|
||||
inline const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; }
|
||||
inline void swap(Array<_Ty>& rhs) { int rhs_size = rhs.size_; rhs.size_ = size_; size_ = rhs_size; int rhs_cap = rhs.capacity_; rhs.capacity_ = capacity_; capacity_ = rhs_cap; _Ty* rhs_data = rhs.data_; rhs.data_ = data_; data_ = rhs_data; }
|
||||
|
||||
inline void resize(int new_size) { if (new_size > capacity_) { reserve(_grow_capacity(new_size)); } _Ty tmp; std::uninitialized_fill_n(data_ + size_, new_size - size_, tmp); size_ = new_size; }
|
||||
inline void resize(int new_size, const _Ty& v) { if (new_size > capacity_) reserve(_grow_capacity(new_size)); if (new_size > size_) std::uninitialized_fill_n(data_ + size_, new_size - size_, v); size_ = new_size; }
|
||||
inline void reserve(int new_capacity) { if (new_capacity <= capacity_) return; _Ty* new_data = _Alloc::allocate(new_capacity); if (data_) { ::memcpy(new_data, data_, (size_t)size_ * sizeof(_Ty)); _Alloc::deallocate(data_, capacity_); } data_ = new_data; capacity_ = new_capacity; }
|
||||
|
||||
inline void push_back(const _Ty& v) { if (size_ == capacity_) reserve(_grow_capacity(size_ + 1)); _Alloc::construct(data_ + size_, v); size_++; }
|
||||
inline void pop_back() { if (empty()) throw std::out_of_range("vector empty before pop"); size_--; }
|
||||
inline void push_front(const _Ty& v) { if (size_ == 0) push_back(v); else insert(data_, v); }
|
||||
inline iterator erase(const_iterator it) { E2D_ASSERT(it >= data_ && it < data_ + size_); _Alloc::destroy(it); const ptrdiff_t off = it - data_; ::memmove(data_ + off, data_ + off + 1, ((size_t)size_ - (size_t)off - 1) * sizeof(_Ty)); size_--; return data_ + off; }
|
||||
inline iterator erase(const_iterator it, const_iterator it_last) { E2D_ASSERT(it >= data_ && it < data_ + size_ && it_last > it && it_last <= data_ + size_); _destroy(it, it_last); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - data_; ::memmove(data_ + off, data_ + off + count, ((size_t)size_ - (size_t)off - count) * sizeof(_Ty)); size_ -= (int)count; return data_ + off; }
|
||||
inline iterator insert(const_iterator it, const _Ty& v) { E2D_ASSERT(it >= data_ && it <= data_ + size_); const ptrdiff_t off = it - data_; if (size_ == capacity_) reserve(_grow_capacity(size_ + 1)); if (off < (int)size_) ::memmove(data_ + off + 1, data_ + off, ((size_t)size_ - (size_t)off) * sizeof(_Ty)); _Alloc::construct(data_ + off, v); size_++; return data_ + off; }
|
||||
inline bool contains(const _Ty& v) const { const _Ty* data = data_; const _Ty* data_end = data_ + size_; while (data < data_end) if (*data++ == v) return true; return false; }
|
||||
inline int index_of(const_iterator it) const { E2D_ASSERT(it >= data_ && it <= data_ + size_); const ptrdiff_t off = it - data_; return (int)off; }
|
||||
|
||||
private:
|
||||
inline int _grow_capacity(int sz) const { int new_capacity = capacity_ ? (capacity_ + capacity_ / 2) : 8; return new_capacity > sz ? new_capacity : sz; }
|
||||
inline void _destroy(iterator it, iterator it_last) { E2D_ASSERT(it >= data_ && it < data_ + size_ && it_last > it && it_last <= data_ + size_); for (; it != it_last; ++it) _Alloc::destroy(it); }
|
||||
inline void _destroy_all() { E2D_ASSERT((data_ && capacity_) || (!data_ && !capacity_)); if (size_) _destroy(begin(), end()); if (data_ && capacity_) _Alloc::deallocate(data_, capacity_); size_ = capacity_ = 0; data_ = nullptr; }
|
||||
|
||||
private:
|
||||
int size_;
|
||||
int capacity_;
|
||||
_Ty* data_;
|
||||
};
|
||||
}
|
||||
|
|
@ -422,12 +422,9 @@ namespace easy2d
|
|||
{
|
||||
if (current_sink_ && !points.empty())
|
||||
{
|
||||
auto d2d_points = reinterpret_cast<Array<D2D_POINT_2F> const&>(points);
|
||||
auto size = d2d_points.size();
|
||||
|
||||
current_sink_->AddLines(
|
||||
&d2d_points[0],
|
||||
static_cast<UINT32>(size)
|
||||
reinterpret_cast<const D2D_POINT_2F*>(&points[0]),
|
||||
static_cast<UINT32>(points.size())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,9 +49,13 @@ namespace easy2d
|
|||
|
||||
void Frames::Add(Array<ImagePtr> const& frames)
|
||||
{
|
||||
for (const auto &image : frames)
|
||||
if (frames_.empty())
|
||||
frames_ = frames;
|
||||
else
|
||||
{
|
||||
this->Add(image);
|
||||
frames_.reserve(frames_.size() + frames.size());
|
||||
for (const auto& image : frames)
|
||||
Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,12 +328,9 @@ namespace easy2d
|
|||
{
|
||||
if (current_sink_ && !points.empty())
|
||||
{
|
||||
auto d2d_points = reinterpret_cast<Array<D2D_POINT_2F> const&>(points);
|
||||
auto size = d2d_points.size();
|
||||
|
||||
current_sink_->AddLines(
|
||||
&d2d_points[0],
|
||||
static_cast<UINT32>(size)
|
||||
reinterpret_cast<const D2D_POINT_2F*>(&points[0]),
|
||||
static_cast<UINT32>(points.size())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace easy2d
|
|||
|
||||
Object::Object()
|
||||
: tracing_leak_(false)
|
||||
, user_data_(nullptr)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
#include "RefCounter.hpp"
|
||||
#include "IntrusivePtr.hpp"
|
||||
#include "Array.h"
|
||||
#include "closure.hpp"
|
||||
#include "../math/vector.hpp"
|
||||
#include "../math/Rect.hpp"
|
||||
|
|
@ -53,9 +54,6 @@ namespace easy2d
|
|||
template<typename Type1, typename Type2>
|
||||
using Pair = std::pair<Type1, Type2>;
|
||||
|
||||
template<typename Type>
|
||||
using Array = std::vector<Type>;
|
||||
|
||||
template<typename Type>
|
||||
using List = std::list<Type>;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace easy2d
|
|||
return enabled_;
|
||||
}
|
||||
|
||||
size_t Menu::GetButtonCount() const
|
||||
int Menu::GetButtonCount() const
|
||||
{
|
||||
return buttons_.size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace easy2d
|
|||
bool IsEnable() const;
|
||||
|
||||
// 获取菜单中的按钮数量
|
||||
size_t GetButtonCount() const;
|
||||
int GetButtonCount() const;
|
||||
|
||||
// 设置菜单启用或禁用
|
||||
void SetEnabled(
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ namespace easy2d
|
|||
return 0;
|
||||
|
||||
int total = 0;
|
||||
FramesPtr frames = new (std::nothrow) Frames;
|
||||
if (frames)
|
||||
{
|
||||
Array<ImagePtr> image_arr;
|
||||
|
||||
image_arr.reserve(images.size());
|
||||
for (const auto& image : images)
|
||||
{
|
||||
ImagePtr ptr = new (std::nothrow) Image;
|
||||
|
|
@ -97,38 +97,36 @@ namespace easy2d
|
|||
|
||||
if (ptr->IsValid())
|
||||
{
|
||||
frames->Add(ptr);
|
||||
image_arr.push_back(ptr);
|
||||
++total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (total)
|
||||
{
|
||||
FramesPtr frames = new (std::nothrow) Frames(image_arr);
|
||||
if (frames)
|
||||
{
|
||||
res_.insert(std::make_pair(id, frames));
|
||||
return total;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ResLoader::AddFrames(String const& id, Array<ImagePtr> const& images)
|
||||
{
|
||||
if (images.empty())
|
||||
return 0;
|
||||
|
||||
int total = 0;
|
||||
FramesPtr frames = new (std::nothrow) Frames;
|
||||
FramesPtr frames = new (std::nothrow) Frames(images);
|
||||
if (frames)
|
||||
{
|
||||
for (const auto& image : images)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
frames->Add(image);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (total)
|
||||
res_.insert(std::make_pair(id, frames));
|
||||
return total;
|
||||
return frames->GetFrames().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ResLoader::AddFrames(String const & id, Resource const & image, int cols, int rows)
|
||||
|
|
|
|||
Loading…
Reference in New Issue