Improve code quality (stage1.Oct) (#916)

* Improve code quality

* Add env PULL_REQUEST [skip ci]

* Update build.ps1

* Fix ci [skip ci]

* Update ZipUtils.cpp

* Update build.ps1

* Resolve reviews

* Improve

* Improve code style

* Resolve reviews

* Use pod_vector

* Improve resize growth

* Update CCAnimation3D.cpp

* Update axstd.h [skip ci]
This commit is contained in:
涓€绾跨伒|Deal 2022-10-13 21:44:42 +08:00 committed by GitHub
parent ba95ca98cf
commit 25d93bd509
25 changed files with 448 additions and 135 deletions

View File

@ -10,6 +10,7 @@ env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
PYENV_VERSION: 2.7.18
PULL_REQUEST: yes
jobs:
build-windows:

View File

@ -120,10 +120,8 @@ bool MotionStreak::initWithFade(float fade, float minSeg, float stroke, const Co
_colorPointer = (uint8_t*)malloc(sizeof(uint8_t) * 4 * _vertexCount);
_customCommand.createVertexBuffer(VERTEX_SIZE, _vertexCount, CustomCommand::BufferUsage::DYNAMIC);
std::vector<uint8_t> zeros;
zeros.resize(VERTEX_SIZE * _vertexCount);
std::fill(zeros.begin(), zeros.end(), 0);
_customCommand.updateVertexBuffer(zeros.data(), zeros.size());
auto zeros = std::make_unique<uint8_t[]>(VERTEX_SIZE * _vertexCount);
_customCommand.updateVertexBuffer(zeros.get(), VERTEX_SIZE * _vertexCount);
setTexture(texture);
setColor(color);

View File

@ -148,7 +148,7 @@ void SpriteFrameCache::removeSpriteFrames()
void SpriteFrameCache::removeUnusedSpriteFrames()
{
auto removed = false;
std::vector<std::string> toRemoveFrames;
std::vector<std::string_view> toRemoveFrames;
const auto& frames = getSpriteFrames();
for (auto&& iter : frames)
@ -211,7 +211,7 @@ void SpriteFrameCache::removeSpriteFramesFromDictionary(ValueMap& dictionary)
return;
const auto& framesDict = dictionary["frames"].asValueMap();
std::vector<std::string> keysToRemove;
std::vector<std::string_view> keysToRemove;
for (const auto& iter : framesDict)
{
@ -226,7 +226,7 @@ void SpriteFrameCache::removeSpriteFramesFromDictionary(ValueMap& dictionary)
void SpriteFrameCache::removeSpriteFramesFromTexture(Texture2D* texture)
{
std::vector<std::string> keysToRemove;
std::vector<std::string_view> keysToRemove;
for (auto&& iter : getSpriteFrames())
{
@ -321,7 +321,7 @@ bool SpriteFrameCache::eraseFrame(std::string_view frameName)
return false;
}
bool SpriteFrameCache::eraseFrames(const std::vector<std::string>& frames)
bool SpriteFrameCache::eraseFrames(const std::vector<std::string_view>& frames)
{
auto ret = false;
for (const auto& frame : frames)

View File

@ -274,7 +274,7 @@ protected:
/** Delete a list of frames from cache, rebuild index
*/
bool eraseFrames(const std::vector<std::string>& frame);
bool eraseFrames(const std::vector<std::string_view>& frame);
/** Delete frame from index and SpriteFrame is kept.
*/
bool removeSpriteSheet(std::string_view spriteSheetFileName);

View File

@ -1,6 +1,7 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
Copyright (c) 2022 Bytedance Inc.
https://axmolengine.github.io/
@ -26,6 +27,7 @@
#include "3d/CCAnimation3D.h"
#include "3d/CCBundle3D.h"
#include "platform/CCFileUtils.h"
#include "base/axstd.h"
NS_AX_BEGIN
@ -102,83 +104,83 @@ bool Animation3D::init(const Animation3DData& data)
{
_duration = data._totalTime;
for (const auto& iter : data._translationKeys)
{
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
axstd::pod_vector<float> keys;
axstd::pod_vector<Vec3> values;
for (const auto& iter : data._translationKeys)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if (iter.second.empty())
continue;
std::vector<float> keys;
std::vector<float> values;
for (const auto& keyIter : iter.second)
{
keys.emplace_back(keyIter._time);
values.emplace_back(keyIter._key.x);
values.emplace_back(keyIter._key.y);
values.emplace_back(keyIter._key.z);
}
if (iter.second.empty())
continue;
curve->translateCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0], (int)keys.size());
if (curve->translateCurve)
curve->translateCurve->retain();
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys,
[](const auto& keyIter) { return keyIter._time; });
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values,
[](const auto& keyIter) { return keyIter._key; });
curve->translateCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size());
if (curve->translateCurve)
curve->translateCurve->retain();
}
}
for (const auto& iter : data._rotationKeys)
{
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
axstd::pod_vector<float> keys;
axstd::pod_vector<Quaternion> values;
for (const auto& iter : data._rotationKeys)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if (iter.second.empty())
continue;
std::vector<float> keys;
std::vector<float> values;
for (const auto& keyIter : iter.second)
{
keys.emplace_back(keyIter._time);
values.emplace_back(keyIter._key.x);
values.emplace_back(keyIter._key.y);
values.emplace_back(keyIter._key.z);
values.emplace_back(keyIter._key.w);
}
if (iter.second.empty())
continue;
curve->rotCurve = Curve::AnimationCurveQuat::create(&keys[0], &values[0], (int)keys.size());
if (curve->rotCurve)
curve->rotCurve->retain();
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys,
[](const auto& keyIter) { return keyIter._time; });
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values,
[](const auto& keyIter) { return keyIter._key; });
curve->rotCurve = Curve::AnimationCurveQuat::create(&keys[0], &values[0].x, (int)keys.size());
if (curve->rotCurve)
curve->rotCurve->retain();
}
}
for (const auto& iter : data._scaleKeys)
{
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
axstd::pod_vector<float> keys;
axstd::pod_vector<Vec3> values;
for (const auto& iter : data._scaleKeys)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
Curve* curve = _boneCurves[iter.first];
if (curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if (iter.second.empty())
continue;
std::vector<float> keys;
std::vector<float> values;
for (const auto& keyIter : iter.second)
{
keys.emplace_back(keyIter._time);
values.emplace_back(keyIter._key.x);
values.emplace_back(keyIter._key.y);
values.emplace_back(keyIter._key.z);
}
if (iter.second.empty())
continue;
curve->scaleCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0], (int)keys.size());
if (curve->scaleCurve)
curve->scaleCurve->retain();
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys,
[](const auto& keyIter) { return keyIter._time; });
axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values,
[](const auto& keyIter) { return keyIter._key; });
curve->scaleCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size());
if (curve->scaleCurve)
curve->scaleCurve->retain();
}
}
return true;

View File

@ -162,33 +162,39 @@ Mesh* Mesh::create(const std::vector<float>& positions,
int perVertexSizeInFloat = 0;
std::vector<float> vertices;
std::vector<MeshVertexAttrib> attribs;
MeshVertexAttrib att;
att.type = backend::VertexFormat::FLOAT3;
if (positions.size())
attribs.reserve(3);
size_t hasNormal = 0;
size_t hasTexCoord = 0;
if (!positions.empty())
{
perVertexSizeInFloat += 3;
att.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION;
attribs.emplace_back(att);
}
if (normals.size())
if (!normals.empty())
{
perVertexSizeInFloat += 3;
att.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL;
attribs.emplace_back(att);
hasNormal = 1;
}
if (texs.size())
if (!texs.empty())
{
perVertexSizeInFloat += 2;
att.type = backend::VertexFormat::FLOAT2;
att.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD;
attribs.emplace_back(att);
hasTexCoord = 1;
}
bool hasNormal = (normals.size() != 0);
bool hasTexCoord = (texs.size() != 0);
// position, normal, texCoordinate into _vertexs
size_t vertexNum = positions.size() / 3;
vertices.reserve(positions.size() + hasNormal * 3 + hasTexCoord * 2);
for (size_t i = 0; i < vertexNum; i++)
{
vertices.emplace_back(positions[i * 3]);
@ -341,8 +347,8 @@ void Mesh::setMaterial(Material* material)
{
// allocate MeshCommand vector for technique
// allocate MeshCommand for each pass
_meshCommands[technique->getName()] = std::vector<MeshCommand>(technique->getPasses().size());
auto& list = _meshCommands[technique->getName()];
list.resize(technique->getPasses().size());
int i = 0;
for (auto&& pass : technique->getPasses())

View File

@ -37,6 +37,7 @@ USING_NS_AX;
#include "renderer/backend/Buffer.h"
#include "base/CCDirector.h"
#include "base/ccTypes.h"
#include "base/axstd.h"
#include "base/CCEventType.h"
#include "2d/CCCamera.h"
#include "platform/CCImage.h"
@ -1322,11 +1323,8 @@ void Terrain::Chunk::updateIndicesLOD()
void Terrain::Chunk::calculateAABB()
{
std::vector<Vec3> pos;
for (size_t i = 0, size = _originalVertices.size(); i < size; ++i)
{
pos.emplace_back(_originalVertices[i]._position);
}
auto pos = axstd::pod_vector_from<Vec3>(_originalVertices.begin(), _originalVertices.end(),
[](const auto& it) { return it._position; });
_aabb.updateMinMax(&pos[0], pos.size());
}

View File

@ -189,6 +189,7 @@ endif()
add_subdirectory(${_AX_ROOT_PATH}/extensions ${ENGINE_BINARY_PATH}/extensions)
if(MSVC)
target_sources(${_AX_CORE_LIB} PRIVATE ./axmol.natvis)
target_sources(${_AX_CORE_LIB} PRIVATE ../thirdparty/yasio/yasio.natvis)
target_sources(${_AX_CORE_LIB} PRIVATE ../thirdparty/robin-map/tsl-robin-map.natvis)
target_compile_options(${_AX_CORE_LIB} PUBLIC "/Zm2000")

14
core/axmol.natvis Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="axstd::pod_vector&lt;*&gt;">
<DisplayString>{{ size={_Mylast - _Myfirst} capacity={_Myend - _Myfirst} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
<Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
<ArrayItems>
<Size>_Mylast - _Myfirst</Size>
<ValuePointer>_Myfirst</ValuePointer>
</ArrayItems>
</Expand>
</Type>
</AutoVisualizer>

View File

@ -958,8 +958,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event)
bool isNeedsMutableSet = (oneByOneListeners && allAtOnceListeners);
const std::vector<Touch*>& originalTouches = event->getTouches();
std::vector<Touch*> mutableTouches(originalTouches.size());
std::copy(originalTouches.begin(), originalTouches.end(), mutableTouches.begin());
auto mutableTouches = originalTouches;
//
// process the target handlers 1st
@ -1486,7 +1485,7 @@ void EventDispatcher::removeCustomEventListeners(std::string_view customEventNam
void EventDispatcher::removeAllEventListeners()
{
bool cleanMap = true;
std::vector<EventListener::ListenerID> types;
std::vector<std::string_view> types;
types.reserve(_listenerMap.size());
for (const auto& e : _listenerMap)

View File

@ -40,9 +40,9 @@ USING_NS_AX;
/** @script{ignore} */
void calculateNamespacePath(std::string_view urlString,
std::string& fileString,
std::vector<std::string>& namespacePath);
std::vector<std::string_view>& namespacePath);
/** @script{ignore} */
Properties* getPropertiesFromNamespacePath(Properties* properties, const std::vector<std::string>& namespacePath);
Properties* getPropertiesFromNamespacePath(Properties* properties, const std::vector<std::string_view>& namespacePath);
Properties::Properties() : _dataIdx(nullptr), _data(nullptr), _variables(nullptr), _dirPath(nullptr), _parent(nullptr)
{
@ -108,7 +108,7 @@ Properties* Properties::createNonRefCounted(std::string_view url)
// Calculate the file and full namespace path from the specified url.
auto& urlString = url;
std::string fileString;
std::vector<std::string> namespacePath;
std::vector<std::string_view> namespacePath;
calculateNamespacePath(urlString, fileString, namespacePath);
// data will be released automatically when 'data' goes out of scope
@ -514,7 +514,7 @@ char* Properties::trimWhiteSpace(char* str)
return str;
}
void Properties::resolveInheritance(const char* id)
void Properties::resolveInheritance(std::string_view id)
{
// Namespaces can be defined like so:
// "name id : parentID { }"
@ -522,7 +522,7 @@ void Properties::resolveInheritance(const char* id)
// Get a top-level namespace.
Properties* derived;
if (id)
if (!id.empty())
{
derived = getNamespace(id);
}
@ -551,7 +551,7 @@ void Properties::resolveInheritance(const char* id)
// Copy data from the parent into the child.
derived->_properties = parent->_properties;
derived->_namespaces = std::vector<Properties*>();
derived->_namespaces.clear();
std::vector<Properties*>::const_iterator itt;
for (const auto space : parent->_namespaces)
{
@ -571,7 +571,7 @@ void Properties::resolveInheritance(const char* id)
derived->resolveInheritance();
// Get the next top-level namespace and check again.
if (!id)
if (id.empty())
{
derived = getNextNamespace();
}
@ -606,8 +606,8 @@ void Properties::mergeWith(Properties* overrides)
Properties* derivedNamespace = getNextNamespace();
while (derivedNamespace)
{
if (strcmp(derivedNamespace->getNamespace(), overridesNamespace->getNamespace()) == 0 &&
strcmp(derivedNamespace->getId(), overridesNamespace->getId()) == 0)
if (derivedNamespace->getNamespace() == overridesNamespace->getNamespace() &&
derivedNamespace->getId() == overridesNamespace->getId())
{
derivedNamespace->mergeWith(overridesNamespace);
merged = true;
@ -672,14 +672,14 @@ void Properties::rewind()
_namespacesItr = _namespaces.end();
}
Properties* Properties::getNamespace(const char* id, bool searchNames, bool recurse) const
Properties* Properties::getNamespace(std::string_view id, bool searchNames, bool recurse) const
{
AXASSERT(id, "invalid id");
AXASSERT(!id.empty(), "invalid id");
for (const auto& it : _namespaces)
{
Properties* p = it;
if (strcmp(searchNames ? p->_namespace.c_str() : p->_id.c_str(), id) == 0)
if ((searchNames ? p->_namespace : p->_id) == id)
return p;
if (recurse)
@ -699,7 +699,7 @@ const char* Properties::getNamespace() const
return _namespace.c_str();
}
const char* Properties::getId() const
std::string_view Properties::getId() const
{
return _id.c_str();
}
@ -1054,7 +1054,7 @@ void Properties::setVariable(const char* name, const char* value)
// Add a new variable with this name
if (!_variables)
_variables = new std::vector<Property>();
_variables->emplace_back(Property(name, value ? value : ""));
_variables->emplace_back(name, value ? std::string_view{value} : ""sv);
}
}
@ -1107,7 +1107,7 @@ void Properties::setDirectoryPath(std::string_view path)
void calculateNamespacePath(std::string_view urlString,
std::string& fileString,
std::vector<std::string>& namespacePath)
std::vector<std::string_view>& namespacePath)
{
// If the url references a specific namespace within the file,
// calculate the full namespace path to the final namespace.
@ -1118,10 +1118,10 @@ void calculateNamespacePath(std::string_view urlString,
auto namespacePathString = urlString.substr(loc + 1);
while ((loc = namespacePathString.find('/')) != std::string::npos)
{
namespacePath.emplace_back(std::string{namespacePathString.substr(0, loc)});
namespacePath.emplace_back(namespacePathString.substr(0, loc));
namespacePathString = namespacePathString.substr(loc + 1);
}
namespacePath.emplace_back(std::string{namespacePathString});
namespacePath.emplace_back(namespacePathString);
}
else
{
@ -1129,7 +1129,7 @@ void calculateNamespacePath(std::string_view urlString,
}
}
Properties* getPropertiesFromNamespacePath(Properties* properties, const std::vector<std::string>& namespacePath)
Properties* getPropertiesFromNamespacePath(Properties* properties, const std::vector<std::string_view>& namespacePath)
{
// If the url references a specific namespace within the file,
// return the specified namespace or notify the user if it cannot be found.
@ -1148,7 +1148,7 @@ Properties* getPropertiesFromNamespacePath(Properties* properties, const std::ve
return nullptr;
}
if (strcmp(iter->getId(), namespacePath[i].c_str()) == 0)
if (iter->getId() == namespacePath[i])
{
if (i != size - 1)
{

View File

@ -226,7 +226,7 @@ public:
*
* @return A properties object with the given ID or name.
*/
Properties* getNamespace(const char* id, bool searchNames = false, bool recurse = true) const;
Properties* getNamespace(std::string_view id, bool searchNames = false, bool recurse = true) const;
/**
* Get the name of this Property's namespace.
@ -241,7 +241,7 @@ public:
*
* @return The ID of this Property's namespace.
*/
const char* getId() const;
std::string_view getId() const;
/**
* Check if a property with the given name is specified in this Properties object.
@ -569,7 +569,7 @@ private:
bool eof();
// Called after createNonRefCounted(); copies info from parents into derived namespaces.
void resolveInheritance(const char* id = NULL);
void resolveInheritance(std::string_view id = std::string_view{});
// Called by resolveInheritance().
void mergeWith(Properties* overrides);

View File

@ -762,7 +762,7 @@ std::vector<std::string> ZipFile::listFiles(std::string_view pathname) const
// filter files which `filename.startsWith(pathname)`
// then make each path unique
std::set<std::string> fileSet;
std::set<std::string_view> fileSet;
ZipFilePrivate::FileListContainer::const_iterator it = _data->fileList.begin();
ZipFilePrivate::FileListContainer::const_iterator end = _data->fileList.end();
// ensure pathname ends with `/` as a directory
@ -777,12 +777,12 @@ std::vector<std::string> ZipFile::listFiles(std::string_view pathname) const
auto pos = suffix.find('/');
if (pos == std::string::npos)
{
fileSet.insert(std::string{suffix});
fileSet.insert(suffix);
}
else
{
// fileSet.insert(parts[0] + "/");
fileSet.insert(std::string{suffix.substr(0, pos + 1)});
fileSet.insert(suffix.substr(0, pos + 1));
}
}
}

50
core/base/axstd.h Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#include <type_traits>
#include <memory>
#include "pod_vector.h"
namespace axstd
{
/* make_unique_for_overwrite since c++20, but not all platformm support */
template <class _Ty, std::enable_if_t<!std::is_array_v<_Ty>, int> = 0>
inline std::unique_ptr<_Ty> make_unique_for_overwrite()
{
// make a unique_ptr with default initialization
return std::unique_ptr<_Ty>(new _Ty);
}
template <class _Ty, std::enable_if_t<std::is_array_v<_Ty> && std::is_trivially_copyable_v<_Ty>, int> = 0>
inline std::unique_ptr<_Ty> make_unique_for_overwrite(const size_t _Size)
{
// make a unique_ptr with default initialization
using _Elem = std::remove_extent_t<_Ty>;
return std::unique_ptr<_Ty>(new _Elem[_Size]);
}
// If the _OutCont is `std::vector`, the resize still with zero filled which is not needs at here
// some follow concepts needs standardized in the future, may be c++23
// - resize_and_overwrite:
// - https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1072r10.html
// - boost vector resize with init behavior parameter
// - https://github.com/boostorg/container/blob/develop/include/boost/container/vector.hpp
// - pod_vector
// -
// https://stackoverflow.com/questions/15219984/using-vectorchar-as-a-buffer-without-initializing-it-on-resize/15220853#15220853
// - https://github.com/yasio/yasio/blob/perftest/tests/perf/pod_vector.h
template <class _InIt, class _OutCont, class _Fn>
inline auto resize_and_transform(const _InIt _First, const _InIt _Last, _OutCont& _Dest, _Fn _Func)
{
auto count = std::distance(_First, _Last);
_Dest.resize(static_cast<size_t>(count));
return std::transform(_First, _Last, _Dest.begin(), _Func);
}
template <class _Ty, class _InIt, class _Fn>
inline pod_vector<_Ty> pod_vector_from(const _InIt _First, const _InIt _Last, _Fn _Func)
{
auto count = std::distance(_First, _Last);
pod_vector<_Ty> dest(static_cast<size_t>(count));
std::transform(_First, _Last, dest.begin(), _Func);
return dest;
}
} // namespace axstd

240
core/base/pod_vector.h Normal file
View File

@ -0,0 +1,240 @@
/****************************************************************************
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Copyright (c) 2022 Bytedance Inc.
https://axmolengine.github.io/
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.
The pod_vector concepts:
a. only accept pod types
b. support release memory ownership with `release_pointer`
c. support pod_allocater with C(realloc) or C++(new/delete)
Copy of https://github.com/microsoft/STL/blob/main/stl/inc/vector but for pod types and only provide
'emplace_back'
*/
#pragma once
#include <string.h>
#include <utility>
#include <new>
#include <type_traits>
#include <stdexcept>
#include <limits>
#include <stdint.h>
namespace axstd
{
template <typename _Ty, bool /*_use_crt_alloc*/ = false>
struct pod_allocator
{
static _Ty* allocate(size_t count) { return (_Ty*)new uint8_t[count * sizeof(_Ty)]; }
static void deallocate(_Ty* pBlock) { delete[](uint8_t*) pBlock; }
};
template <typename _Ty>
struct pod_allocator<_Ty, true>
{
static _Ty* allocate(size_t count) { return malloc(count * sizeof(_Ty)); }
static void deallocate(_Ty* pBlock) { free(pBlock); }
};
template <typename _Ty,
typename _Alty = pod_allocator<_Ty>,
std::enable_if_t<std::is_trivially_copyable_v<_Ty>, int> = 0>
class pod_vector
{
public:
using pointer = _Ty*;
using const_pointer = const _Ty*;
using reference = _Ty&;
using const_reference = const _Ty&;
using size_type = size_t;
using value_type = _Ty;
using iterator = _Ty*; // transparent iterator
using const_iterator = const _Ty*;
pod_vector() = default;
explicit pod_vector(size_t count) { resize_fit(count); }
pod_vector(pod_vector const&) = delete;
pod_vector& operator=(pod_vector const&) = delete;
pod_vector(pod_vector&& o) noexcept : _Myfirst(o._Myfirst), _Mylast(o._Mylast), _Myend(o._Myend)
{
o._Myfirst = nullptr;
o._Mylast = nullptr;
o._Myend = nullptr;
}
pod_vector& operator=(pod_vector&& o) noexcept
{
this->swap(o);
return *this;
}
void swap(pod_vector& rhs) noexcept
{
std::swap(_Myfirst, rhs._Myfirst);
std::swap(_Mylast, rhs._Mylast);
std::swap(_Myend, rhs._Myend);
}
~pod_vector() { _Tidy(); }
template <typename... _Valty>
_Ty& emplace_back(_Valty&&... _Val) noexcept
{
if (_Mylast != _Myend)
return *new (_Mylast++) _Ty(std::forward<_Valty>(_Val)...);
return *_Emplace_back_reallocate(std::forward<_Valty>(_Val)...);
}
void reserve(size_t new_cap)
{
if (new_cap > this->capacity())
_Reallocate_exactly(new_cap);
}
void resize(size_t new_size)
{
if (this->capacity() < new_size)
_Reallocate_exactly(_Calculate_growth(new_size));
_Mylast = _Myfirst + new_size;
}
void resize_fit(size_t new_size)
{
if (this->capacity() < new_size)
_Reallocate_exactly(new_size);
_Mylast = _Myfirst + new_size;
}
static constexpr size_t max_size() noexcept { return (std::numeric_limits<ptrdiff_t>::max)(); }
iterator begin() noexcept { return _Myfirst; }
iterator end() noexcept { return _Mylast; }
const_iterator begin() const noexcept { return _Myfirst; }
const_iterator end() const noexcept { return _Mylast; }
pointer data() noexcept { return _Myfirst; }
const_pointer data() const noexcept { return _Myfirst; }
size_t capacity() const noexcept { return _Myend - _Myfirst; }
size_t size() const noexcept { return _Mylast - _Myfirst; }
void clear() noexcept { _Mylast = _Myfirst; }
bool empty() const noexcept { return _Mylast == _Myfirst; }
const_reference operator[](size_t index) const { return _Myfirst[index]; }
reference operator[](size_t index) { return _Myfirst[index]; }
void shrink_to_fit()
{ // reduce capacity to size, provide strong guarantee
const pointer _Oldlast = _Mylast;
if (_Oldlast != _Myend)
{ // something to do
const pointer _Oldfirst = _Myfirst;
if (_Oldfirst == _Oldlast)
_Tidy();
else
_Reallocate_exactly(static_cast<size_type>(_Oldlast - _Oldfirst));
}
}
// release memmory ownership
pointer release_pointer() noexcept
{
auto ptr = _Myfirst;
_Myfirst = nullptr;
_Mylast = nullptr;
_Myend = nullptr;
return ptr;
}
private:
template <class... _Valty>
pointer _Emplace_back_reallocate(_Valty&&... _Val)
{
const auto _Oldsize = static_cast<size_type>(_Mylast - _Myfirst);
if (_Oldsize == max_size())
throw std::length_error("pod_vector too long");
const size_type _Newsize = _Oldsize + 1;
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const pointer _Newvec = _Alty::allocate(_Newcapacity);
const pointer _Newptr = _Newvec + _Oldsize;
new ((void*)_Newptr) _Ty(std::forward<_Valty>(_Val)...);
// at back, provide strong guarantee
std::move(_Myfirst, _Mylast, _Newvec);
_Change_array(_Newvec, _Newsize, _Newcapacity);
return _Newptr;
}
void _Reallocate_exactly(size_t _Newcapacity)
{
const auto _Size = static_cast<size_type>(_Mylast - _Myfirst);
const pointer _Newvec = _Alty::allocate(_Newcapacity);
std::copy(_Myfirst, _Mylast, _Newvec);
_Change_array(_Newvec, _Size, _Newcapacity);
}
void _Change_array(const pointer _Newvec, const size_type _Newsize, const size_type _Newcapacity)
{
if (_Myfirst)
_Alty::deallocate(_Myfirst /*, static_cast<size_type>(_Myend - _Myfirst)*/);
_Myfirst = _Newvec;
_Mylast = _Newvec + _Newsize;
_Myend = _Newvec + _Newcapacity;
}
size_type _Calculate_growth(const size_type _Newsize) const
{
// given _Oldcapacity and _Newsize, calculate geometric growth
const size_type _Oldcapacity = capacity();
const auto _Max = max_size();
if (_Oldcapacity > _Max - _Oldcapacity / 2)
return _Max; // geometric growth would overflow
const size_type _Geometric = _Oldcapacity + (_Oldcapacity >> 1);
if (_Geometric < _Newsize)
return _Newsize; // geometric growth would be insufficient
return _Geometric; // geometric growth is sufficient
}
void _Tidy() noexcept
{ // free all storage
if (_Myfirst)
{ // destroy and deallocate old array
_Alty::deallocate(_Myfirst /*, static_cast<size_type>(_Myend - _Myfirst)*/);
_Myfirst = nullptr;
_Mylast = nullptr;
_Myend = nullptr;
}
}
pointer _Myfirst = nullptr;
pointer _Mylast = nullptr;
pointer _Myend = nullptr;
};
} // namespace axstd

View File

@ -51,7 +51,7 @@ const int PhysicsWorld::DEBUGDRAW_JOINT = 0x02;
const int PhysicsWorld::DEBUGDRAW_CONTACT = 0x04;
const int PhysicsWorld::DEBUGDRAW_ALL = DEBUGDRAW_SHAPE | DEBUGDRAW_JOINT | DEBUGDRAW_CONTACT;
const float _debugDrawThickness = 0.5f; // thickness of the DebugDraw lines, circles, dots, polygons
const float _debugDrawThickness = 0.5f; // thickness of the DebugDraw lines, circles, dots, polygons
namespace
{
@ -349,11 +349,11 @@ bool PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
{
bool ret = true;
PhysicsShape* shapeA = contact.getShapeA();
PhysicsShape* shapeB = contact.getShapeB();
PhysicsBody* bodyA = shapeA->getBody();
PhysicsBody* bodyB = shapeB->getBody();
std::vector<PhysicsJoint*> jointsA = bodyA->getJoints();
PhysicsShape* shapeA = contact.getShapeA();
PhysicsShape* shapeB = contact.getShapeB();
PhysicsBody* bodyA = shapeA->getBody();
PhysicsBody* bodyB = shapeB->getBody();
auto&& jointsA = bodyA->getJoints();
// check the joint is collision enable or not
for (PhysicsJoint* joint : jointsA)

View File

@ -69,6 +69,7 @@ static std::vector<Touch*> getAllTouchesVector()
int i;
int temp = g_indexBitsUsed;
ret.reserve(EventTouch::MAX_TOUCHES);
for (i = 0; i < EventTouch::MAX_TOUCHES; i++)
{
if (temp & 0x00000001)

View File

@ -32,6 +32,7 @@ THE SOFTWARE.
#include <string>
#include <ctype.h>
#include "base/axstd.h"
#include "base/ccConfig.h" // AX_USE_JPEG, AX_USE_WEBP
#define STBI_NO_JPEG
@ -2003,7 +2004,7 @@ bool Image::initWithS3TCData(uint8_t* data, ssize_t dataLen, bool ownData)
int bytePerPixel = 4;
unsigned int stride = width * bytePerPixel;
std::vector<uint8_t> decodeImageData(stride * height);
auto decodeImageData = axstd::make_unique_for_overwrite<uint8_t[]>(stride * height);
if (FOURCC_DXT1 == header->ddsd.DUMMYUNIONNAMEN4.ddpfPixelFormat.fourCC)
{
s3tc_decode(pixelData + encodeOffset, &decodeImageData[0], width, height, S3TCDecodeFlag::DXT1);

View File

@ -262,7 +262,7 @@ bool Material::parsePass(Technique* technique, Properties* passProperties)
// cocos2d-x doesn't support Samplers yet. But will be added soon
bool Material::parseSampler(backend::ProgramState* programState, Properties* samplerProperties)
{
AXASSERT(samplerProperties->getId(), "Sampler must have an id. The id is the uniform name");
AXASSERT(!samplerProperties->getId().empty(), "Sampler must have an id. The id is the uniform name");
// required
auto filename = samplerProperties->getString("path");

View File

@ -207,7 +207,7 @@ protected:
// weak reference
Node* _target = nullptr;
std::unordered_map<std::string, int> _textureSlots;
hlookup::string_map<int> _textureSlots;
int _textureSlotIndex = 0;
bool _isTransparent = false; // is this mesh transparent.

View File

@ -147,7 +147,7 @@ void RenderQueue::realloc(size_t reserveSize)
{
for (int i = 0; i < QUEUE_GROUP::QUEUE_COUNT; ++i)
{
_commands[i] = std::vector<RenderCommand*>();
_commands[i].clear();
_commands[i].reserve(reserveSize);
}
}
@ -166,8 +166,7 @@ Renderer::Renderer()
_commandGroupStack.push(DEFAULT_RENDER_QUEUE);
RenderQueue defaultRenderQueue;
_renderGroups.emplace_back(defaultRenderQueue);
_renderGroups.emplace_back();
_queuedTriangleCommands.reserve(BATCH_TRIAGCOMMAND_RESERVED_SIZE);
// for the batched TriangleCommand

View File

@ -30,8 +30,8 @@
#include "base/CCDirector.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/axstd.h"
#include "renderer/backend/opengl/UtilsGL.h"
#include "yasio/detail/byte_buffer.hpp"
NS_AX_BACKEND_BEGIN
@ -138,9 +138,9 @@ void ProgramGL::compileProgram()
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &errorInfoLen);
if (errorInfoLen > 1)
{
yasio::sbyte_buffer errorInfo{static_cast<size_t>(errorInfoLen), std::true_type{}};
glGetProgramInfoLog(_program, errorInfoLen, NULL, errorInfo.data());
log("cocos2d: ERROR: %s: failed to link program: %s ", __FUNCTION__, errorInfo.data());
auto errorInfo = axstd::make_unique_for_overwrite<char[]>(static_cast<size_t>(errorInfoLen));
glGetProgramInfoLog(_program, errorInfoLen, NULL, errorInfo.get());
log("cocos2d: ERROR: %s: failed to link program: %s ", __FUNCTION__, errorInfo.get());
}
else
log("cocos2d: ERROR: %s: failed to link program ", __FUNCTION__);
@ -234,8 +234,8 @@ const hlookup::string_map<AttributeBindInfo>& ProgramGL::getActiveAttributes() c
_activeAttribs.reserve(numOfActiveAttributes);
int MAX_ATTRIBUTE_NAME_LENGTH = 256;
std::vector<char> attrName(MAX_ATTRIBUTE_NAME_LENGTH + 1);
int MAX_ATTRIBUTE_NAME_LENGTH = 255;
auto attrName = axstd::make_unique_for_overwrite<char[]>(MAX_ATTRIBUTE_NAME_LENGTH + 1);
GLint attrNameLen = 0;
GLenum attrType;
@ -244,9 +244,9 @@ const hlookup::string_map<AttributeBindInfo>& ProgramGL::getActiveAttributes() c
for (int i = 0; i < numOfActiveAttributes; i++)
{
glGetActiveAttrib(_program, i, MAX_ATTRIBUTE_NAME_LENGTH, &attrNameLen, &attrSize, &attrType, attrName.data());
glGetActiveAttrib(_program, i, MAX_ATTRIBUTE_NAME_LENGTH, &attrNameLen, &attrSize, &attrType, attrName.get());
CHECK_GL_ERROR_DEBUG();
info.attributeName = std::string(attrName.data(), attrName.data() + attrNameLen);
info.attributeName = std::string(attrName.get(), attrName.get() + attrNameLen);
info.location = glGetAttribLocation(_program, info.attributeName.c_str());
info.type = attrType;
info.size = UtilsGL::getGLDataTypeSize(attrType) * attrSize;

View File

@ -27,7 +27,7 @@
#include "platform/CCPlatformMacros.h"
#include "base/ccMacros.h"
#include "yasio/detail/byte_buffer.hpp"
#include "base/axstd.h"
NS_AX_BACKEND_BEGIN
@ -61,9 +61,9 @@ void ShaderModuleGL::compileShader(ShaderStage stage, std::string_view source)
if (logLength > 1)
{
yasio::sbyte_buffer errorLog{static_cast<size_t>(logLength), std::true_type{}};
glGetShaderInfoLog(_shader, logLength, nullptr, (GLchar*)errorLog.data());
ax::log("cocos2d: ERROR: Failed to compile shader, detail: %s\n%s", errorLog.data(),
auto errorLog = axstd::make_unique_for_overwrite<char[]>(static_cast<size_t>(logLength));
glGetShaderInfoLog(_shader, logLength, nullptr, (GLchar*)errorLog.get());
ax::log("cocos2d: ERROR: Failed to compile shader, detail: %s\n%s", errorLog.get(),
source.data());
}
else

View File

@ -482,7 +482,7 @@ static void printProperties(Properties* properties, int indent)
{
// Print the name and ID of the current namespace.
const char* spacename = properties->getNamespace();
const char* id = properties->getId();
const char* id = properties->getId().data();
char chindent[64];
int i = 0;
for (i = 0; i < indent * 2; i++)

View File

@ -10,4 +10,7 @@ if($BUILD_ARCH -eq "x86") {
cmake -S . -B build_$BUILD_ARCH $CONFIG_ALL_OPTIONS -Thost=x64 -DAX_ENABLE_EXT_IMGUI=ON
cmake --build build_$BUILD_ARCH --config Release --target cpp_tests
cmake --build build_$BUILD_ARCH --config Release --target lua_tests
if ( !($env:PULL_REQUEST -eq 'yes') ) {
cmake --build build_$BUILD_ARCH --config Release --target lua_tests
}