diff --git a/project/Easy2D/Easy2D.vcxproj b/project/Easy2D/Easy2D.vcxproj
index 1c9388ff..50697a0b 100644
--- a/project/Easy2D/Easy2D.vcxproj
+++ b/project/Easy2D/Easy2D.vcxproj
@@ -7,6 +7,7 @@
+
diff --git a/project/Easy2D/Easy2D.vcxproj.filters b/project/Easy2D/Easy2D.vcxproj.filters
index 0453e1d6..31e88199 100644
--- a/project/Easy2D/Easy2D.vcxproj.filters
+++ b/project/Easy2D/Easy2D.vcxproj.filters
@@ -217,6 +217,9 @@
math
+
+ core
+
diff --git a/src/core/ActionGroup.cpp b/src/core/ActionGroup.cpp
index e9dbd3b8..44fd0ee8 100644
--- a/src/core/ActionGroup.cpp
+++ b/src/core/ActionGroup.cpp
@@ -182,9 +182,13 @@ namespace easy2d
void Sequence::Add(Array 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 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);
}
}
diff --git a/src/core/Animation.cpp b/src/core/Animation.cpp
index 678959e3..cb052fca 100644
--- a/src/core/Animation.cpp
+++ b/src/core/Animation.cpp
@@ -76,8 +76,8 @@ namespace easy2d
E2D_ASSERT(dynamic_cast(target) && "Animation only supports Sprites");
const auto& frames = frames_->GetFrames();
- size_t size = frames.size();
- size_t index = std::min(static_cast(math::Floor(size * step)), size - 1);
+ int size = frames.size();
+ int index = std::min(static_cast(math::Floor(size * step)), size - 1);
static_cast(target)->Load(frames[index]);
}
diff --git a/src/core/Array.h b/src/core/Array.h
new file mode 100644
index 00000000..988df825
--- /dev/null
+++ b/src/core/Array.h
@@ -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>
+ 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;
+ using const_reverse_iterator = std::reverse_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_;
+ };
+}
diff --git a/src/core/Canvas.cpp b/src/core/Canvas.cpp
index c1dfad40..68e25302 100644
--- a/src/core/Canvas.cpp
+++ b/src/core/Canvas.cpp
@@ -422,12 +422,9 @@ namespace easy2d
{
if (current_sink_ && !points.empty())
{
- auto d2d_points = reinterpret_cast const&>(points);
- auto size = d2d_points.size();
-
current_sink_->AddLines(
- &d2d_points[0],
- static_cast(size)
+ reinterpret_cast(&points[0]),
+ static_cast(points.size())
);
}
}
diff --git a/src/core/Frames.cpp b/src/core/Frames.cpp
index c700c445..f90e71bb 100644
--- a/src/core/Frames.cpp
+++ b/src/core/Frames.cpp
@@ -49,9 +49,13 @@ namespace easy2d
void Frames::Add(Array 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);
}
}
diff --git a/src/core/Geometry.cpp b/src/core/Geometry.cpp
index 76387963..4a8d839c 100644
--- a/src/core/Geometry.cpp
+++ b/src/core/Geometry.cpp
@@ -328,12 +328,9 @@ namespace easy2d
{
if (current_sink_ && !points.empty())
{
- auto d2d_points = reinterpret_cast const&>(points);
- auto size = d2d_points.size();
-
current_sink_->AddLines(
- &d2d_points[0],
- static_cast(size)
+ reinterpret_cast(&points[0]),
+ static_cast(points.size())
);
}
}
diff --git a/src/core/Object.cpp b/src/core/Object.cpp
index e9a41c6d..2a956d51 100644
--- a/src/core/Object.cpp
+++ b/src/core/Object.cpp
@@ -30,6 +30,7 @@ namespace easy2d
Object::Object()
: tracing_leak_(false)
+ , user_data_(nullptr)
{
#ifdef E2D_DEBUG
diff --git a/src/core/helper.hpp b/src/core/helper.hpp
index 6fc580aa..f8828b12 100644
--- a/src/core/helper.hpp
+++ b/src/core/helper.hpp
@@ -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
using Pair = std::pair;
- template
- using Array = std::vector;
-
template
using List = std::list;
diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp
index 78e11b5e..181de680 100644
--- a/src/ui/Menu.cpp
+++ b/src/ui/Menu.cpp
@@ -43,7 +43,7 @@ namespace easy2d
return enabled_;
}
- size_t Menu::GetButtonCount() const
+ int Menu::GetButtonCount() const
{
return buttons_.size();
}
diff --git a/src/ui/Menu.h b/src/ui/Menu.h
index fefd7828..56fc562a 100644
--- a/src/ui/Menu.h
+++ b/src/ui/Menu.h
@@ -40,7 +40,7 @@ namespace easy2d
bool IsEnable() const;
// 获取菜单中的按钮数量
- size_t GetButtonCount() const;
+ int GetButtonCount() const;
// 设置菜单启用或禁用
void SetEnabled(
diff --git a/src/utils/ResLoader.cpp b/src/utils/ResLoader.cpp
index 014f6fc5..16e661a3 100644
--- a/src/utils/ResLoader.cpp
+++ b/src/utils/ResLoader.cpp
@@ -79,33 +79,40 @@ namespace easy2d
return 0;
int total = 0;
- FramesPtr frames = new (std::nothrow) Frames;
- if (frames)
- {
- for (const auto& image : images)
- {
- ImagePtr ptr = new (std::nothrow) Image;
- if (ptr)
- {
- if (image.IsFile())
- {
- String path = Search(image.GetFileName(), search_paths_);
- ptr->Load(path.c_str());
- }
- else
- ptr->Load(image);
+ Array image_arr;
- if (ptr->IsValid())
- {
- frames->Add(ptr);
- ++total;
- }
+ image_arr.reserve(images.size());
+ for (const auto& image : images)
+ {
+ ImagePtr ptr = new (std::nothrow) Image;
+ if (ptr)
+ {
+ if (image.IsFile())
+ {
+ String path = Search(image.GetFileName(), search_paths_);
+ ptr->Load(path.c_str());
+ }
+ else
+ ptr->Load(image);
+
+ if (ptr->IsValid())
+ {
+ image_arr.push_back(ptr);
+ ++total;
}
}
}
+
if (total)
- res_.insert(std::make_pair(id, frames));
- return 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 const& images)
@@ -113,22 +120,13 @@ namespace easy2d
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)