9 Commits

44 changed files with 751 additions and 2346 deletions

View File

@ -1,3 +1,4 @@
#include <iostream>
#include <irrlicht.h>
#include "exampleHelper.h"
@ -6,6 +7,8 @@ using namespace irr;
static IrrlichtDevice *device = nullptr;
static int test_fail = 0;
extern void test_irr_array();
static video::E_DRIVER_TYPE chooseDriver(const char *arg_)
{
if (core::stringc(arg_) == "null")
@ -27,8 +30,15 @@ static inline void check(bool ok, const char *msg)
}
}
void run_unit_tests() {
std::cout << "Running unit tests:" << std::endl;
test_irr_array();
}
int main(int argc, char *argv[])
{
run_unit_tests();
SIrrlichtCreationParameters p;
p.DriverType = chooseDriver(argc > 1 ? argv[1] : "");
p.WindowSize = core::dimension2du(640, 480);

View File

@ -0,0 +1,135 @@
#include "irrArray.h"
#include "test_helper.h"
using namespace irr;
using core::array;
static void test_basics() {
array<int> v;
v.push_back(1); // 1
v.push_front(2); // 2, 1
v.insert(4, 0); // 4, 2, 1
v.insert(3, 1); // 4, 3, 2, 1
v.insert(0, 4); // 4, 3, 2, 1, 0
UASSERTEQ(v.size(), 5);
UASSERTEQ(v[0], 4);
UASSERTEQ(v[1], 3);
UASSERTEQ(v[2], 2);
UASSERTEQ(v[3], 1);
UASSERTEQ(v[4], 0);
array<int> w = v;
UASSERTEQ(w.size(), 5);
UASSERT(w == v);
w.clear();
UASSERTEQ(w.size(), 0);
UASSERTEQ(w.allocated_size(), 0);
UASSERT(w.empty());
w = v;
UASSERTEQ(w.size(), 5);
w.set_used(3);
UASSERTEQ(w.size(), 3);
UASSERTEQ(w[0], 4);
UASSERTEQ(w[1], 3);
UASSERTEQ(w[2], 2);
UASSERTEQ(w.getLast(), 2);
w.set_used(20);
UASSERTEQ(w.size(), 20);
w = v;
w.sort();
UASSERTEQ(w.size(), 5);
UASSERTEQ(w[0], 0);
UASSERTEQ(w[1], 1);
UASSERTEQ(w[2], 2);
UASSERTEQ(w[3], 3);
UASSERTEQ(w[4], 4);
w.erase(0);
UASSERTEQ(w.size(), 4);
UASSERTEQ(w[0], 1);
UASSERTEQ(w[1], 2);
UASSERTEQ(w[2], 3);
UASSERTEQ(w[3], 4);
w.erase(1, 2);
UASSERTEQ(w.size(), 2);
UASSERTEQ(w[0], 1);
UASSERTEQ(w[1], 4);
w.swap(v);
UASSERTEQ(w.size(), 5);
UASSERTEQ(v.size(), 2);
}
static void test_linear_searches() {
// Populate the array with 0, 1, 2, ..., 100, 100, 99, 98, 97, ..., 0
array<int> arr;
for (int i = 0; i <= 100; i++)
arr.push_back(i);
for (int i = 100; i >= 0; i--)
arr.push_back(i);
s32 end = arr.size() - 1;
for (int i = 0; i <= 100; i++) {
s32 index = arr.linear_reverse_search(i);
UASSERTEQ(index, end - i);
}
for (int i = 0; i <= 100; i++) {
s32 index = arr.linear_search(i);
UASSERTEQ(index, i);
}
}
static void test_binary_searches() {
const auto& values = { 3, 5, 1, 2, 5, 10, 19, 9, 7, 1, 2, 5, 8, 15 };
array<int> arr;
for (int value : values) {
arr.push_back(value);
}
// Test the const form first, it uses a linear search without sorting
const array<int> & carr = arr;
UASSERTEQ(carr.binary_search(20), -1);
UASSERTEQ(carr.binary_search(0), -1);
UASSERTEQ(carr.binary_search(1), 2);
// Sorted: 1, 1, 2, 2, 3, 5, 5, 5, 7, 8, 9, 10, 15, 19
UASSERTEQ(arr.binary_search(20), -1);
UASSERTEQ(arr.binary_search(0), -1);
for (int value : values) {
s32 i = arr.binary_search(value);
UASSERTNE(i, -1);
UASSERTEQ(arr[i], value);
}
s32 first, last;
first = arr.binary_search_multi(1, last);
UASSERTEQ(first, 0);
UASSERTEQ(last, 1);
first = arr.binary_search_multi(2, last);
UASSERTEQ(first, 2);
UASSERTEQ(last, 3);
first = arr.binary_search_multi(3, last);
UASSERTEQ(first, 4);
UASSERTEQ(last, 4);
first = arr.binary_search_multi(4, last);
UASSERTEQ(first, -1);
first = arr.binary_search_multi(5, last);
UASSERTEQ(first, 5);
UASSERTEQ(last, 7);
first = arr.binary_search_multi(7, last);
UASSERTEQ(first, 8);
UASSERTEQ(last, 8);
first = arr.binary_search_multi(19, last);
UASSERTEQ(first, 13);
UASSERTEQ(last, 13);
}
void test_irr_array()
{
test_basics();
test_linear_searches();
test_binary_searches();
std::cout << " test_irr_array PASSED" << std::endl;
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <exception>
#include <iostream>
class TestFailedException : public std::exception {
};
// Asserts the comparison specified by CMP is true, or fails the current unit test
#define UASSERTCMP(CMP, actual, expected) do { \
const auto &a = (actual); \
const auto &e = (expected); \
if (!CMP(a, e)) { \
std::cout \
<< "Test assertion failed: " << #actual << " " << #CMP << " " \
<< #expected << std::endl \
<< " at " << __FILE__ << ":" << __LINE__ << std::endl \
<< " actual: " << a << std::endl << " expected: " \
<< e << std::endl; \
throw TestFailedException(); \
} \
} while (0)
#define CMPEQ(a, e) (a == e)
#define CMPTRUE(a, e) (a)
#define CMPNE(a, e) (a != e)
#define UASSERTEQ(actual, expected) UASSERTCMP(CMPEQ, actual, expected)
#define UASSERTNE(actual, nexpected) UASSERTCMP(CMPNE, actual, nexpected)
#define UASSERT(actual) UASSERTCMP(CMPTRUE, actual, true)

View File

@ -1,3 +1,5 @@
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(IRREXAMPLES
# removed

View File

@ -6,7 +6,6 @@
#define __I_GUI_ELEMENT_H_INCLUDED__
#include "IReferenceCounted.h"
#include "irrList.h"
#include "rect.h"
#include "irrString.h"
#include "IEventReceiver.h"
@ -14,6 +13,10 @@
#include "EGUIAlignment.h"
#include "IAttributes.h"
#include "IGUIEnvironment.h"
#include <cassert>
#include <algorithm>
#include <list>
#include <vector>
namespace irr
{
@ -50,12 +53,9 @@ public:
//! Destructor
virtual ~IGUIElement()
{
// delete all children
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
{
(*it)->Parent = 0;
(*it)->drop();
for (auto child : Children) {
child->Parent = nullptr;
child->drop();
}
}
@ -239,10 +239,9 @@ public:
recalculateAbsolutePosition(false);
// update all children
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
for (auto child : Children)
{
(*it)->updateAbsolutePosition();
child->updateAbsolutePosition();
}
}
@ -263,20 +262,19 @@ public:
{
IGUIElement* target = 0;
// we have to search from back to front, because later children
// might be drawn over the top of earlier ones.
core::list<IGUIElement*>::ConstIterator it = Children.getLast();
if (isVisible())
{
while(it != Children.end())
// we have to search from back to front, because later children
// might be drawn over the top of earlier ones.
auto it = Children.rbegin();
auto ie = Children.rend();
while (it != ie)
{
target = (*it)->getElementFromPoint(point);
if (target)
return target;
--it;
++it;
}
}
@ -308,17 +306,19 @@ public:
//! Removes a child.
virtual void removeChild(IGUIElement* child)
{
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
if ((*it) == child)
{
(*it)->Parent = 0;
(*it)->drop();
Children.erase(it);
return;
}
assert(child->Parent == this);
Children.erase(child->ParentPos);
child->Parent = nullptr;
child->drop();
}
//! Removes all children.
virtual void removeAllChildren() {
while (!Children.empty()) {
auto child = Children.back();
child->remove();
}
}
//! Removes this element from its parent.
virtual void remove()
@ -333,9 +333,8 @@ public:
{
if ( isVisible() )
{
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->draw();
for (auto child : Children)
child->draw();
}
}
@ -345,9 +344,8 @@ public:
{
if ( isVisible() )
{
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnPostRender( timeMs );
for (auto child : Children)
child->OnPostRender( timeMs );
}
}
@ -555,20 +553,15 @@ public:
//! Brings a child to front
/** \return True if successful, false if not. */
virtual bool bringToFront(IGUIElement* element)
virtual bool bringToFront(IGUIElement* child)
{
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
{
if (element == (*it))
{
Children.erase(it);
Children.push_back(element);
return true;
}
}
return false;
if (child->Parent != this)
return false;
if (std::next(child->ParentPos) == Children.end()) // already there
return true;
Children.erase(child->ParentPos);
child->ParentPos = Children.insert(Children.end(), child);
return true;
}
@ -576,24 +569,17 @@ public:
/** \return True if successful, false if not. */
virtual bool sendToBack(IGUIElement* child)
{
core::list<IGUIElement*>::Iterator it = Children.begin();
if (child == (*it)) // already there
if (child->Parent != this)
return false;
if (child->ParentPos == Children.begin()) // already there
return true;
for (; it != Children.end(); ++it)
{
if (child == (*it))
{
Children.erase(it);
Children.push_front(child);
return true;
}
}
return false;
Children.erase(child->ParentPos);
child->ParentPos = Children.insert(Children.begin(), child);
return true;
}
//! Returns list with children of this element
virtual const core::list<IGUIElement*>& getChildren() const
virtual const std::list<IGUIElement*>& getChildren() const
{
return Children;
}
@ -610,14 +596,13 @@ public:
{
IGUIElement* e = 0;
core::list<IGUIElement*>::ConstIterator it = Children.begin();
for (; it != Children.end(); ++it)
for (auto child : Children)
{
if ((*it)->getID() == id)
return (*it);
if (child->getID() == id)
return child;
if (searchchildren)
e = (*it)->getElementFromId(id, true);
e = child->getElementFromId(id, true);
if (e)
return e;
@ -663,7 +648,7 @@ public:
if (wanted==-2)
wanted = 1073741824; // maximum s32
core::list<IGUIElement*>::ConstIterator it = Children.begin();
auto it = Children.begin();
s32 closestOrder, currentOrder;
@ -806,10 +791,40 @@ protected:
child->remove(); // remove from old parent
child->LastParentRect = getAbsolutePosition();
child->Parent = this;
Children.push_back(child);
child->ParentPos = Children.insert(Children.end(), child);
}
}
#ifndef NDEBUG
template<typename Iterator>
static size_t _fastSetChecksum(Iterator begin, Iterator end) {
std::hash<typename Iterator::value_type> hasher;
size_t checksum = 0;
for (Iterator it = begin; it != end; ++it) {
size_t h = hasher(*it);
checksum ^= 966073049 + (h * 3432918353) + ((h >> 16) * 461845907);
}
return checksum;
}
#endif
// Reorder children [from, to) to the order given by `neworder`
void reorderChildren(
std::list<IGUIElement*>::iterator from,
std::list<IGUIElement*>::iterator to,
const std::vector<IGUIElement*> &neworder)
{
assert(_fastSetChecksum(from, to) == _fastSetChecksum(neworder.begin(), neworder.end()));
for (auto e : neworder)
{
*from = e;
e->ParentPos = from;
++from;
}
assert(from == to);
}
// not virtual because needed in constructor
void recalculateAbsolutePosition(bool recursive)
{
@ -931,10 +946,9 @@ protected:
if ( recursive )
{
// update all children
core::list<IGUIElement*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
for (auto child : Children)
{
(*it)->recalculateAbsolutePosition(recursive);
child->recalculateAbsolutePosition(recursive);
}
}
}
@ -942,11 +956,14 @@ protected:
protected:
//! List of all children of this element
core::list<IGUIElement*> Children;
std::list<IGUIElement*> Children;
//! Pointer to the parent
IGUIElement* Parent;
//! Our position in the parent list. Only valid when Parent != nullptr
std::list<IGUIElement*>::iterator ParentPos;
//! relative rect of element
core::rect<s32> RelativeRect;

View File

@ -13,8 +13,8 @@
#include "irrString.h"
#include "aabbox3d.h"
#include "matrix4.h"
#include "irrList.h"
#include "IAttributes.h"
#include <list>
namespace irr
{
@ -24,7 +24,7 @@ namespace scene
class ISceneManager;
//! Typedef for list of scene nodes
typedef core::list<ISceneNode*> ISceneNodeList;
typedef std::list<ISceneNode*> ISceneNodeList;
//! Scene node interface.
/** A scene node is a node in the hierarchical scene graph. Every scene
@ -81,7 +81,7 @@ namespace scene
{
if (IsVisible)
{
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnRegisterSceneNode();
}
@ -103,7 +103,7 @@ namespace scene
// perform the post render process on all children
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
@ -289,7 +289,7 @@ namespace scene
e.g. because it couldn't be found in the children list. */
virtual bool removeChild(ISceneNode* child)
{
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
if ((*it) == child)
{
@ -309,7 +309,7 @@ namespace scene
*/
virtual void removeAll()
{
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
{
(*it)->Parent = 0;
@ -519,7 +519,7 @@ namespace scene
//! Returns a const reference to the list of all children.
/** \return The list of all children of this node. */
const core::list<ISceneNode*>& getChildren() const
const std::list<ISceneNode*>& getChildren() const
{
return Children;
}
@ -611,7 +611,7 @@ namespace scene
// clone children
ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
ISceneNodeList::iterator it = toCopyFrom->Children.begin();
for (; it != toCopyFrom->Children.end(); ++it)
(*it)->clone(this, newManager);
}
@ -622,7 +622,7 @@ namespace scene
{
SceneManager = newManager;
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->setSceneManager(newManager);
}
@ -646,7 +646,7 @@ namespace scene
ISceneNode* Parent;
//! List of all children of this node
core::list<ISceneNode*> Children;
std::list<ISceneNode*> Children;
//! Pointer to the scene manager
ISceneManager* SceneManager;

View File

@ -100,7 +100,7 @@ namespace scene
private:
//! Internal members used by CSkinnedMesh
friend class CSkinnedMesh;
bool *Moved;
char *Moved;
core::vector3df StaticPos;
core::vector3df StaticNormal;
};

View File

@ -6,8 +6,8 @@
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
//! Identifies the IrrlichtMt fork customized for the Minetest engine
#define IRRLICHT_VERSION_MT_REVISION 5
#define IRRLICHT_VERSION_MT "mt5"
#define IRRLICHT_VERSION_MT_REVISION 6
#define IRRLICHT_VERSION_MT "mt6"
//! Irrlicht SDK Version
#define IRRLICHT_VERSION_MAJOR 1

View File

@ -1,70 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __IRR_HEAPSORT_H_INCLUDED__
#define __IRR_HEAPSORT_H_INCLUDED__
#include "irrTypes.h"
namespace irr
{
namespace core
{
//! Sinks an element into the heap.
template<class T>
inline void heapsink(T*array, s32 element, s32 max)
{
while ((element<<1) < max) // there is a left child
{
s32 j = (element<<1);
if (j+1 < max && array[j] < array[j+1])
j = j+1; // take right child
if (array[element] < array[j])
{
T t = array[j]; // swap elements
array[j] = array[element];
array[element] = t;
element = j;
}
else
return;
}
}
//! Sorts an array with size 'size' using heapsort.
template<class T>
inline void heapsort(T* array_, s32 size)
{
// for heapsink we pretend this is not c++, where
// arrays start with index 0. So we decrease the array pointer,
// the maximum always +2 and the element always +1
T* virtualArray = array_ - 1;
s32 virtualSize = size + 2;
s32 i;
// build heap
for (i=((size-1)/2); i>=0; --i)
heapsink(virtualArray, i+1, virtualSize-1);
// sort array, leave out the last element (0)
for (i=size-1; i>0; --i)
{
T t = array_[0];
array_[0] = array_[i];
array_[i] = t;
heapsink(virtualArray, 1, i + 1);
}
}
} // end namespace core
} // end namespace irr
#endif

View File

@ -5,9 +5,11 @@
#ifndef __IRR_ARRAY_H_INCLUDED__
#define __IRR_ARRAY_H_INCLUDED__
#include <algorithm>
#include <iterator>
#include <vector>
#include "irrTypes.h"
#include "heapsort.h"
#include "irrAllocator.h"
#include "irrMath.h"
namespace irr
@ -18,44 +20,27 @@ namespace core
//! Self reallocating template array (like stl vector) with additional features.
/** Some features are: Heap sorting, binary search methods, easier debugging.
*/
template <class T, typename TAlloc = irrAllocator<T> >
template <class T>
class array
{
public:
static_assert(!std::is_same<T, bool>::value,
"irr::core::array<T> with T = bool not supported. Use std::vector instead.");
//! Default constructor for empty array.
array() : data(0), allocated(0), used(0),
strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true)
{
}
array() : m_data(), is_sorted(true)
{ }
//! Constructs an array and allocates an initial chunk of memory.
/** \param start_count Amount of elements to pre-allocate. */
explicit array(u32 start_count) : data(0), allocated(0), used(0),
strategy(ALLOC_STRATEGY_DOUBLE),
free_when_destroyed(true), is_sorted(true)
explicit array(u32 start_count) : m_data(), is_sorted(true)
{
reallocate(start_count);
m_data.reserve(start_count);
}
//! Copy constructor
array(const array<T, TAlloc>& other) : data(0)
{
*this = other;
}
//! Destructor.
/** Frees allocated memory, if set_free_when_destroyed was not set to
false by the user before. */
~array()
{
clear();
}
array(const array<T>& other) : m_data(other.m_data), is_sorted(other.is_sorted)
{ }
//! Reallocates the array, make it bigger or smaller.
/** \param new_size New size of array.
@ -65,52 +50,28 @@ public:
*/
void reallocate(u32 new_size, bool canShrink=true)
{
if (allocated==new_size)
return;
if (!canShrink && (new_size < allocated))
return;
T* old_data = data;
data = allocator.allocate(new_size); //new T[new_size];
allocated = new_size;
// copy old data
const s32 end = used < new_size ? used : new_size;
for (s32 i=0; i<end; ++i)
{
// data[i] = old_data[i];
allocator.construct(&data[i], old_data[i]);
size_t allocated = m_data.capacity();
if (new_size < allocated) {
if (canShrink)
m_data.resize(new_size);
} else {
m_data.reserve(new_size);
}
// destruct old data
for (u32 j=0; j<used; ++j)
allocator.destruct(&old_data[j]);
if (allocated < used)
used = allocated;
allocator.deallocate(old_data); //delete [] old_data;
}
//! set a new allocation strategy
/** if the maximum size of the array is unknown, you can define how big the
allocation should happen.
\param newStrategy New strategy to apply to this array. */
void setAllocStrategy ( eAllocStrategy newStrategy = ALLOC_STRATEGY_DOUBLE )
{
strategy = newStrategy;
}
//! Adds an element at back of array.
/** If the array is too small to add this new element it is made bigger.
\param element: Element to add at the back of the array. */
void push_back(const T& element)
{
insert(element, used);
m_data.push_back(element);
is_sorted = false;
}
void push_back(T&& element)
{
m_data.push_back(std::move(element));
is_sorted = false;
}
@ -121,7 +82,14 @@ public:
\param element Element to add at the back of the array. */
void push_front(const T& element)
{
insert(element);
m_data.insert(m_data.begin(), element);
is_sorted = false;
}
void push_front(T&& element)
{
m_data.insert(m_data.begin(), std::move(element));
is_sorted = false;
}
@ -131,106 +99,21 @@ public:
\param index: Where position to insert the new element. */
void insert(const T& element, u32 index=0)
{
_IRR_DEBUG_BREAK_IF(index>used) // access violation
if (used + 1 > allocated)
{
// this doesn't work if the element is in the same
// array. So we'll copy the element first to be sure
// we'll get no data corruption
const T e(element);
// increase data block
u32 newAlloc;
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 5 + (allocated < 500 ? used : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc);
// move array content and construct new element
// first move end one up
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
// then add new element
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], e); // data[index] = e;
}
else
{
// element inserted not at end
if ( used > index )
{
// create one new element at the end
allocator.construct(&data[used], data[used-1]);
// move the rest of the array content
for (u32 i=used-1; i>index; --i)
{
data[i] = data[i-1];
}
// insert the new element
data[index] = element;
}
else
{
// insert the new element to the end
allocator.construct(&data[index], element);
}
}
// set to false as we don't know if we have the comparison operators
_IRR_DEBUG_BREAK_IF(index > m_data.size()) // access violation
auto pos = std::next(m_data.begin(), index);
m_data.insert(pos, element);
is_sorted = false;
++used;
}
//! Clears the array and deletes all allocated memory.
void clear()
{
if (free_when_destroyed)
{
for (u32 i=0; i<used; ++i)
allocator.destruct(&data[i]);
allocator.deallocate(data); // delete [] data;
}
data = 0;
used = 0;
allocated = 0;
// vector::clear() reduces the size to 0, but doesn't free memory.
// This swap is guaranteed to delete the allocated memory.
std::vector<T>().swap(m_data);
is_sorted = true;
}
//! Sets pointer to new array, using this as new workspace.
/** Make sure that set_free_when_destroyed is used properly.
\param newPointer: Pointer to new array of elements.
\param size: Size of the new array.
\param _is_sorted Flag which tells whether the new array is already
sorted.
\param _free_when_destroyed Sets whether the new memory area shall be
freed by the array upon destruction, or if this will be up to the user
application. */
void set_pointer(T* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)
{
clear();
data = newPointer;
allocated = size;
used = size;
is_sorted = _is_sorted;
free_when_destroyed=_free_when_destroyed;
}
//! Set (copy) data from given memory block
/** \param newData data to set, must have newSize elements
\param newSize Amount of elements in newData
@ -240,12 +123,11 @@ public:
*/
void set_data(const T* newData, u32 newSize, bool newDataIsSorted=false, bool canShrink=false)
{
reallocate(newSize, canShrink);
set_used(newSize);
for ( u32 i=0; i<newSize; ++i)
{
data[i] = newData[i];
m_data.resize(newSize);
if (canShrink) {
m_data.shrink_to_fit();
}
std::copy(newData, newData + newSize, m_data.begin());
is_sorted = newDataIsSorted;
}
@ -255,85 +137,51 @@ public:
\param size Amount of elements in otherData */
bool equals(const T* otherData, u32 size) const
{
if (used != size)
if (m_data.size() != size)
return false;
for (u32 i=0; i<size; ++i)
if (data[i] != otherData[i])
return false;
return true;
return std::equal(m_data.begin(), m_data.end(), otherData);
}
//! Sets if the array should delete the memory it uses upon destruction.
/** Also clear and set_pointer will only delete the (original) memory
area if this flag is set to true, which is also the default. The
methods reallocate, set_used, push_back, push_front, insert, and erase
will still try to deallocate the original memory, which might cause
troubles depending on the intended use of the memory area.
\param f If true, the array frees the allocated memory in its
destructor, otherwise not. The default is true. */
void set_free_when_destroyed(bool f)
{
free_when_destroyed = f;
}
//! Sets the size of the array and allocates new elements if necessary.
/** Please note: This is only secure when using it with simple types,
because no default constructor will be called for the added elements.
\param usedNow Amount of elements now used. */
/** \param usedNow Amount of elements now used. */
void set_used(u32 usedNow)
{
if (allocated < usedNow)
reallocate(usedNow);
used = usedNow;
m_data.resize(usedNow);
}
//! Assignment operator
const array<T, TAlloc>& operator=(const array<T, TAlloc>& other)
const array<T>& operator=(const array<T>& other)
{
if (this == &other)
return *this;
strategy = other.strategy;
// (TODO: we could probably avoid re-allocations of data when (allocated < other.allocated)
if (data)
clear();
used = other.used;
free_when_destroyed = true;
m_data = other.m_data;
is_sorted = other.is_sorted;
allocated = other.allocated;
if (other.allocated == 0)
{
data = 0;
}
else
{
data = allocator.allocate(other.allocated); // new T[other.allocated];
for (u32 i=0; i<other.used; ++i)
allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i];
}
return *this;
}
array<T>& operator=(const std::vector<T> &other)
{
m_data = other;
is_sorted = false;
return *this;
}
array<T>& operator=(std::vector<T> &&other)
{
m_data = std::move(other);
is_sorted = false;
return *this;
}
//! Equality operator
bool operator == (const array<T, TAlloc>& other) const
bool operator == (const array<T>& other) const
{
return equals(other.const_pointer(), other.size());
}
//! Inequality operator
bool operator != (const array<T, TAlloc>& other) const
bool operator != (const array<T>& other) const
{
return !(*this==other);
}
@ -342,36 +190,36 @@ public:
//! Direct access operator
T& operator [](u32 index)
{
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
_IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation
return data[index];
return m_data[index];
}
//! Direct const access operator
const T& operator [](u32 index) const
{
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
_IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation
return data[index];
return m_data[index];
}
//! Gets last element.
T& getLast()
{
_IRR_DEBUG_BREAK_IF(!used) // access violation
_IRR_DEBUG_BREAK_IF(m_data.empty()) // access violation
return data[used-1];
return m_data.back();
}
//! Gets last element
const T& getLast() const
{
_IRR_DEBUG_BREAK_IF(!used) // access violation
_IRR_DEBUG_BREAK_IF(m_data.empty()) // access violation
return data[used-1];
return m_data.back();
}
@ -379,7 +227,7 @@ public:
/** \return Pointer to the array. */
T* pointer()
{
return data;
return &m_data[0];
}
@ -387,7 +235,7 @@ public:
/** \return Pointer to the array. */
const T* const_pointer() const
{
return data;
return &m_data[0];
}
@ -395,7 +243,7 @@ public:
/** \return Size of elements in the array which are actually occupied. */
u32 size() const
{
return used;
return m_data.size();
}
@ -404,7 +252,7 @@ public:
allocated would be allocated_size() * sizeof(ElementTypeUsed); */
u32 allocated_size() const
{
return allocated;
return m_data.capacity();
}
@ -412,7 +260,7 @@ public:
/** \return True if the array is empty false if not. */
bool empty() const
{
return used == 0;
return m_data.empty();
}
@ -421,9 +269,10 @@ public:
O(n*log n) in worst case. */
void sort()
{
if (!is_sorted && used>1)
heapsort(data, used);
is_sorted = true;
if (!is_sorted) {
std::sort(m_data.begin(), m_data.end());
is_sorted = true;
}
}
@ -437,10 +286,9 @@ public:
s32 binary_search(const T& element)
{
sort();
return binary_search(element, 0, used-1);
return binary_search(element, 0, (s32)m_data.size() - 1);
}
//! Performs a binary search for an element if possible, returns -1 if not found.
/** This method is for const arrays and so cannot call sort(), if the array is
not sorted then linear_search will be used instead. Potentially very slow!
@ -450,12 +298,11 @@ public:
s32 binary_search(const T& element) const
{
if (is_sorted)
return binary_search(element, 0, used-1);
return binary_search(element, 0, (s32)m_data.size() - 1);
else
return linear_search(element);
}
//! Performs a binary search for an element, returns -1 if not found.
/** \param element: Element to search for.
\param left First left index
@ -464,31 +311,15 @@ public:
is returned. */
s32 binary_search(const T& element, s32 left, s32 right) const
{
if (!used)
if (left > right)
return -1;
s32 m;
do
{
m = (left+right)>>1;
if (element < data[m])
right = m - 1;
else
left = m + 1;
} while((element < data[m] || data[m] < element) && left<=right);
// this last line equals to:
// " while((element != array[m]) && left<=right);"
// but we only want to use the '<' operator.
// the same in next line, it is "(element == array[m])"
if (!(element < data[m]) && !(data[m] < element))
return m;
return -1;
auto lpos = std::next(m_data.begin(), left);
auto rpos = std::next(m_data.begin(), right);
auto it = std::lower_bound(lpos, rpos, element);
// *it = first element in [first, last) that is >= element, or last if not found.
if (*it < element || element < *it)
return -1;
return it - m_data.begin();
}
@ -503,25 +334,11 @@ public:
s32 binary_search_multi(const T& element, s32 &last)
{
sort();
s32 index = binary_search(element, 0, used-1);
if ( index < 0 )
return index;
// The search can be somewhere in the middle of the set
// look linear previous and past the index
last = index;
while ( index > 0 && !(element < data[index - 1]) && !(data[index - 1] < element) )
{
index -= 1;
}
// look linear up
while ( last < (s32) used - 1 && !(element < data[last + 1]) && !(data[last + 1] < element) )
{
last += 1;
}
return index;
auto iters = std::equal_range(m_data.begin(), m_data.end(), element);
if (iters.first == iters.second)
return -1;
last = (iters.second - m_data.begin()) - 1;
return iters.first - m_data.begin();
}
@ -533,11 +350,10 @@ public:
is returned. */
s32 linear_search(const T& element) const
{
for (u32 i=0; i<used; ++i)
if (element == data[i])
return (s32)i;
return -1;
auto it = std::find(m_data.begin(), m_data.end(), element);
if (it == m_data.end())
return -1;
return it - m_data.begin();
}
@ -549,11 +365,11 @@ public:
is returned. */
s32 linear_reverse_search(const T& element) const
{
for (s32 i=used-1; i>=0; --i)
if (data[i] == element)
return i;
return -1;
auto it = std::find(m_data.rbegin(), m_data.rend(), element);
if (it == m_data.rend())
return -1;
size_t offset = it - m_data.rbegin();
return m_data.size() - offset - 1;
}
@ -563,17 +379,9 @@ public:
\param index: Index of element to be erased. */
void erase(u32 index)
{
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
for (u32 i=index+1; i<used; ++i)
{
allocator.destruct(&data[i-1]);
allocator.construct(&data[i-1], data[i]); // data[i-1] = data[i];
}
allocator.destruct(&data[used-1]);
--used;
_IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation
auto it = std::next(m_data.begin(), index);
m_data.erase(it);
}
@ -584,30 +392,14 @@ public:
\param count: Amount of elements to be erased. */
void erase(u32 index, s32 count)
{
if (index>=used || count<1)
if (index >= m_data.size() || count < 1)
return;
if (index+count>used)
count = used-index;
u32 i;
for (i=index; i<index+count; ++i)
allocator.destruct(&data[i]);
for (i=index+count; i<used; ++i)
{
if (i-count >= index+count) // not already destructed before loop
allocator.destruct(&data[i-count]);
allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i];
if (i >= used-count) // those which are not overwritten
allocator.destruct(&data[i]);
}
used-= count;
count = std::min(count, (s32)m_data.size() - (s32)index);
auto first = std::next(m_data.begin(), index);
auto last = std::next(first, count);
m_data.erase(first, last);
}
//! Sets if the array is sorted
void set_sorted(bool _is_sorted)
{
@ -619,38 +411,30 @@ public:
/** Afterward this object will contain the content of the other object and the other
object will contain the content of this object.
\param other Swap content with this object */
void swap(array<T, TAlloc>& other)
void swap(array<T>& other)
{
core::swap(data, other.data);
core::swap(allocated, other.allocated);
core::swap(used, other.used);
core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
eAllocStrategy helper_strategy(strategy); // can't use core::swap with bitfields
strategy = other.strategy;
other.strategy = helper_strategy;
bool helper_free_when_destroyed(free_when_destroyed);
free_when_destroyed = other.free_when_destroyed;
other.free_when_destroyed = helper_free_when_destroyed;
bool helper_is_sorted(is_sorted);
is_sorted = other.is_sorted;
other.is_sorted = helper_is_sorted;
m_data.swap(other.m_data);
std::swap(is_sorted, other.is_sorted);
}
//! Pull the contents of this array as a vector.
// The array is left empty.
std::vector<T> steal()
{
std::vector<T> ret = std::move(m_data);
m_data.clear();
is_sorted = true;
return ret;
}
typedef TAlloc allocator_type;
typedef T value_type;
typedef u32 size_type;
private:
T* data;
u32 allocated;
u32 used;
TAlloc allocator;
eAllocStrategy strategy:4;
bool free_when_destroyed:1;
bool is_sorted:1;
std::vector<T> m_data;
bool is_sorted;
};
} // end namespace core
} // end namespace irr

View File

@ -1,414 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __IRR_LIST_H_INCLUDED__
#define __IRR_LIST_H_INCLUDED__
#include "irrTypes.h"
#include "irrAllocator.h"
#include "irrMath.h"
namespace irr
{
namespace core
{
//! Doubly linked list template.
template <class T>
class list
{
private:
//! List element node with pointer to previous and next element in the list.
struct SKListNode
{
SKListNode(const T& e) : Next(0), Prev(0), Element(e) {}
SKListNode* Next;
SKListNode* Prev;
T Element;
};
public:
class ConstIterator;
//! List iterator.
class Iterator
{
public:
Iterator() : Current(0) {}
Iterator& operator ++() { Current = Current->Next; return *this; }
Iterator& operator --() { Current = Current->Prev; return *this; }
Iterator operator ++(s32) { Iterator tmp = *this; Current = Current->Next; return tmp; }
Iterator operator --(s32) { Iterator tmp = *this; Current = Current->Prev; return tmp; }
Iterator& operator +=(s32 num)
{
if(num > 0)
{
while (num-- && this->Current != 0) ++(*this);
}
else
{
while(num++ && this->Current != 0) --(*this);
}
return *this;
}
Iterator operator + (s32 num) const { Iterator tmp = *this; return tmp += num; }
Iterator& operator -=(s32 num) { return (*this)+=(-num); }
Iterator operator - (s32 num) const { return (*this)+ (-num); }
bool operator ==(const Iterator& other) const { return Current == other.Current; }
bool operator !=(const Iterator& other) const { return Current != other.Current; }
bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
T & operator * () { return Current->Element; }
T * operator ->() { return &Current->Element; }
private:
explicit Iterator(SKListNode* begin) : Current(begin) {}
SKListNode* Current;
friend class list<T>;
friend class ConstIterator;
};
//! List iterator for const access.
class ConstIterator
{
public:
ConstIterator() : Current(0) {}
ConstIterator(const Iterator& iter) : Current(iter.Current) {}
ConstIterator& operator ++() { Current = Current->Next; return *this; }
ConstIterator& operator --() { Current = Current->Prev; return *this; }
ConstIterator operator ++(s32) { ConstIterator tmp = *this; Current = Current->Next; return tmp; }
ConstIterator operator --(s32) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; }
ConstIterator& operator +=(s32 num)
{
if(num > 0)
{
while(num-- && this->Current != 0) ++(*this);
}
else
{
while(num++ && this->Current != 0) --(*this);
}
return *this;
}
ConstIterator operator + (s32 num) const { ConstIterator tmp = *this; return tmp += num; }
ConstIterator& operator -=(s32 num) { return (*this)+=(-num); }
ConstIterator operator - (s32 num) const { return (*this)+ (-num); }
bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
bool operator ==(const Iterator& other) const { return Current == other.Current; }
bool operator !=(const Iterator& other) const { return Current != other.Current; }
const T & operator * () { return Current->Element; }
const T * operator ->() { return &Current->Element; }
ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; }
private:
explicit ConstIterator(SKListNode* begin) : Current(begin) {}
SKListNode* Current;
friend class Iterator;
friend class list<T>;
};
//! Default constructor for empty list.
list()
: First(0), Last(0), Size(0) {}
//! Copy constructor.
list(const list<T>& other) : First(0), Last(0), Size(0)
{
*this = other;
}
//! Destructor
~list()
{
clear();
}
//! Assignment operator
void operator=(const list<T>& other)
{
if(&other == this)
{
return;
}
clear();
SKListNode* node = other.First;
while(node)
{
push_back(node->Element);
node = node->Next;
}
}
//! Returns amount of elements in list.
/** \return Amount of elements in the list. */
u32 size() const
{
return Size;
}
u32 getSize() const
{
return Size;
}
//! Clears the list, deletes all elements in the list.
/** All existing iterators of this list will be invalid. */
void clear()
{
while(First)
{
SKListNode * next = First->Next;
allocator.destruct(First);
allocator.deallocate(First);
First = next;
}
//First = 0; handled by loop
Last = 0;
Size = 0;
}
//! Checks for empty list.
/** \return True if the list is empty and false if not. */
bool empty() const
{
return (First == 0);
}
//! Adds an element at the end of the list.
/** \param element Element to add to the list. */
void push_back(const T& element)
{
SKListNode* node = allocator.allocate(1);
allocator.construct(node, element);
++Size;
if (First == 0)
First = node;
node->Prev = Last;
if (Last != 0)
Last->Next = node;
Last = node;
}
//! Adds an element at the begin of the list.
/** \param element: Element to add to the list. */
void push_front(const T& element)
{
SKListNode* node = allocator.allocate(1);
allocator.construct(node, element);
++Size;
if (First == 0)
{
Last = node;
First = node;
}
else
{
node->Next = First;
First->Prev = node;
First = node;
}
}
//! Gets first node.
/** \return A list iterator pointing to the beginning of the list. */
Iterator begin()
{
return Iterator(First);
}
//! Gets first node.
/** \return A const list iterator pointing to the beginning of the list. */
ConstIterator begin() const
{
return ConstIterator(First);
}
//! Gets end node.
/** \return List iterator pointing to null. */
Iterator end()
{
return Iterator(0);
}
//! Gets end node.
/** \return Const list iterator pointing to null. */
ConstIterator end() const
{
return ConstIterator(0);
}
//! Gets last element.
/** \return List iterator pointing to the last element of the list. */
Iterator getLast()
{
return Iterator(Last);
}
//! Gets last element.
/** \return Const list iterator pointing to the last element of the list. */
ConstIterator getLast() const
{
return ConstIterator(Last);
}
//! Inserts an element after an element.
/** \param it Iterator pointing to element after which the new element
should be inserted.
\param element The new element to be inserted into the list.
*/
void insert_after(const Iterator& it, const T& element)
{
SKListNode* node = allocator.allocate(1);
allocator.construct(node, element);
node->Next = it.Current->Next;
if (it.Current->Next)
it.Current->Next->Prev = node;
node->Prev = it.Current;
it.Current->Next = node;
++Size;
if (it.Current == Last)
Last = node;
}
//! Inserts an element before an element.
/** \param it Iterator pointing to element before which the new element
should be inserted.
\param element The new element to be inserted into the list.
*/
void insert_before(const Iterator& it, const T& element)
{
SKListNode* node = allocator.allocate(1);
allocator.construct(node, element);
node->Prev = it.Current->Prev;
if (it.Current->Prev)
it.Current->Prev->Next = node;
node->Next = it.Current;
it.Current->Prev = node;
++Size;
if (it.Current == First)
First = node;
}
//! Erases an element.
/** \param it Iterator pointing to the element which shall be erased.
\return Iterator pointing to next element. */
Iterator erase(Iterator& it)
{
// suggest changing this to a const Iterator& and
// working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?)
Iterator returnIterator(it);
++returnIterator;
if(it.Current == First)
{
First = it.Current->Next;
}
else
{
it.Current->Prev->Next = it.Current->Next;
}
if(it.Current == Last)
{
Last = it.Current->Prev;
}
else
{
it.Current->Next->Prev = it.Current->Prev;
}
allocator.destruct(it.Current);
allocator.deallocate(it.Current);
it.Current = 0;
--Size;
return returnIterator;
}
//! Swap the content of this list container with the content of another list
/** Afterward this object will contain the content of the other object and the other
object will contain the content of this object. Iterators will afterward be valid for
the swapped object.
\param other Swap content with this object */
void swap(list<T>& other)
{
core::swap(First, other.First);
core::swap(Last, other.Last);
core::swap(Size, other.Size);
core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
}
typedef T value_type;
typedef u32 size_type;
private:
SKListNode* First;
SKListNode* Last;
u32 Size;
irrAllocator<SKListNode> allocator;
};
} // end namespace core
}// end namespace irr
#endif

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,6 @@
#include "EMessageBoxFlags.h"
#include "ESceneNodeTypes.h"
#include "fast_atof.h"
#include "heapsort.h"
#include "IAnimatedMesh.h"
#include "IAnimatedMeshSceneNode.h"
#include "IAttributes.h"
@ -112,8 +111,6 @@
#include "IRandomizer.h"
#include "IRenderTarget.h"
#include "IrrlichtDevice.h"
#include "irrList.h"
#include "irrMap.h"
#include "irrMath.h"
#include "irrString.h"
#include "irrTypes.h"

View File

@ -8,6 +8,8 @@
#include "irrMath.h"
#include "dimension2d.h"
#include <functional>
namespace irr
{
namespace core
@ -414,5 +416,21 @@ public:
} // end namespace core
} // end namespace irr
namespace std
{
template<class T>
struct hash<irr::core::vector2d<T> >
{
size_t operator()(const irr::core::vector2d<T>& vec) const
{
size_t h1 = hash<T>()(vec.X);
size_t h2 = hash<T>()(vec.Y);
return (h1 << (4 * sizeof(h1)) | h1 >> (4 * sizeof(h1))) ^ h2;
}
};
}
#endif

View File

@ -7,6 +7,8 @@
#include "irrMath.h"
#include <functional>
namespace irr
{
namespace core
@ -466,5 +468,22 @@ namespace core
} // end namespace core
} // end namespace irr
namespace std
{
template<class T>
struct hash<irr::core::vector3d<T> >
{
size_t operator()(const irr::core::vector3d<T>& vec) const
{
size_t h1 = hash<T>()(vec.X);
size_t h2 = hash<T>()(vec.Y);
size_t h3 = hash<T>()(vec.Z);
return (h1 << (5 * sizeof(h1)) | h1 >> (3 * sizeof(h1))) ^ (h2 << (2 * sizeof(h2)) | h2 >> (6 * sizeof(h2))) ^ h3;
}
};
}
#endif

View File

@ -14,7 +14,6 @@
#include "IMeshBuffer.h"
#include "IWriteFile.h"
#include "ITexture.h"
#include "irrMap.h"
namespace irr
@ -60,7 +59,7 @@ bool CB3DMeshWriter::writeMesh(io::IWriteFile* file, IMesh* const mesh, s32 flag
const u32 numMeshBuffers = mesh->getMeshBufferCount();
array<SB3dTexture> texs;
map<ITexture *, u32> tex2id; // TODO: texture pointer as key not sufficient as same texture can have several id's
std::map<ITexture *, u32> tex2id; // TODO: texture pointer as key not sufficient as same texture can have several id's
u32 texsizes = 0;
for (u32 i = 0; i < numMeshBuffers; i++)
{

View File

@ -71,7 +71,7 @@ void CBoneSceneNode::OnAnimate(u32 timeMs)
//updateAbsolutePosition();
// perform the post render process on all children
ISceneNodeList::Iterator it = Children.begin();
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
@ -82,7 +82,7 @@ void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node
{
Node->updateAbsolutePosition();
ISceneNodeList::ConstIterator it = Node->getChildren().begin();
ISceneNodeList::const_iterator it = Node->getChildren().begin();
for (; it != Node->getChildren().end(); ++it)
{
helper_updateAbsolutePositionOfAllChildren( (*it) );

View File

@ -16,7 +16,7 @@
#include "CMemoryFile.h"
#include "CLimitReadFile.h"
#include "CWriteFile.h"
#include "irrList.h"
#include <list>
#if defined (__STRICT_ANSI__)
#error Compiling with __STRICT_ANSI__ not supported. g++ does set this when compiling with -std=c++11 or -std=c++0x. Use instead -std=gnu++11 or -std=gnu++0x. Or use -U__STRICT_ANSI__ to disable strict ansi.
@ -714,11 +714,10 @@ path CFileSystem::getRelativeFilename(const path& filename, const path& director
io::path path1, file, ext;
core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext);
io::path path2(getAbsolutePath(directory));
core::list<io::path> list1, list2;
std::list<io::path> list1, list2;
path1.split(list1, _IRR_TEXT("/\\"), 2);
path2.split(list2, _IRR_TEXT("/\\"), 2);
u32 i=0;
core::list<io::path>::ConstIterator it1,it2;
std::list<io::path>::const_iterator it1,it2;
it1=list1.begin();
it2=list2.begin();
@ -742,19 +741,19 @@ path CFileSystem::getRelativeFilename(const path& filename, const path& director
#endif
for (; i<list1.size() && i<list2.size()
for (; it1 != list1.end() && it2 != list2.end()
#if defined (_IRR_WINDOWS_API_)
&& (io::path(*it1).make_lower()==io::path(*it2).make_lower())
#else
&& (*it1==*it2)
#endif
; ++i)
;)
{
++it1;
++it2;
}
path1=_IRR_TEXT("");
for (; i<list2.size(); ++i)
for (; it2 != list2.end(); ++it2)
path1 += _IRR_TEXT("../");
while (it1 != list1.end())
{

View File

@ -387,11 +387,7 @@ void CGUIEnvironment::clear()
HoveredNoSubelement = 0;
}
// get the root's children in case the root changes in future
const core::list<IGUIElement*>& children = getRootGUIElement()->getChildren();
while (!children.empty())
(*children.getLast())->remove();
getRootGUIElement()->removeAllChildren();
}

View File

@ -165,7 +165,7 @@ bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
}
rectangle.LowerRightCorner.Y = val;
CharacterMap.insert(ch,Areas.size());
CharacterMap.emplace(ch, Areas.size());
// make frame
f.rectNumber = SpriteBank->getPositions().size();
@ -374,7 +374,7 @@ void CGUIFont::readPositions(video::IImage* image, s32& lowerRightPositions)
Areas.push_back(a);
// map letter to character
wchar_t ch = (wchar_t)(lowerRightPositions + 32);
CharacterMap.set(ch, lowerRightPositions);
CharacterMap[ch] = lowerRightPositions;
++lowerRightPositions;
}
@ -435,9 +435,9 @@ u32 CGUIFont::getSpriteNoFromChar(const wchar_t *c) const
s32 CGUIFont::getAreaFromCharacter(const wchar_t c) const
{
core::map<wchar_t, s32>::Node* n = CharacterMap.find(c);
if (n)
return n->getValue();
auto n = CharacterMap.find(c);
if (n != CharacterMap.end())
return n->second;
else
return WrongCharacter;
}

View File

@ -10,9 +10,9 @@
#include "IGUIFontBitmap.h"
#include "irrString.h"
#include "irrMap.h"
#include "IReadFile.h"
#include "irrArray.h"
#include <map>
namespace irr
{
@ -97,7 +97,7 @@ private:
void popTextureCreationFlags(const bool(&flags)[3]);
core::array<SFontArea> Areas;
core::map<wchar_t, s32> CharacterMap;
std::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver;
IGUISpriteBank* SpriteBank;
IGUIEnvironment* Environment;

View File

@ -57,17 +57,12 @@ bool CGUIModalScreen::isVisible() const
}
// any child visible?
bool visible = false;
core::list<IGUIElement*>::ConstIterator it = Children.begin();
for (; it != Children.end(); ++it)
for (const auto& child : Children)
{
if ( (*it)->isVisible() )
{
visible = true;
break;
}
if ( child->isVisible() )
return true;
}
return visible;
return false;
}
bool CGUIModalScreen::isPointInside(const core::position2d<s32>& point) const
@ -98,7 +93,7 @@ bool CGUIModalScreen::OnEvent(const SEvent& event)
if ( !canTakeFocus(event.GUIEvent.Caller))
{
if ( !Children.empty() )
Environment->setFocus(*(Children.begin()));
Environment->setFocus(Children.front());
else
Environment->setFocus(this);
}
@ -110,7 +105,7 @@ bool CGUIModalScreen::OnEvent(const SEvent& event)
if ( isMyChild(event.GUIEvent.Caller) )
{
if ( !Children.empty() )
Environment->setFocus(*(Children.begin()));
Environment->setFocus(Children.front());
else
Environment->setFocus(this);
}
@ -171,15 +166,14 @@ void CGUIModalScreen::draw()
u32 now = os::Timer::getTime();
if (BlinkMode && now - MouseDownTime < 300 && (now / 70)%2)
{
core::list<IGUIElement*>::Iterator it = Children.begin();
core::rect<s32> r;
video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT);
for (; it != Children.end(); ++it)
for (auto child : Children)
{
if ((*it)->isVisible())
if (child->isVisible())
{
r = (*it)->getAbsolutePosition();
r = child->getAbsolutePosition();
r.LowerRightCorner.X += 1;
r.LowerRightCorner.Y += 1;
r.UpperLeftCorner.X -= 1;

View File

@ -34,11 +34,8 @@ CGUIToolBar::CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32
parentwidth = Parent->getAbsolutePosition().getWidth();
s32 parentheight = Parent->getAbsolutePosition().getHeight();
const core::list<IGUIElement*>& children = parent->getChildren();
core::list<IGUIElement*>::ConstIterator it = children.begin();
for (; it != children.end(); ++it)
for (const auto& e : parent->getChildren())
{
const IGUIElement* e = *it;
if ( e->hasType(EGUIET_CONTEXT_MENU)
|| e->hasType(EGUIET_MENU)
|| e->hasType(EGUIET_TOOL_BAR) )

View File

@ -66,11 +66,10 @@ void CGUITreeViewNode::setIcon( const wchar_t* icon )
void CGUITreeViewNode::clearChildren()
{
core::list<CGUITreeViewNode*>::Iterator it;
for( it = Children.begin(); it != Children.end(); it++ )
for (auto child : Children)
{
( *it )->drop();
child->Parent = nullptr;
child->drop();
}
Children.clear();
}
@ -83,9 +82,8 @@ IGUITreeViewNode* CGUITreeViewNode::addChildBack(
void* data /*= 0*/,
IReferenceCounted* data2 /*= 0*/ )
{
CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
Children.push_back( newChild );
auto newChild = new CGUITreeViewNode( Owner, this );
newChild->ParentPos = Children.insert(Children.end(), newChild);
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
@ -107,9 +105,8 @@ IGUITreeViewNode* CGUITreeViewNode::addChildFront(
void* data /*= 0*/,
IReferenceCounted* data2 /*= 0*/ )
{
CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
Children.push_front( newChild );
auto newChild = new CGUITreeViewNode( Owner, this );
newChild->ParentPos = Children.insert(Children.begin(), newChild);
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
@ -124,7 +121,7 @@ IGUITreeViewNode* CGUITreeViewNode::addChildFront(
}
IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
IGUITreeViewNode* other,
IGUITreeViewNode* iother,
const wchar_t* text,
const wchar_t* icon /*= 0*/,
s32 imageIndex /*= -1*/,
@ -132,33 +129,27 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
void* data /*= 0*/,
IReferenceCounted* data2/* = 0*/ )
{
core::list<CGUITreeViewNode*>::Iterator itOther;
CGUITreeViewNode* newChild = 0;
for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
{
if( other == *itOther )
{
newChild = new CGUITreeViewNode( Owner, this );
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
newChild->SelectedImageIndex = selectedImageIndex;
newChild->Data = data;
newChild->Data2 = data2;
if( data2 )
{
data2->grab();
}
Children.insert_after( itOther, newChild );
break;
}
}
// This cast is needed to access the ParentPos member of `other`.
// The abstraction was already broken, because Children is a list of
// CGUITreeViewNode, not IGUITreeViewNode. The existing code was
// implicitly casting through pointer comparison.
auto other = static_cast<CGUITreeViewNode*>(iother);
assert(other->Parent == this);
auto newChild = new CGUITreeViewNode( Owner, this );
newChild->ParentPos = Children.insert(std::next(other->ParentPos), newChild);
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
newChild->SelectedImageIndex = selectedImageIndex;
newChild->Data = data;
newChild->Data2 = data2;
if( data2 )
data2->grab();
return newChild;
}
IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
IGUITreeViewNode* other,
IGUITreeViewNode* iother,
const wchar_t* text,
const wchar_t* icon /*= 0*/,
s32 imageIndex /*= -1*/,
@ -166,28 +157,18 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
void* data /*= 0*/,
IReferenceCounted* data2/* = 0*/ )
{
core::list<CGUITreeViewNode*>::Iterator itOther;
CGUITreeViewNode* newChild = 0;
for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
{
if( other == *itOther )
{
newChild = new CGUITreeViewNode( Owner, this );
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
newChild->SelectedImageIndex = selectedImageIndex;
newChild->Data = data;
newChild->Data2 = data2;
if( data2 )
{
data2->grab();
}
Children.insert_before( itOther, newChild );
break;
}
}
auto other = static_cast<CGUITreeViewNode*>(iother);
assert(other->Parent == this);
auto newChild = new CGUITreeViewNode( Owner, this );
newChild->ParentPos = Children.insert(other->ParentPos, newChild);
newChild->Text = text;
newChild->Icon = icon;
newChild->ImageIndex = imageIndex;
newChild->SelectedImageIndex = selectedImageIndex;
newChild->Data = data;
newChild->Data2 = data2;
if( data2 )
data2->grab();
return newChild;
}
@ -199,7 +180,7 @@ IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const
}
else
{
return *( Children.begin() );
return Children.front();
}
}
@ -211,54 +192,25 @@ IGUITreeViewNode* CGUITreeViewNode::getLastChild() const
}
else
{
return *( Children.getLast() );
return Children.back();
}
}
IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const
{
core::list<CGUITreeViewNode*>::Iterator itThis;
core::list<CGUITreeViewNode*>::Iterator itOther;
CGUITreeViewNode* other = 0;
if( Parent )
{
for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
{
if( this == *itThis )
{
if( itThis != Parent->Children.begin() )
{
other = *itOther;
}
break;
}
itOther = itThis;
}
}
return other;
if (!Parent || ParentPos == Parent->Children.begin())
return nullptr;
return *std::prev(ParentPos);
}
IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
{
core::list<CGUITreeViewNode*>::Iterator itThis;
CGUITreeViewNode* other = 0;
if( Parent )
{
for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
{
if( this == *itThis )
{
if( itThis != Parent->Children.getLast() )
{
other = *( ++itThis );
}
break;
}
}
}
return other;
if (!Parent)
return nullptr;
auto nextIt = std::next(ParentPos);
if (nextIt == Parent->Children.end())
return nullptr;
return *nextIt;
}
IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
@ -286,73 +238,40 @@ IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
return next;
}
bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child )
bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* ichild )
{
core::list<CGUITreeViewNode*>::Iterator itChild;
bool deleted = false;
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
{
if( child == *itChild )
{
child->drop();
Children.erase( itChild );
deleted = true;
break;
}
}
return deleted;
auto child = static_cast<CGUITreeViewNode*>(ichild);
assert(child->Parent == this);
Children.erase(child->ParentPos);
child->Parent = nullptr;
child->drop();
return true;
}
bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child )
bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* ichild )
{
core::list<CGUITreeViewNode*>::Iterator itChild;
core::list<CGUITreeViewNode*>::Iterator itOther;
CGUITreeViewNode* nodeTmp;
bool moved = false;
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
{
if( child == *itChild )
{
if( itChild != Children.begin() )
{
nodeTmp = *itChild;
*itChild = *itOther;
*itOther = nodeTmp;
moved = true;
}
break;
}
itOther = itChild;
}
return moved;
auto child = static_cast<CGUITreeViewNode*>(ichild);
assert(child->Parent == this);
if (child->ParentPos == Children.begin())
return false;
auto curPos = child->ParentPos;
auto prevPos = std::prev(child->ParentPos);
std::swap(*curPos, *prevPos);
std::swap((*curPos)->ParentPos, (*prevPos)->ParentPos);
return true;
}
bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child )
bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* ichild )
{
core::list<CGUITreeViewNode*>::Iterator itChild;
core::list<CGUITreeViewNode*>::Iterator itOther;
CGUITreeViewNode* nodeTmp;
bool moved = false;
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
{
if( child == *itChild )
{
if( itChild != Children.getLast() )
{
itOther = itChild;
++itOther;
nodeTmp = *itChild;
*itChild = *itOther;
*itOther = nodeTmp;
moved = true;
}
break;
}
}
return moved;
auto child = static_cast<CGUITreeViewNode*>(ichild);
assert(child->Parent == this);
auto nextPos = std::next(child->ParentPos);
if (nextPos == Children.end())
return false;
auto curPos = child->ParentPos;
std::swap(*curPos, *nextPos);
std::swap((*curPos)->ParentPos, (*nextPos)->ParentPos);
return true;
}
void CGUITreeViewNode::setExpanded( bool expanded )

View File

@ -5,7 +5,6 @@
#define __C_GUI_TREE_VIEW_H_INCLUDED__
#include "IGUITreeView.h"
#include "irrList.h"
namespace irr
@ -93,7 +92,7 @@ namespace gui
//! returns the child item count
virtual u32 getChildCount() const _IRR_OVERRIDE_
{ return Children.getSize(); }
{ return Children.size(); }
//! removes all children (recursive) from this node
virtual void clearChildren() _IRR_OVERRIDE_;
@ -231,7 +230,10 @@ namespace gui
void* Data;
IReferenceCounted* Data2;
bool Expanded;
core::list<CGUITreeViewNode*> Children;
std::list<CGUITreeViewNode*> Children;
// Position of this node in Parent->Children.
// Only valid when Parent != NULL
std::list<CGUITreeViewNode*>::iterator ParentPos;
};

View File

@ -14,7 +14,6 @@
#include "CIrrDeviceOSX.h"
#include "IEventReceiver.h"
#include "irrList.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"

View File

@ -8,7 +8,6 @@
#include "CIrrDeviceSDL.h"
#include "IEventReceiver.h"
#include "irrList.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"
@ -26,28 +25,26 @@
#include <emscripten.h>
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "CSDLManager.h"
#endif
static int SDLDeviceInstances = 0;
namespace irr
{
namespace video
{
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params,
io::IFileSystem* io, HWND window);
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceSDL* device);
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#endif
#if defined(_IRR_COMPILE_WITH_OGLES2_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
IVideoDriver* createOGLES2Driver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#ifdef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#endif
#if defined(_IRR_COMPILE_WITH_WEBGL1_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
IVideoDriver* createWebGL1Driver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#ifdef _IRR_COMPILE_WITH_WEBGL1_
IVideoDriver* createWebGL1Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#endif
} // end namespace video
@ -461,7 +458,8 @@ void CIrrDeviceSDL::createDriver()
case video::EDT_OPENGL:
#ifdef _IRR_COMPILE_WITH_OPENGL_
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
ContextManager = new video::CSDLManager(this);
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
#else
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
#endif

View File

@ -12,7 +12,6 @@
#include "CIrrDeviceWin32.h"
#include "IEventReceiver.h"
#include "irrList.h"
#include "os.h"
#include "CTimer.h"

View File

@ -48,8 +48,7 @@ find_package(ZLIB REQUIRED)
find_package(JPEG REQUIRED)
find_package(PNG REQUIRED)
# To configure the features available in this Irrlicht build please edit
# include/IrrCompileConfig.h and re-run CMake from a clean state
# To configure the features available in this Irrlicht build please edit include/IrrCompileConfig.h.
include(CheckSymbolExists)
set(CMAKE_REQUIRED_INCLUDES ${PROJECT_SOURCE_DIR}/include)
unset(OGLES1_ENABLED CACHE)
@ -58,6 +57,9 @@ unset(OGL_ENABLED CACHE)
unset(XINPUT2_ENABLED CACHE)
unset(SDL_ENABLED CACHE)
# tell cmake about the dependency
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_REQUIRED_INCLUDES}/IrrCompileConfig.h)
check_symbol_exists(_IRR_COMPILE_WITH_OGLES1_ "IrrCompileConfig.h" OGLES1_ENABLED)
if(OGLES1_ENABLED)
# only tested on Android, probably works on Linux (is this needed anywhere else?)
@ -75,11 +77,12 @@ if(OGL_ENABLED)
set(OpenGL_GL_PREFERENCE "LEGACY")
find_package(OpenGL REQUIRED)
endif()
check_symbol_exists(_IRR_LINUX_X11_XINPUT2_ "IrrCompileConfig.h" XINPUT2_ENABLED)
if(XINPUT2_ENABLED)
find_library(XINPUT_LIBRARY Xi REQUIRED)
if(NOT ANDROID AND NOT APPLE)
check_symbol_exists(_IRR_LINUX_X11_XINPUT2_ "IrrCompileConfig.h" XINPUT2_ENABLED)
if(XINPUT2_ENABLED)
find_library(XINPUT_LIBRARY Xi REQUIRED)
endif()
endif()
check_symbol_exists(_IRR_COMPILE_WITH_SDL_DEVICE_ "IrrCompileConfig.h" SDL_ENABLED)
if(SDL_ENABLED)
find_package(SDL2 CONFIG REQUIRED)
@ -185,6 +188,7 @@ set(IRRDRVROBJ
CGLXManager.cpp
CWGLManager.cpp
CEGLManager.cpp
CSDLManager.cpp
mt_opengl_loader.cpp
)

View File

@ -8,8 +8,8 @@
#include "CMeshBuffer.h"
#include "SAnimatedMesh.h"
#include "os.h"
#include "irrMap.h"
#include "triangle3d.h"
#include <map>
namespace irr
{
@ -1789,8 +1789,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
buf->Vertices.reallocate(vcount);
buf->Indices.reallocate(icount);
core::map<const video::S3DVertex, const u16> sind; // search index for fast operation
typedef core::map<const video::S3DVertex, const u16>::Node snode;
std::map<const video::S3DVertex, const u16> sind; // search index for fast operation
typedef std::map<const video::S3DVertex, const u16>::iterator snode;
// Main algorithm
u32 highest = 0;
@ -1820,45 +1820,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
// Output the best triangle
u16 newind = buf->Vertices.size();
snode *s = sind.find(v[tc[highest].ind[0]]);
snode s = sind.find(v[tc[highest].ind[0]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[0]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[0]], newind);
sind.emplace(v[tc[highest].ind[0]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[1]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[1]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[1]], newind);
sind.emplace(v[tc[highest].ind[1]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[2]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[2]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[2]], newind);
sind.emplace(v[tc[highest].ind[2]], newind);
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
vc[tc[highest].ind[0]].NumActiveTris--;
@ -1901,8 +1901,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
buf->Vertices.reallocate(vcount);
buf->Indices.reallocate(icount);
core::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation
typedef core::map<const video::S3DVertex2TCoords, const u16>::Node snode;
std::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation
typedef std::map<const video::S3DVertex2TCoords, const u16>::iterator snode;
// Main algorithm
u32 highest = 0;
@ -1932,45 +1932,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
// Output the best triangle
u16 newind = buf->Vertices.size();
snode *s = sind.find(v[tc[highest].ind[0]]);
snode s = sind.find(v[tc[highest].ind[0]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[0]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[0]], newind);
sind.emplace(v[tc[highest].ind[0]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[1]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[1]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[1]], newind);
sind.emplace(v[tc[highest].ind[1]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[2]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[2]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[2]], newind);
sind.emplace(v[tc[highest].ind[2]], newind);
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
vc[tc[highest].ind[0]].NumActiveTris--;
@ -2014,8 +2014,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
buf->Vertices.reallocate(vcount);
buf->Indices.reallocate(icount);
core::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation
typedef core::map<const video::S3DVertexTangents, const u16>::Node snode;
std::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation
typedef std::map<const video::S3DVertexTangents, const u16>::iterator snode;
// Main algorithm
u32 highest = 0;
@ -2045,45 +2045,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
// Output the best triangle
u16 newind = buf->Vertices.size();
snode *s = sind.find(v[tc[highest].ind[0]]);
snode s = sind.find(v[tc[highest].ind[0]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[0]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[0]], newind);
sind.emplace(v[tc[highest].ind[0]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[1]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[1]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[1]], newind);
sind.emplace(v[tc[highest].ind[1]], newind);
newind++;
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
s = sind.find(v[tc[highest].ind[2]]);
if (!s)
if (s == sind.end())
{
buf->Vertices.push_back(v[tc[highest].ind[2]]);
buf->Indices.push_back(newind);
sind.insert(v[tc[highest].ind[2]], newind);
sind.emplace(v[tc[highest].ind[2]], newind);
}
else
{
buf->Indices.push_back(s->getValue());
buf->Indices.push_back(s->second);
}
vc[tc[highest].ind[0]].NumActiveTris--;

View File

@ -11,7 +11,6 @@
#include "IGPUProgrammingServices.h"
#include "irrArray.h"
#include "irrString.h"
#include "irrMap.h"
#include "IAttributes.h"
#include "IMesh.h"
#include "IMeshBuffer.h"

View File

@ -70,9 +70,9 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
const u32 WORD_BUFFER_LENGTH = 512;
core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > vertexBuffer(1000);
core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > normalsBuffer(1000);
core::array<core::vector2df, core::irrAllocatorFast<core::vector2df> > textureCoordBuffer(1000);
core::array<core::vector3df> vertexBuffer(1000);
core::array<core::vector3df> normalsBuffer(1000);
core::array<core::vector2df> textureCoordBuffer(1000);
SObjMtl * currMtl = new SObjMtl();
Materials.push_back(currMtl);
@ -250,16 +250,16 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
}
int vertLocation;
core::map<video::S3DVertex, int>::Node* n = currMtl->VertMap.find(v);
if (n)
auto n = currMtl->VertMap.find(v);
if (n != currMtl->VertMap.end())
{
vertLocation = n->getValue();
vertLocation = n->second;
}
else
{
currMtl->Meshbuffer->Vertices.push_back(v);
vertLocation = currMtl->Meshbuffer->Vertices.size() -1;
currMtl->VertMap.insert(v, vertLocation);
currMtl->VertMap.emplace(v, vertLocation);
}
faceCorners.push_back(vertLocation);

View File

@ -5,12 +5,12 @@
#ifndef __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
#define __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
#include <map>
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "ISceneManager.h"
#include "irrString.h"
#include "SMeshBuffer.h"
#include "irrMap.h"
namespace irr
{
@ -61,7 +61,7 @@ private:
Meshbuffer->Material = o.Meshbuffer->Material;
}
core::map<video::S3DVertex, int> VertMap;
std::map<video::S3DVertex, int> VertMap;
scene::SMeshBuffer *Meshbuffer;
core::stringc Name;
core::stringc Group;

View File

@ -441,9 +441,8 @@ COGLES2Driver::~COGLES2Driver()
const E_VERTEX_TYPE vType = mb->getVertexType();
const u32 vertexSize = getVertexPitchFromType(vType);
//buffer vertex data, and convert colours...
core::array<c8> buffer(vertexSize * vertexCount);
memcpy(buffer.pointer(), vertices, vertexSize * vertexCount);
const void *buffer = vertices;
size_t bufferSize = vertexSize * vertexCount;
//get or create buffer
bool newBuffer = false;
@ -453,7 +452,7 @@ COGLES2Driver::~COGLES2Driver()
if (!HWBuffer->vbo_verticesID) return false;
newBuffer = true;
}
else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize)
else if (HWBuffer->vbo_verticesSize < bufferSize)
{
newBuffer = true;
}
@ -462,15 +461,15 @@ COGLES2Driver::~COGLES2Driver()
// copy data to graphics card
if (!newBuffer)
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, buffer.const_pointer());
glBufferSubData(GL_ARRAY_BUFFER, 0, bufferSize, buffer);
else
{
HWBuffer->vbo_verticesSize = vertexCount * vertexSize;
HWBuffer->vbo_verticesSize = bufferSize;
if (HWBuffer->Mapped_Vertex == scene::EHM_STATIC)
glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW);
else
glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_DYNAMIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_DYNAMIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);

View File

@ -112,12 +112,12 @@ bool COGLES1Driver::genericDriverInit(const core::dimension2d<u32>& screenSize,
glPixelStorei(GL_PACK_ALIGNMENT, 1);
UserClipPlane.reallocate(MaxUserClipPlanes);
UserClipPlaneEnabled.reallocate(MaxUserClipPlanes);
UserClipPlaneEnabled.resize(MaxUserClipPlanes);
for (s32 i = 0; i < MaxUserClipPlanes; ++i)
{
UserClipPlane.push_back(core::plane3df());
UserClipPlaneEnabled.push_back(false);
UserClipPlaneEnabled[i] = false;
}
for (s32 i = 0; i < ETS_COUNT; ++i)

View File

@ -363,7 +363,7 @@ namespace video
SMaterial Material, LastMaterial;
core::array<core::plane3df> UserClipPlane;
core::array<bool> UserClipPlaneEnabled;
std::vector<bool> UserClipPlaneEnabled;
core::stringc VendorName;

View File

@ -20,10 +20,6 @@
#include "mt_opengl.h"
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
#include "CIrrDeviceSDL.h"
#endif
namespace irr
{
namespace video
@ -32,7 +28,6 @@ namespace video
// Statics variables
const u16 COpenGLDriver::Quad2DIndices[4] = { 0, 1, 2, 3 };
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), CacheHandler(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE), Params(params),
@ -42,23 +37,6 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFil
setDebugName("COpenGLDriver");
#endif
}
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceSDL* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), CacheHandler(0),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
Params(params), SDLDevice(device), ContextManager(0)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
genericDriverInit();
}
#endif
bool COpenGLDriver::initDriver()
{
@ -267,11 +245,6 @@ bool COpenGLDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth,
if (ContextManager)
ContextManager->activateContext(videoData, true);
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
if (SDLDevice)
glFrontFace(GL_CW);
#endif
clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);
return true;
@ -288,14 +261,6 @@ bool COpenGLDriver::endScene()
if (ContextManager)
status = ContextManager->swapBuffers();
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
if (SDLDevice)
{
SDLDevice->SwapWindow();
status = true;
}
#endif
// todo: console device present
return status;
@ -4437,7 +4402,6 @@ namespace irr
namespace video
{
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
@ -4454,22 +4418,6 @@ namespace video
return 0;
#endif
}
#endif
// -----------------------------------
// SDL VERSION
// -----------------------------------
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceSDL* device)
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
return new COpenGLDriver(params, io, device);
#else
return 0;
#endif // _IRR_COMPILE_WITH_OPENGL_
}
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
} // end namespace
} // end namespace

View File

@ -44,13 +44,7 @@ namespace video
EOFPS_DISABLE_TO_ENABLE // switch from programmable to fixed pipeline.
};
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceSDL* device);
#endif
bool initDriver();
@ -520,10 +514,6 @@ namespace video
S3DVertex Quad2DVertices[4];
static const u16 Quad2DIndices[4];
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
CIrrDeviceSDL *SDLDevice;
#endif
IContextManager* ContextManager;
};

View File

@ -0,0 +1,56 @@
// Copyright (C) 2022 sfan5
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "CSDLManager.h"
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && defined(_IRR_COMPILE_WITH_OPENGL_)
#include "CIrrDeviceSDL.h"
#include "COpenGLCommon.h"
namespace irr
{
namespace video
{
CSDLManager::CSDLManager(CIrrDeviceSDL* device) : IContextManager(), SDLDevice(device)
{
#ifdef _DEBUG
setDebugName("CSDLManager");
#endif
}
bool CSDLManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data)
{
Data = data;
return true;
}
const SExposedVideoData& CSDLManager::getContext() const
{
return Data;
}
bool CSDLManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)
{
// unclear if this is still needed:
glFrontFace(GL_CW);
return true;
}
void* CSDLManager::getProcAddress(const std::string &procName)
{
return SDL_GL_GetProcAddress(procName.c_str());
}
bool CSDLManager::swapBuffers()
{
SDLDevice->SwapWindow();
return true;
}
}
}
#endif

View File

@ -0,0 +1,53 @@
// Copyright (C) 2022 sfan5
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_SDL_MANAGER_H_INCLUDED__
#define __C_SDL_MANAGER_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && defined(_IRR_COMPILE_WITH_OPENGL_)
#include "IContextManager.h"
namespace irr
{
class CIrrDeviceSDL;
namespace video
{
// Manager for SDL with OpenGL
class CSDLManager : public IContextManager
{
public:
CSDLManager(CIrrDeviceSDL* device);
virtual ~CSDLManager() {}
virtual bool initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data) _IRR_OVERRIDE_;
virtual void terminate() _IRR_OVERRIDE_ {};
virtual bool generateSurface() _IRR_OVERRIDE_ { return true; };
virtual void destroySurface() _IRR_OVERRIDE_ {};
virtual bool generateContext() _IRR_OVERRIDE_ { return true; };
virtual void destroyContext() _IRR_OVERRIDE_ {};
virtual const SExposedVideoData& getContext() const _IRR_OVERRIDE_;
virtual bool activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero=false) _IRR_OVERRIDE_;
virtual void* getProcAddress(const std::string &procName) _IRR_OVERRIDE_;
virtual bool swapBuffers() _IRR_OVERRIDE_;
private:
SExposedVideoData Data;
CIrrDeviceSDL *SDLDevice;
};
}
}
#endif
#endif

View File

@ -855,7 +855,7 @@ ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* st
ISceneNode* node = 0;
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
ISceneNodeList::const_iterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromName(name, *it);
@ -879,7 +879,7 @@ ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
ISceneNode* node = 0;
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
ISceneNodeList::const_iterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromId(id, *it);
@ -903,7 +903,7 @@ ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, IS
ISceneNode* node = 0;
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
ISceneNodeList::const_iterator it = list.begin();
for (; it!=list.end(); ++it)
{
node = getSceneNodeFromType(type, *it);
@ -925,7 +925,7 @@ void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array<sce
outNodes.push_back(start);
const ISceneNodeList& list = start->getChildren();
ISceneNodeList::ConstIterator it = list.begin();
ISceneNodeList::const_iterator it = list.begin();
for (; it!=list.end(); ++it)
{

View File

@ -231,6 +231,9 @@ namespace scene
struct DefaultNodeEntry
{
DefaultNodeEntry()
{ }
DefaultNodeEntry(ISceneNode* n) :
Node(n), TextureValue(0)
{
@ -251,6 +254,9 @@ namespace scene
//! sort on distance (center) to camera
struct TransparentNodeEntry
{
TransparentNodeEntry()
{ }
TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera)
: Node(n)
{

View File

@ -1042,7 +1042,7 @@ void CSkinnedMesh::finalize()
for (i=0; i<LocalBuffers.size(); ++i)
{
Vertices_Moved.push_back( core::array<bool>() );
Vertices_Moved.push_back( core::array<char>() );
Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());
}

View File

@ -196,7 +196,9 @@ private:
core::array<SJoint*> AllJoints;
core::array<SJoint*> RootJoints;
core::array< core::array<bool> > Vertices_Moved;
// bool can't be used here because std::vector<bool>
// doesn't allow taking a reference to individual elements.
core::array< core::array<char> > Vertices_Moved;
core::aabbox3d<f32> BoundingBox;