mirror of
https://github.com/minetest/irrlicht.git
synced 2025-07-03 08:40:26 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
128cf1696c | |||
3e81f38098 | |||
593103a261 | |||
0732807cc8 | |||
00a7741cd4 | |||
51ae495c4a | |||
6928c7eb6f | |||
372b3642bf | |||
51dad49d8b |
@ -1,3 +1,4 @@
|
|||||||
|
#include <iostream>
|
||||||
#include <irrlicht.h>
|
#include <irrlicht.h>
|
||||||
#include "exampleHelper.h"
|
#include "exampleHelper.h"
|
||||||
|
|
||||||
@ -6,6 +7,8 @@ using namespace irr;
|
|||||||
static IrrlichtDevice *device = nullptr;
|
static IrrlichtDevice *device = nullptr;
|
||||||
static int test_fail = 0;
|
static int test_fail = 0;
|
||||||
|
|
||||||
|
extern void test_irr_array();
|
||||||
|
|
||||||
static video::E_DRIVER_TYPE chooseDriver(const char *arg_)
|
static video::E_DRIVER_TYPE chooseDriver(const char *arg_)
|
||||||
{
|
{
|
||||||
if (core::stringc(arg_) == "null")
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
run_unit_tests();
|
||||||
|
|
||||||
SIrrlichtCreationParameters p;
|
SIrrlichtCreationParameters p;
|
||||||
p.DriverType = chooseDriver(argc > 1 ? argv[1] : "");
|
p.DriverType = chooseDriver(argc > 1 ? argv[1] : "");
|
||||||
p.WindowSize = core::dimension2du(640, 480);
|
p.WindowSize = core::dimension2du(640, 480);
|
||||||
|
135
examples/AutomatedTest/test_array.cpp
Normal file
135
examples/AutomatedTest/test_array.cpp
Normal 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;
|
||||||
|
}
|
30
examples/AutomatedTest/test_helper.h
Normal file
30
examples/AutomatedTest/test_helper.h
Normal 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)
|
@ -1,3 +1,5 @@
|
|||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(IRREXAMPLES
|
set(IRREXAMPLES
|
||||||
# removed
|
# removed
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#define __I_GUI_ELEMENT_H_INCLUDED__
|
#define __I_GUI_ELEMENT_H_INCLUDED__
|
||||||
|
|
||||||
#include "IReferenceCounted.h"
|
#include "IReferenceCounted.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "rect.h"
|
#include "rect.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
@ -14,6 +13,10 @@
|
|||||||
#include "EGUIAlignment.h"
|
#include "EGUIAlignment.h"
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
#include "IGUIEnvironment.h"
|
#include "IGUIEnvironment.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -50,12 +53,9 @@ public:
|
|||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~IGUIElement()
|
virtual ~IGUIElement()
|
||||||
{
|
{
|
||||||
// delete all children
|
for (auto child : Children) {
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
child->Parent = nullptr;
|
||||||
for (; it != Children.end(); ++it)
|
child->drop();
|
||||||
{
|
|
||||||
(*it)->Parent = 0;
|
|
||||||
(*it)->drop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,10 +239,9 @@ public:
|
|||||||
recalculateAbsolutePosition(false);
|
recalculateAbsolutePosition(false);
|
||||||
|
|
||||||
// update all children
|
// update all children
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
for (auto child : Children)
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
(*it)->updateAbsolutePosition();
|
child->updateAbsolutePosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,20 +262,19 @@ public:
|
|||||||
{
|
{
|
||||||
IGUIElement* target = 0;
|
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())
|
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);
|
target = (*it)->getElementFromPoint(point);
|
||||||
if (target)
|
if (target)
|
||||||
return target;
|
return target;
|
||||||
|
|
||||||
--it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,17 +306,19 @@ public:
|
|||||||
//! Removes a child.
|
//! Removes a child.
|
||||||
virtual void removeChild(IGUIElement* child)
|
virtual void removeChild(IGUIElement* child)
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
assert(child->Parent == this);
|
||||||
for (; it != Children.end(); ++it)
|
Children.erase(child->ParentPos);
|
||||||
if ((*it) == child)
|
child->Parent = nullptr;
|
||||||
{
|
child->drop();
|
||||||
(*it)->Parent = 0;
|
|
||||||
(*it)->drop();
|
|
||||||
Children.erase(it);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Removes all children.
|
||||||
|
virtual void removeAllChildren() {
|
||||||
|
while (!Children.empty()) {
|
||||||
|
auto child = Children.back();
|
||||||
|
child->remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Removes this element from its parent.
|
//! Removes this element from its parent.
|
||||||
virtual void remove()
|
virtual void remove()
|
||||||
@ -333,9 +333,8 @@ public:
|
|||||||
{
|
{
|
||||||
if ( isVisible() )
|
if ( isVisible() )
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
for (auto child : Children)
|
||||||
for (; it != Children.end(); ++it)
|
child->draw();
|
||||||
(*it)->draw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,9 +344,8 @@ public:
|
|||||||
{
|
{
|
||||||
if ( isVisible() )
|
if ( isVisible() )
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
for (auto child : Children)
|
||||||
for (; it != Children.end(); ++it)
|
child->OnPostRender( timeMs );
|
||||||
(*it)->OnPostRender( timeMs );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,20 +553,15 @@ public:
|
|||||||
|
|
||||||
//! Brings a child to front
|
//! Brings a child to front
|
||||||
/** \return True if successful, false if not. */
|
/** \return True if successful, false if not. */
|
||||||
virtual bool bringToFront(IGUIElement* element)
|
virtual bool bringToFront(IGUIElement* child)
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
if (child->Parent != this)
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
|
||||||
if (element == (*it))
|
|
||||||
{
|
|
||||||
Children.erase(it);
|
|
||||||
Children.push_back(element);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
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. */
|
/** \return True if successful, false if not. */
|
||||||
virtual bool sendToBack(IGUIElement* child)
|
virtual bool sendToBack(IGUIElement* child)
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
if (child->Parent != this)
|
||||||
if (child == (*it)) // already there
|
|
||||||
return true;
|
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
|
||||||
if (child == (*it))
|
|
||||||
{
|
|
||||||
Children.erase(it);
|
|
||||||
Children.push_front(child);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
if (child->ParentPos == Children.begin()) // already there
|
||||||
|
return true;
|
||||||
|
Children.erase(child->ParentPos);
|
||||||
|
child->ParentPos = Children.insert(Children.begin(), child);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns list with children of this element
|
//! Returns list with children of this element
|
||||||
virtual const core::list<IGUIElement*>& getChildren() const
|
virtual const std::list<IGUIElement*>& getChildren() const
|
||||||
{
|
{
|
||||||
return Children;
|
return Children;
|
||||||
}
|
}
|
||||||
@ -610,14 +596,13 @@ public:
|
|||||||
{
|
{
|
||||||
IGUIElement* e = 0;
|
IGUIElement* e = 0;
|
||||||
|
|
||||||
core::list<IGUIElement*>::ConstIterator it = Children.begin();
|
for (auto child : Children)
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
if ((*it)->getID() == id)
|
if (child->getID() == id)
|
||||||
return (*it);
|
return child;
|
||||||
|
|
||||||
if (searchchildren)
|
if (searchchildren)
|
||||||
e = (*it)->getElementFromId(id, true);
|
e = child->getElementFromId(id, true);
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
@ -663,7 +648,7 @@ public:
|
|||||||
if (wanted==-2)
|
if (wanted==-2)
|
||||||
wanted = 1073741824; // maximum s32
|
wanted = 1073741824; // maximum s32
|
||||||
|
|
||||||
core::list<IGUIElement*>::ConstIterator it = Children.begin();
|
auto it = Children.begin();
|
||||||
|
|
||||||
s32 closestOrder, currentOrder;
|
s32 closestOrder, currentOrder;
|
||||||
|
|
||||||
@ -806,10 +791,40 @@ protected:
|
|||||||
child->remove(); // remove from old parent
|
child->remove(); // remove from old parent
|
||||||
child->LastParentRect = getAbsolutePosition();
|
child->LastParentRect = getAbsolutePosition();
|
||||||
child->Parent = this;
|
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
|
// not virtual because needed in constructor
|
||||||
void recalculateAbsolutePosition(bool recursive)
|
void recalculateAbsolutePosition(bool recursive)
|
||||||
{
|
{
|
||||||
@ -931,10 +946,9 @@ protected:
|
|||||||
if ( recursive )
|
if ( recursive )
|
||||||
{
|
{
|
||||||
// update all children
|
// update all children
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
for (auto child : Children)
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
(*it)->recalculateAbsolutePosition(recursive);
|
child->recalculateAbsolutePosition(recursive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -942,11 +956,14 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! List of all children of this element
|
//! List of all children of this element
|
||||||
core::list<IGUIElement*> Children;
|
std::list<IGUIElement*> Children;
|
||||||
|
|
||||||
//! Pointer to the parent
|
//! Pointer to the parent
|
||||||
IGUIElement* Parent;
|
IGUIElement* Parent;
|
||||||
|
|
||||||
|
//! Our position in the parent list. Only valid when Parent != nullptr
|
||||||
|
std::list<IGUIElement*>::iterator ParentPos;
|
||||||
|
|
||||||
//! relative rect of element
|
//! relative rect of element
|
||||||
core::rect<s32> RelativeRect;
|
core::rect<s32> RelativeRect;
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ namespace scene
|
|||||||
class ISceneManager;
|
class ISceneManager;
|
||||||
|
|
||||||
//! Typedef for list of scene nodes
|
//! Typedef for list of scene nodes
|
||||||
typedef core::list<ISceneNode*> ISceneNodeList;
|
typedef std::list<ISceneNode*> ISceneNodeList;
|
||||||
|
|
||||||
//! Scene node interface.
|
//! Scene node interface.
|
||||||
/** A scene node is a node in the hierarchical scene graph. Every scene
|
/** A scene node is a node in the hierarchical scene graph. Every scene
|
||||||
@ -81,7 +81,7 @@ namespace scene
|
|||||||
{
|
{
|
||||||
if (IsVisible)
|
if (IsVisible)
|
||||||
{
|
{
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
(*it)->OnRegisterSceneNode();
|
(*it)->OnRegisterSceneNode();
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ namespace scene
|
|||||||
|
|
||||||
// perform the post render process on all children
|
// perform the post render process on all children
|
||||||
|
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
(*it)->OnAnimate(timeMs);
|
(*it)->OnAnimate(timeMs);
|
||||||
}
|
}
|
||||||
@ -289,7 +289,7 @@ namespace scene
|
|||||||
e.g. because it couldn't be found in the children list. */
|
e.g. because it couldn't be found in the children list. */
|
||||||
virtual bool removeChild(ISceneNode* child)
|
virtual bool removeChild(ISceneNode* child)
|
||||||
{
|
{
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
if ((*it) == child)
|
if ((*it) == child)
|
||||||
{
|
{
|
||||||
@ -309,7 +309,7 @@ namespace scene
|
|||||||
*/
|
*/
|
||||||
virtual void removeAll()
|
virtual void removeAll()
|
||||||
{
|
{
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
{
|
{
|
||||||
(*it)->Parent = 0;
|
(*it)->Parent = 0;
|
||||||
@ -519,7 +519,7 @@ namespace scene
|
|||||||
|
|
||||||
//! Returns a const reference to the list of all children.
|
//! Returns a const reference to the list of all children.
|
||||||
/** \return The list of all children of this node. */
|
/** \return The list of all children of this node. */
|
||||||
const core::list<ISceneNode*>& getChildren() const
|
const std::list<ISceneNode*>& getChildren() const
|
||||||
{
|
{
|
||||||
return Children;
|
return Children;
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@ namespace scene
|
|||||||
|
|
||||||
// clone children
|
// clone children
|
||||||
|
|
||||||
ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
|
ISceneNodeList::iterator it = toCopyFrom->Children.begin();
|
||||||
for (; it != toCopyFrom->Children.end(); ++it)
|
for (; it != toCopyFrom->Children.end(); ++it)
|
||||||
(*it)->clone(this, newManager);
|
(*it)->clone(this, newManager);
|
||||||
}
|
}
|
||||||
@ -622,7 +622,7 @@ namespace scene
|
|||||||
{
|
{
|
||||||
SceneManager = newManager;
|
SceneManager = newManager;
|
||||||
|
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
(*it)->setSceneManager(newManager);
|
(*it)->setSceneManager(newManager);
|
||||||
}
|
}
|
||||||
@ -646,7 +646,7 @@ namespace scene
|
|||||||
ISceneNode* Parent;
|
ISceneNode* Parent;
|
||||||
|
|
||||||
//! List of all children of this node
|
//! List of all children of this node
|
||||||
core::list<ISceneNode*> Children;
|
std::list<ISceneNode*> Children;
|
||||||
|
|
||||||
//! Pointer to the scene manager
|
//! Pointer to the scene manager
|
||||||
ISceneManager* SceneManager;
|
ISceneManager* SceneManager;
|
||||||
|
@ -100,7 +100,7 @@ namespace scene
|
|||||||
private:
|
private:
|
||||||
//! Internal members used by CSkinnedMesh
|
//! Internal members used by CSkinnedMesh
|
||||||
friend class CSkinnedMesh;
|
friend class CSkinnedMesh;
|
||||||
bool *Moved;
|
char *Moved;
|
||||||
core::vector3df StaticPos;
|
core::vector3df StaticPos;
|
||||||
core::vector3df StaticNormal;
|
core::vector3df StaticNormal;
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
|
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
|
||||||
|
|
||||||
//! Identifies the IrrlichtMt fork customized for the Minetest engine
|
//! Identifies the IrrlichtMt fork customized for the Minetest engine
|
||||||
#define IRRLICHT_VERSION_MT_REVISION 5
|
#define IRRLICHT_VERSION_MT_REVISION 6
|
||||||
#define IRRLICHT_VERSION_MT "mt5"
|
#define IRRLICHT_VERSION_MT "mt6"
|
||||||
|
|
||||||
//! Irrlicht SDK Version
|
//! Irrlicht SDK Version
|
||||||
#define IRRLICHT_VERSION_MAJOR 1
|
#define IRRLICHT_VERSION_MAJOR 1
|
||||||
|
@ -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
|
|
||||||
|
|
@ -5,9 +5,11 @@
|
|||||||
#ifndef __IRR_ARRAY_H_INCLUDED__
|
#ifndef __IRR_ARRAY_H_INCLUDED__
|
||||||
#define __IRR_ARRAY_H_INCLUDED__
|
#define __IRR_ARRAY_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "irrTypes.h"
|
#include "irrTypes.h"
|
||||||
#include "heapsort.h"
|
|
||||||
#include "irrAllocator.h"
|
|
||||||
#include "irrMath.h"
|
#include "irrMath.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -18,44 +20,27 @@ namespace core
|
|||||||
//! Self reallocating template array (like stl vector) with additional features.
|
//! Self reallocating template array (like stl vector) with additional features.
|
||||||
/** Some features are: Heap sorting, binary search methods, easier debugging.
|
/** Some features are: Heap sorting, binary search methods, easier debugging.
|
||||||
*/
|
*/
|
||||||
template <class T, typename TAlloc = irrAllocator<T> >
|
template <class T>
|
||||||
class array
|
class array
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
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.
|
//! Default constructor for empty array.
|
||||||
array() : data(0), allocated(0), used(0),
|
array() : m_data(), is_sorted(true)
|
||||||
strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true)
|
{ }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Constructs an array and allocates an initial chunk of memory.
|
//! Constructs an array and allocates an initial chunk of memory.
|
||||||
/** \param start_count Amount of elements to pre-allocate. */
|
/** \param start_count Amount of elements to pre-allocate. */
|
||||||
explicit array(u32 start_count) : data(0), allocated(0), used(0),
|
explicit array(u32 start_count) : m_data(), is_sorted(true)
|
||||||
strategy(ALLOC_STRATEGY_DOUBLE),
|
|
||||||
free_when_destroyed(true), is_sorted(true)
|
|
||||||
{
|
{
|
||||||
reallocate(start_count);
|
m_data.reserve(start_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Copy constructor
|
//! Copy constructor
|
||||||
array(const array<T, TAlloc>& other) : data(0)
|
array(const array<T>& other) : m_data(other.m_data), is_sorted(other.is_sorted)
|
||||||
{
|
{ }
|
||||||
*this = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Destructor.
|
|
||||||
/** Frees allocated memory, if set_free_when_destroyed was not set to
|
|
||||||
false by the user before. */
|
|
||||||
~array()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Reallocates the array, make it bigger or smaller.
|
//! Reallocates the array, make it bigger or smaller.
|
||||||
/** \param new_size New size of array.
|
/** \param new_size New size of array.
|
||||||
@ -65,52 +50,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
void reallocate(u32 new_size, bool canShrink=true)
|
void reallocate(u32 new_size, bool canShrink=true)
|
||||||
{
|
{
|
||||||
if (allocated==new_size)
|
size_t allocated = m_data.capacity();
|
||||||
return;
|
if (new_size < allocated) {
|
||||||
if (!canShrink && (new_size < allocated))
|
if (canShrink)
|
||||||
return;
|
m_data.resize(new_size);
|
||||||
|
} else {
|
||||||
T* old_data = data;
|
m_data.reserve(new_size);
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
//! Adds an element at back of array.
|
||||||
/** If the array is too small to add this new element it is made bigger.
|
/** 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. */
|
\param element: Element to add at the back of the array. */
|
||||||
void push_back(const T& element)
|
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. */
|
\param element Element to add at the back of the array. */
|
||||||
void push_front(const T& element)
|
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. */
|
\param index: Where position to insert the new element. */
|
||||||
void insert(const T& element, u32 index=0)
|
void insert(const T& element, u32 index=0)
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index>used) // access violation
|
_IRR_DEBUG_BREAK_IF(index > m_data.size()) // access violation
|
||||||
|
auto pos = std::next(m_data.begin(), index);
|
||||||
if (used + 1 > allocated)
|
m_data.insert(pos, element);
|
||||||
{
|
|
||||||
// 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
|
|
||||||
is_sorted = false;
|
is_sorted = false;
|
||||||
++used;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Clears the array and deletes all allocated memory.
|
//! Clears the array and deletes all allocated memory.
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (free_when_destroyed)
|
// vector::clear() reduces the size to 0, but doesn't free memory.
|
||||||
{
|
// This swap is guaranteed to delete the allocated memory.
|
||||||
for (u32 i=0; i<used; ++i)
|
std::vector<T>().swap(m_data);
|
||||||
allocator.destruct(&data[i]);
|
|
||||||
|
|
||||||
allocator.deallocate(data); // delete [] data;
|
|
||||||
}
|
|
||||||
data = 0;
|
|
||||||
used = 0;
|
|
||||||
allocated = 0;
|
|
||||||
is_sorted = true;
|
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
|
//! Set (copy) data from given memory block
|
||||||
/** \param newData data to set, must have newSize elements
|
/** \param newData data to set, must have newSize elements
|
||||||
\param newSize Amount of elements in newData
|
\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)
|
void set_data(const T* newData, u32 newSize, bool newDataIsSorted=false, bool canShrink=false)
|
||||||
{
|
{
|
||||||
reallocate(newSize, canShrink);
|
m_data.resize(newSize);
|
||||||
set_used(newSize);
|
if (canShrink) {
|
||||||
for ( u32 i=0; i<newSize; ++i)
|
m_data.shrink_to_fit();
|
||||||
{
|
|
||||||
data[i] = newData[i];
|
|
||||||
}
|
}
|
||||||
|
std::copy(newData, newData + newSize, m_data.begin());
|
||||||
is_sorted = newDataIsSorted;
|
is_sorted = newDataIsSorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,85 +137,51 @@ public:
|
|||||||
\param size Amount of elements in otherData */
|
\param size Amount of elements in otherData */
|
||||||
bool equals(const T* otherData, u32 size) const
|
bool equals(const T* otherData, u32 size) const
|
||||||
{
|
{
|
||||||
if (used != size)
|
if (m_data.size() != size)
|
||||||
return false;
|
return false;
|
||||||
|
return std::equal(m_data.begin(), m_data.end(), otherData);
|
||||||
for (u32 i=0; i<size; ++i)
|
|
||||||
if (data[i] != otherData[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! 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.
|
//! Sets the size of the array and allocates new elements if necessary.
|
||||||
/** Please note: This is only secure when using it with simple types,
|
/** \param usedNow Amount of elements now used. */
|
||||||
because no default constructor will be called for the added elements.
|
|
||||||
\param usedNow Amount of elements now used. */
|
|
||||||
void set_used(u32 usedNow)
|
void set_used(u32 usedNow)
|
||||||
{
|
{
|
||||||
if (allocated < usedNow)
|
m_data.resize(usedNow);
|
||||||
reallocate(usedNow);
|
|
||||||
|
|
||||||
used = usedNow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Assignment operator
|
//! Assignment operator
|
||||||
const array<T, TAlloc>& operator=(const array<T, TAlloc>& other)
|
const array<T>& operator=(const array<T>& other)
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return *this;
|
return *this;
|
||||||
strategy = other.strategy;
|
m_data = other.m_data;
|
||||||
|
|
||||||
// (TODO: we could probably avoid re-allocations of data when (allocated < other.allocated)
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
clear();
|
|
||||||
|
|
||||||
used = other.used;
|
|
||||||
free_when_destroyed = true;
|
|
||||||
is_sorted = other.is_sorted;
|
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;
|
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
|
//! Equality operator
|
||||||
bool operator == (const array<T, TAlloc>& other) const
|
bool operator == (const array<T>& other) const
|
||||||
{
|
{
|
||||||
return equals(other.const_pointer(), other.size());
|
return equals(other.const_pointer(), other.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Inequality operator
|
//! Inequality operator
|
||||||
bool operator != (const array<T, TAlloc>& other) const
|
bool operator != (const array<T>& other) const
|
||||||
{
|
{
|
||||||
return !(*this==other);
|
return !(*this==other);
|
||||||
}
|
}
|
||||||
@ -342,36 +190,36 @@ public:
|
|||||||
//! Direct access operator
|
//! Direct access operator
|
||||||
T& operator [](u32 index)
|
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
|
//! Direct const access operator
|
||||||
const T& operator [](u32 index) const
|
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.
|
//! Gets last element.
|
||||||
T& getLast()
|
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
|
//! Gets last element
|
||||||
const T& getLast() const
|
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. */
|
/** \return Pointer to the array. */
|
||||||
T* pointer()
|
T* pointer()
|
||||||
{
|
{
|
||||||
return data;
|
return &m_data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +235,7 @@ public:
|
|||||||
/** \return Pointer to the array. */
|
/** \return Pointer to the array. */
|
||||||
const T* const_pointer() const
|
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. */
|
/** \return Size of elements in the array which are actually occupied. */
|
||||||
u32 size() const
|
u32 size() const
|
||||||
{
|
{
|
||||||
return used;
|
return m_data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -404,7 +252,7 @@ public:
|
|||||||
allocated would be allocated_size() * sizeof(ElementTypeUsed); */
|
allocated would be allocated_size() * sizeof(ElementTypeUsed); */
|
||||||
u32 allocated_size() const
|
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. */
|
/** \return True if the array is empty false if not. */
|
||||||
bool empty() const
|
bool empty() const
|
||||||
{
|
{
|
||||||
return used == 0;
|
return m_data.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -421,10 +269,11 @@ public:
|
|||||||
O(n*log n) in worst case. */
|
O(n*log n) in worst case. */
|
||||||
void sort()
|
void sort()
|
||||||
{
|
{
|
||||||
if (!is_sorted && used>1)
|
if (!is_sorted) {
|
||||||
heapsort(data, used);
|
std::sort(m_data.begin(), m_data.end());
|
||||||
is_sorted = true;
|
is_sorted = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Performs a binary search for an element, returns -1 if not found.
|
//! Performs a binary search for an element, returns -1 if not found.
|
||||||
@ -437,10 +286,9 @@ public:
|
|||||||
s32 binary_search(const T& element)
|
s32 binary_search(const T& element)
|
||||||
{
|
{
|
||||||
sort();
|
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.
|
//! 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
|
/** 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!
|
not sorted then linear_search will be used instead. Potentially very slow!
|
||||||
@ -450,12 +298,11 @@ public:
|
|||||||
s32 binary_search(const T& element) const
|
s32 binary_search(const T& element) const
|
||||||
{
|
{
|
||||||
if (is_sorted)
|
if (is_sorted)
|
||||||
return binary_search(element, 0, used-1);
|
return binary_search(element, 0, (s32)m_data.size() - 1);
|
||||||
else
|
else
|
||||||
return linear_search(element);
|
return linear_search(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Performs a binary search for an element, returns -1 if not found.
|
//! Performs a binary search for an element, returns -1 if not found.
|
||||||
/** \param element: Element to search for.
|
/** \param element: Element to search for.
|
||||||
\param left First left index
|
\param left First left index
|
||||||
@ -464,31 +311,15 @@ public:
|
|||||||
is returned. */
|
is returned. */
|
||||||
s32 binary_search(const T& element, s32 left, s32 right) const
|
s32 binary_search(const T& element, s32 left, s32 right) const
|
||||||
{
|
{
|
||||||
if (!used)
|
if (left > right)
|
||||||
return -1;
|
return -1;
|
||||||
|
auto lpos = std::next(m_data.begin(), left);
|
||||||
s32 m;
|
auto rpos = std::next(m_data.begin(), right);
|
||||||
|
auto it = std::lower_bound(lpos, rpos, element);
|
||||||
do
|
// *it = first element in [first, last) that is >= element, or last if not found.
|
||||||
{
|
if (*it < element || element < *it)
|
||||||
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;
|
return -1;
|
||||||
|
return it - m_data.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -503,25 +334,11 @@ public:
|
|||||||
s32 binary_search_multi(const T& element, s32 &last)
|
s32 binary_search_multi(const T& element, s32 &last)
|
||||||
{
|
{
|
||||||
sort();
|
sort();
|
||||||
s32 index = binary_search(element, 0, used-1);
|
auto iters = std::equal_range(m_data.begin(), m_data.end(), element);
|
||||||
if ( index < 0 )
|
if (iters.first == iters.second)
|
||||||
return index;
|
return -1;
|
||||||
|
last = (iters.second - m_data.begin()) - 1;
|
||||||
// The search can be somewhere in the middle of the set
|
return iters.first - m_data.begin();
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -533,11 +350,10 @@ public:
|
|||||||
is returned. */
|
is returned. */
|
||||||
s32 linear_search(const T& element) const
|
s32 linear_search(const T& element) const
|
||||||
{
|
{
|
||||||
for (u32 i=0; i<used; ++i)
|
auto it = std::find(m_data.begin(), m_data.end(), element);
|
||||||
if (element == data[i])
|
if (it == m_data.end())
|
||||||
return (s32)i;
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
return it - m_data.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -549,11 +365,11 @@ public:
|
|||||||
is returned. */
|
is returned. */
|
||||||
s32 linear_reverse_search(const T& element) const
|
s32 linear_reverse_search(const T& element) const
|
||||||
{
|
{
|
||||||
for (s32 i=used-1; i>=0; --i)
|
auto it = std::find(m_data.rbegin(), m_data.rend(), element);
|
||||||
if (data[i] == element)
|
if (it == m_data.rend())
|
||||||
return i;
|
|
||||||
|
|
||||||
return -1;
|
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. */
|
\param index: Index of element to be erased. */
|
||||||
void erase(u32 index)
|
void erase(u32 index)
|
||||||
{
|
{
|
||||||
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
|
_IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation
|
||||||
|
auto it = std::next(m_data.begin(), index);
|
||||||
for (u32 i=index+1; i<used; ++i)
|
m_data.erase(it);
|
||||||
{
|
|
||||||
allocator.destruct(&data[i-1]);
|
|
||||||
allocator.construct(&data[i-1], data[i]); // data[i-1] = data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
allocator.destruct(&data[used-1]);
|
|
||||||
|
|
||||||
--used;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -584,30 +392,14 @@ public:
|
|||||||
\param count: Amount of elements to be erased. */
|
\param count: Amount of elements to be erased. */
|
||||||
void erase(u32 index, s32 count)
|
void erase(u32 index, s32 count)
|
||||||
{
|
{
|
||||||
if (index>=used || count<1)
|
if (index >= m_data.size() || count < 1)
|
||||||
return;
|
return;
|
||||||
if (index+count>used)
|
count = std::min(count, (s32)m_data.size() - (s32)index);
|
||||||
count = used-index;
|
auto first = std::next(m_data.begin(), index);
|
||||||
|
auto last = std::next(first, count);
|
||||||
u32 i;
|
m_data.erase(first, last);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Sets if the array is sorted
|
//! Sets if the array is sorted
|
||||||
void set_sorted(bool _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
|
/** Afterward this object will contain the content of the other object and the other
|
||||||
object will contain the content of this object.
|
object will contain the content of this object.
|
||||||
\param other Swap content with 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);
|
m_data.swap(other.m_data);
|
||||||
core::swap(allocated, other.allocated);
|
std::swap(is_sorted, other.is_sorted);
|
||||||
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
|
//! Pull the contents of this array as a vector.
|
||||||
strategy = other.strategy;
|
// The array is left empty.
|
||||||
other.strategy = helper_strategy;
|
std::vector<T> steal()
|
||||||
bool helper_free_when_destroyed(free_when_destroyed);
|
{
|
||||||
free_when_destroyed = other.free_when_destroyed;
|
std::vector<T> ret = std::move(m_data);
|
||||||
other.free_when_destroyed = helper_free_when_destroyed;
|
m_data.clear();
|
||||||
bool helper_is_sorted(is_sorted);
|
is_sorted = true;
|
||||||
is_sorted = other.is_sorted;
|
return ret;
|
||||||
other.is_sorted = helper_is_sorted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef TAlloc allocator_type;
|
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef u32 size_type;
|
typedef u32 size_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* data;
|
std::vector<T> m_data;
|
||||||
u32 allocated;
|
bool is_sorted;
|
||||||
u32 used;
|
|
||||||
TAlloc allocator;
|
|
||||||
eAllocStrategy strategy:4;
|
|
||||||
bool free_when_destroyed:1;
|
|
||||||
bool is_sorted:1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace core
|
} // end namespace core
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
1082
include/irrMap.h
1082
include/irrMap.h
File diff suppressed because it is too large
Load Diff
@ -50,7 +50,6 @@
|
|||||||
#include "EMessageBoxFlags.h"
|
#include "EMessageBoxFlags.h"
|
||||||
#include "ESceneNodeTypes.h"
|
#include "ESceneNodeTypes.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "heapsort.h"
|
|
||||||
#include "IAnimatedMesh.h"
|
#include "IAnimatedMesh.h"
|
||||||
#include "IAnimatedMeshSceneNode.h"
|
#include "IAnimatedMeshSceneNode.h"
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
@ -112,8 +111,6 @@
|
|||||||
#include "IRandomizer.h"
|
#include "IRandomizer.h"
|
||||||
#include "IRenderTarget.h"
|
#include "IRenderTarget.h"
|
||||||
#include "IrrlichtDevice.h"
|
#include "IrrlichtDevice.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "irrMap.h"
|
|
||||||
#include "irrMath.h"
|
#include "irrMath.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "irrTypes.h"
|
#include "irrTypes.h"
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "irrMath.h"
|
#include "irrMath.h"
|
||||||
#include "dimension2d.h"
|
#include "dimension2d.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace core
|
namespace core
|
||||||
@ -414,5 +416,21 @@ public:
|
|||||||
} // end namespace core
|
} // end namespace core
|
||||||
} // end namespace irr
|
} // 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
|
#endif
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "irrMath.h"
|
#include "irrMath.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace core
|
namespace core
|
||||||
@ -466,5 +468,22 @@ namespace core
|
|||||||
} // end namespace core
|
} // end namespace core
|
||||||
} // end namespace irr
|
} // 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
|
#endif
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "IMeshBuffer.h"
|
#include "IMeshBuffer.h"
|
||||||
#include "IWriteFile.h"
|
#include "IWriteFile.h"
|
||||||
#include "ITexture.h"
|
#include "ITexture.h"
|
||||||
#include "irrMap.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -60,7 +59,7 @@ bool CB3DMeshWriter::writeMesh(io::IWriteFile* file, IMesh* const mesh, s32 flag
|
|||||||
|
|
||||||
const u32 numMeshBuffers = mesh->getMeshBufferCount();
|
const u32 numMeshBuffers = mesh->getMeshBufferCount();
|
||||||
array<SB3dTexture> texs;
|
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;
|
u32 texsizes = 0;
|
||||||
for (u32 i = 0; i < numMeshBuffers; i++)
|
for (u32 i = 0; i < numMeshBuffers; i++)
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@ void CBoneSceneNode::OnAnimate(u32 timeMs)
|
|||||||
//updateAbsolutePosition();
|
//updateAbsolutePosition();
|
||||||
|
|
||||||
// perform the post render process on all children
|
// perform the post render process on all children
|
||||||
ISceneNodeList::Iterator it = Children.begin();
|
ISceneNodeList::iterator it = Children.begin();
|
||||||
for (; it != Children.end(); ++it)
|
for (; it != Children.end(); ++it)
|
||||||
(*it)->OnAnimate(timeMs);
|
(*it)->OnAnimate(timeMs);
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node
|
|||||||
{
|
{
|
||||||
Node->updateAbsolutePosition();
|
Node->updateAbsolutePosition();
|
||||||
|
|
||||||
ISceneNodeList::ConstIterator it = Node->getChildren().begin();
|
ISceneNodeList::const_iterator it = Node->getChildren().begin();
|
||||||
for (; it != Node->getChildren().end(); ++it)
|
for (; it != Node->getChildren().end(); ++it)
|
||||||
{
|
{
|
||||||
helper_updateAbsolutePositionOfAllChildren( (*it) );
|
helper_updateAbsolutePositionOfAllChildren( (*it) );
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "CMemoryFile.h"
|
#include "CMemoryFile.h"
|
||||||
#include "CLimitReadFile.h"
|
#include "CLimitReadFile.h"
|
||||||
#include "CWriteFile.h"
|
#include "CWriteFile.h"
|
||||||
#include "irrList.h"
|
#include <list>
|
||||||
|
|
||||||
#if defined (__STRICT_ANSI__)
|
#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.
|
#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;
|
io::path path1, file, ext;
|
||||||
core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext);
|
core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext);
|
||||||
io::path path2(getAbsolutePath(directory));
|
io::path path2(getAbsolutePath(directory));
|
||||||
core::list<io::path> list1, list2;
|
std::list<io::path> list1, list2;
|
||||||
path1.split(list1, _IRR_TEXT("/\\"), 2);
|
path1.split(list1, _IRR_TEXT("/\\"), 2);
|
||||||
path2.split(list2, _IRR_TEXT("/\\"), 2);
|
path2.split(list2, _IRR_TEXT("/\\"), 2);
|
||||||
u32 i=0;
|
std::list<io::path>::const_iterator it1,it2;
|
||||||
core::list<io::path>::ConstIterator it1,it2;
|
|
||||||
it1=list1.begin();
|
it1=list1.begin();
|
||||||
it2=list2.begin();
|
it2=list2.begin();
|
||||||
|
|
||||||
@ -742,19 +741,19 @@ path CFileSystem::getRelativeFilename(const path& filename, const path& director
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
for (; i<list1.size() && i<list2.size()
|
for (; it1 != list1.end() && it2 != list2.end()
|
||||||
#if defined (_IRR_WINDOWS_API_)
|
#if defined (_IRR_WINDOWS_API_)
|
||||||
&& (io::path(*it1).make_lower()==io::path(*it2).make_lower())
|
&& (io::path(*it1).make_lower()==io::path(*it2).make_lower())
|
||||||
#else
|
#else
|
||||||
&& (*it1==*it2)
|
&& (*it1==*it2)
|
||||||
#endif
|
#endif
|
||||||
; ++i)
|
;)
|
||||||
{
|
{
|
||||||
++it1;
|
++it1;
|
||||||
++it2;
|
++it2;
|
||||||
}
|
}
|
||||||
path1=_IRR_TEXT("");
|
path1=_IRR_TEXT("");
|
||||||
for (; i<list2.size(); ++i)
|
for (; it2 != list2.end(); ++it2)
|
||||||
path1 += _IRR_TEXT("../");
|
path1 += _IRR_TEXT("../");
|
||||||
while (it1 != list1.end())
|
while (it1 != list1.end())
|
||||||
{
|
{
|
||||||
|
@ -387,11 +387,7 @@ void CGUIEnvironment::clear()
|
|||||||
HoveredNoSubelement = 0;
|
HoveredNoSubelement = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the root's children in case the root changes in future
|
getRootGUIElement()->removeAllChildren();
|
||||||
const core::list<IGUIElement*>& children = getRootGUIElement()->getChildren();
|
|
||||||
|
|
||||||
while (!children.empty())
|
|
||||||
(*children.getLast())->remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
|
|||||||
}
|
}
|
||||||
rectangle.LowerRightCorner.Y = val;
|
rectangle.LowerRightCorner.Y = val;
|
||||||
|
|
||||||
CharacterMap.insert(ch,Areas.size());
|
CharacterMap.emplace(ch, Areas.size());
|
||||||
|
|
||||||
// make frame
|
// make frame
|
||||||
f.rectNumber = SpriteBank->getPositions().size();
|
f.rectNumber = SpriteBank->getPositions().size();
|
||||||
@ -374,7 +374,7 @@ void CGUIFont::readPositions(video::IImage* image, s32& lowerRightPositions)
|
|||||||
Areas.push_back(a);
|
Areas.push_back(a);
|
||||||
// map letter to character
|
// map letter to character
|
||||||
wchar_t ch = (wchar_t)(lowerRightPositions + 32);
|
wchar_t ch = (wchar_t)(lowerRightPositions + 32);
|
||||||
CharacterMap.set(ch, lowerRightPositions);
|
CharacterMap[ch] = lowerRightPositions;
|
||||||
|
|
||||||
++lowerRightPositions;
|
++lowerRightPositions;
|
||||||
}
|
}
|
||||||
@ -435,9 +435,9 @@ u32 CGUIFont::getSpriteNoFromChar(const wchar_t *c) const
|
|||||||
|
|
||||||
s32 CGUIFont::getAreaFromCharacter(const wchar_t c) const
|
s32 CGUIFont::getAreaFromCharacter(const wchar_t c) const
|
||||||
{
|
{
|
||||||
core::map<wchar_t, s32>::Node* n = CharacterMap.find(c);
|
auto n = CharacterMap.find(c);
|
||||||
if (n)
|
if (n != CharacterMap.end())
|
||||||
return n->getValue();
|
return n->second;
|
||||||
else
|
else
|
||||||
return WrongCharacter;
|
return WrongCharacter;
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
#include "IGUIFontBitmap.h"
|
#include "IGUIFontBitmap.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "irrMap.h"
|
|
||||||
#include "IReadFile.h"
|
#include "IReadFile.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ private:
|
|||||||
void popTextureCreationFlags(const bool(&flags)[3]);
|
void popTextureCreationFlags(const bool(&flags)[3]);
|
||||||
|
|
||||||
core::array<SFontArea> Areas;
|
core::array<SFontArea> Areas;
|
||||||
core::map<wchar_t, s32> CharacterMap;
|
std::map<wchar_t, s32> CharacterMap;
|
||||||
video::IVideoDriver* Driver;
|
video::IVideoDriver* Driver;
|
||||||
IGUISpriteBank* SpriteBank;
|
IGUISpriteBank* SpriteBank;
|
||||||
IGUIEnvironment* Environment;
|
IGUIEnvironment* Environment;
|
||||||
|
@ -57,17 +57,12 @@ bool CGUIModalScreen::isVisible() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// any child visible?
|
// any child visible?
|
||||||
bool visible = false;
|
for (const auto& child : Children)
|
||||||
core::list<IGUIElement*>::ConstIterator it = Children.begin();
|
|
||||||
for (; it != Children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
if ( (*it)->isVisible() )
|
if ( child->isVisible() )
|
||||||
{
|
return true;
|
||||||
visible = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGUIModalScreen::isPointInside(const core::position2d<s32>& point) const
|
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 ( !canTakeFocus(event.GUIEvent.Caller))
|
||||||
{
|
{
|
||||||
if ( !Children.empty() )
|
if ( !Children.empty() )
|
||||||
Environment->setFocus(*(Children.begin()));
|
Environment->setFocus(Children.front());
|
||||||
else
|
else
|
||||||
Environment->setFocus(this);
|
Environment->setFocus(this);
|
||||||
}
|
}
|
||||||
@ -110,7 +105,7 @@ bool CGUIModalScreen::OnEvent(const SEvent& event)
|
|||||||
if ( isMyChild(event.GUIEvent.Caller) )
|
if ( isMyChild(event.GUIEvent.Caller) )
|
||||||
{
|
{
|
||||||
if ( !Children.empty() )
|
if ( !Children.empty() )
|
||||||
Environment->setFocus(*(Children.begin()));
|
Environment->setFocus(Children.front());
|
||||||
else
|
else
|
||||||
Environment->setFocus(this);
|
Environment->setFocus(this);
|
||||||
}
|
}
|
||||||
@ -171,15 +166,14 @@ void CGUIModalScreen::draw()
|
|||||||
u32 now = os::Timer::getTime();
|
u32 now = os::Timer::getTime();
|
||||||
if (BlinkMode && now - MouseDownTime < 300 && (now / 70)%2)
|
if (BlinkMode && now - MouseDownTime < 300 && (now / 70)%2)
|
||||||
{
|
{
|
||||||
core::list<IGUIElement*>::Iterator it = Children.begin();
|
|
||||||
core::rect<s32> r;
|
core::rect<s32> r;
|
||||||
video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT);
|
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.X += 1;
|
||||||
r.LowerRightCorner.Y += 1;
|
r.LowerRightCorner.Y += 1;
|
||||||
r.UpperLeftCorner.X -= 1;
|
r.UpperLeftCorner.X -= 1;
|
||||||
|
@ -34,11 +34,8 @@ CGUIToolBar::CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32
|
|||||||
parentwidth = Parent->getAbsolutePosition().getWidth();
|
parentwidth = Parent->getAbsolutePosition().getWidth();
|
||||||
s32 parentheight = Parent->getAbsolutePosition().getHeight();
|
s32 parentheight = Parent->getAbsolutePosition().getHeight();
|
||||||
|
|
||||||
const core::list<IGUIElement*>& children = parent->getChildren();
|
for (const auto& e : parent->getChildren())
|
||||||
core::list<IGUIElement*>::ConstIterator it = children.begin();
|
|
||||||
for (; it != children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
const IGUIElement* e = *it;
|
|
||||||
if ( e->hasType(EGUIET_CONTEXT_MENU)
|
if ( e->hasType(EGUIET_CONTEXT_MENU)
|
||||||
|| e->hasType(EGUIET_MENU)
|
|| e->hasType(EGUIET_MENU)
|
||||||
|| e->hasType(EGUIET_TOOL_BAR) )
|
|| e->hasType(EGUIET_TOOL_BAR) )
|
||||||
|
@ -66,11 +66,10 @@ void CGUITreeViewNode::setIcon( const wchar_t* icon )
|
|||||||
|
|
||||||
void CGUITreeViewNode::clearChildren()
|
void CGUITreeViewNode::clearChildren()
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator it;
|
for (auto child : Children)
|
||||||
|
|
||||||
for( it = Children.begin(); it != Children.end(); it++ )
|
|
||||||
{
|
{
|
||||||
( *it )->drop();
|
child->Parent = nullptr;
|
||||||
|
child->drop();
|
||||||
}
|
}
|
||||||
Children.clear();
|
Children.clear();
|
||||||
}
|
}
|
||||||
@ -83,9 +82,8 @@ IGUITreeViewNode* CGUITreeViewNode::addChildBack(
|
|||||||
void* data /*= 0*/,
|
void* data /*= 0*/,
|
||||||
IReferenceCounted* data2 /*= 0*/ )
|
IReferenceCounted* data2 /*= 0*/ )
|
||||||
{
|
{
|
||||||
CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
|
auto newChild = new CGUITreeViewNode( Owner, this );
|
||||||
|
newChild->ParentPos = Children.insert(Children.end(), newChild);
|
||||||
Children.push_back( newChild );
|
|
||||||
newChild->Text = text;
|
newChild->Text = text;
|
||||||
newChild->Icon = icon;
|
newChild->Icon = icon;
|
||||||
newChild->ImageIndex = imageIndex;
|
newChild->ImageIndex = imageIndex;
|
||||||
@ -107,9 +105,8 @@ IGUITreeViewNode* CGUITreeViewNode::addChildFront(
|
|||||||
void* data /*= 0*/,
|
void* data /*= 0*/,
|
||||||
IReferenceCounted* data2 /*= 0*/ )
|
IReferenceCounted* data2 /*= 0*/ )
|
||||||
{
|
{
|
||||||
CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
|
auto newChild = new CGUITreeViewNode( Owner, this );
|
||||||
|
newChild->ParentPos = Children.insert(Children.begin(), newChild);
|
||||||
Children.push_front( newChild );
|
|
||||||
newChild->Text = text;
|
newChild->Text = text;
|
||||||
newChild->Icon = icon;
|
newChild->Icon = icon;
|
||||||
newChild->ImageIndex = imageIndex;
|
newChild->ImageIndex = imageIndex;
|
||||||
@ -124,7 +121,7 @@ IGUITreeViewNode* CGUITreeViewNode::addChildFront(
|
|||||||
}
|
}
|
||||||
|
|
||||||
IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
|
IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
|
||||||
IGUITreeViewNode* other,
|
IGUITreeViewNode* iother,
|
||||||
const wchar_t* text,
|
const wchar_t* text,
|
||||||
const wchar_t* icon /*= 0*/,
|
const wchar_t* icon /*= 0*/,
|
||||||
s32 imageIndex /*= -1*/,
|
s32 imageIndex /*= -1*/,
|
||||||
@ -132,14 +129,14 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
|
|||||||
void* data /*= 0*/,
|
void* data /*= 0*/,
|
||||||
IReferenceCounted* data2/* = 0*/ )
|
IReferenceCounted* data2/* = 0*/ )
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itOther;
|
// This cast is needed to access the ParentPos member of `other`.
|
||||||
CGUITreeViewNode* newChild = 0;
|
// The abstraction was already broken, because Children is a list of
|
||||||
|
// CGUITreeViewNode, not IGUITreeViewNode. The existing code was
|
||||||
for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
|
// implicitly casting through pointer comparison.
|
||||||
{
|
auto other = static_cast<CGUITreeViewNode*>(iother);
|
||||||
if( other == *itOther )
|
assert(other->Parent == this);
|
||||||
{
|
auto newChild = new CGUITreeViewNode( Owner, this );
|
||||||
newChild = new CGUITreeViewNode( Owner, this );
|
newChild->ParentPos = Children.insert(std::next(other->ParentPos), newChild);
|
||||||
newChild->Text = text;
|
newChild->Text = text;
|
||||||
newChild->Icon = icon;
|
newChild->Icon = icon;
|
||||||
newChild->ImageIndex = imageIndex;
|
newChild->ImageIndex = imageIndex;
|
||||||
@ -147,18 +144,12 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
|
|||||||
newChild->Data = data;
|
newChild->Data = data;
|
||||||
newChild->Data2 = data2;
|
newChild->Data2 = data2;
|
||||||
if( data2 )
|
if( data2 )
|
||||||
{
|
|
||||||
data2->grab();
|
data2->grab();
|
||||||
}
|
|
||||||
Children.insert_after( itOther, newChild );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newChild;
|
return newChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
|
IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
|
||||||
IGUITreeViewNode* other,
|
IGUITreeViewNode* iother,
|
||||||
const wchar_t* text,
|
const wchar_t* text,
|
||||||
const wchar_t* icon /*= 0*/,
|
const wchar_t* icon /*= 0*/,
|
||||||
s32 imageIndex /*= -1*/,
|
s32 imageIndex /*= -1*/,
|
||||||
@ -166,14 +157,10 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
|
|||||||
void* data /*= 0*/,
|
void* data /*= 0*/,
|
||||||
IReferenceCounted* data2/* = 0*/ )
|
IReferenceCounted* data2/* = 0*/ )
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itOther;
|
auto other = static_cast<CGUITreeViewNode*>(iother);
|
||||||
CGUITreeViewNode* newChild = 0;
|
assert(other->Parent == this);
|
||||||
|
auto newChild = new CGUITreeViewNode( Owner, this );
|
||||||
for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
|
newChild->ParentPos = Children.insert(other->ParentPos, newChild);
|
||||||
{
|
|
||||||
if( other == *itOther )
|
|
||||||
{
|
|
||||||
newChild = new CGUITreeViewNode( Owner, this );
|
|
||||||
newChild->Text = text;
|
newChild->Text = text;
|
||||||
newChild->Icon = icon;
|
newChild->Icon = icon;
|
||||||
newChild->ImageIndex = imageIndex;
|
newChild->ImageIndex = imageIndex;
|
||||||
@ -181,13 +168,7 @@ IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
|
|||||||
newChild->Data = data;
|
newChild->Data = data;
|
||||||
newChild->Data2 = data2;
|
newChild->Data2 = data2;
|
||||||
if( data2 )
|
if( data2 )
|
||||||
{
|
|
||||||
data2->grab();
|
data2->grab();
|
||||||
}
|
|
||||||
Children.insert_before( itOther, newChild );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newChild;
|
return newChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +180,7 @@ IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return *( Children.begin() );
|
return Children.front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,54 +192,25 @@ IGUITreeViewNode* CGUITreeViewNode::getLastChild() const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return *( Children.getLast() );
|
return Children.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const
|
IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itThis;
|
if (!Parent || ParentPos == Parent->Children.begin())
|
||||||
core::list<CGUITreeViewNode*>::Iterator itOther;
|
return nullptr;
|
||||||
CGUITreeViewNode* other = 0;
|
return *std::prev(ParentPos);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
|
IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itThis;
|
if (!Parent)
|
||||||
CGUITreeViewNode* other = 0;
|
return nullptr;
|
||||||
|
auto nextIt = std::next(ParentPos);
|
||||||
if( Parent )
|
if (nextIt == Parent->Children.end())
|
||||||
{
|
return nullptr;
|
||||||
for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
|
return *nextIt;
|
||||||
{
|
|
||||||
if( this == *itThis )
|
|
||||||
{
|
|
||||||
if( itThis != Parent->Children.getLast() )
|
|
||||||
{
|
|
||||||
other = *( ++itThis );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return other;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
|
IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
|
||||||
@ -286,73 +238,40 @@ IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child )
|
bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* ichild )
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itChild;
|
auto child = static_cast<CGUITreeViewNode*>(ichild);
|
||||||
bool deleted = false;
|
assert(child->Parent == this);
|
||||||
|
Children.erase(child->ParentPos);
|
||||||
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
|
child->Parent = nullptr;
|
||||||
{
|
|
||||||
if( child == *itChild )
|
|
||||||
{
|
|
||||||
child->drop();
|
child->drop();
|
||||||
Children.erase( itChild );
|
return true;
|
||||||
deleted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return deleted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child )
|
bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* ichild )
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itChild;
|
auto child = static_cast<CGUITreeViewNode*>(ichild);
|
||||||
core::list<CGUITreeViewNode*>::Iterator itOther;
|
assert(child->Parent == this);
|
||||||
CGUITreeViewNode* nodeTmp;
|
if (child->ParentPos == Children.begin())
|
||||||
bool moved = false;
|
return false;
|
||||||
|
auto curPos = child->ParentPos;
|
||||||
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
|
auto prevPos = std::prev(child->ParentPos);
|
||||||
{
|
std::swap(*curPos, *prevPos);
|
||||||
if( child == *itChild )
|
std::swap((*curPos)->ParentPos, (*prevPos)->ParentPos);
|
||||||
{
|
return true;
|
||||||
if( itChild != Children.begin() )
|
|
||||||
{
|
|
||||||
nodeTmp = *itChild;
|
|
||||||
*itChild = *itOther;
|
|
||||||
*itOther = nodeTmp;
|
|
||||||
moved = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
itOther = itChild;
|
|
||||||
}
|
|
||||||
return moved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child )
|
bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* ichild )
|
||||||
{
|
{
|
||||||
core::list<CGUITreeViewNode*>::Iterator itChild;
|
auto child = static_cast<CGUITreeViewNode*>(ichild);
|
||||||
core::list<CGUITreeViewNode*>::Iterator itOther;
|
assert(child->Parent == this);
|
||||||
CGUITreeViewNode* nodeTmp;
|
auto nextPos = std::next(child->ParentPos);
|
||||||
bool moved = false;
|
if (nextPos == Children.end())
|
||||||
|
return false;
|
||||||
for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
|
auto curPos = child->ParentPos;
|
||||||
{
|
std::swap(*curPos, *nextPos);
|
||||||
if( child == *itChild )
|
std::swap((*curPos)->ParentPos, (*nextPos)->ParentPos);
|
||||||
{
|
return true;
|
||||||
if( itChild != Children.getLast() )
|
|
||||||
{
|
|
||||||
itOther = itChild;
|
|
||||||
++itOther;
|
|
||||||
nodeTmp = *itChild;
|
|
||||||
*itChild = *itOther;
|
|
||||||
*itOther = nodeTmp;
|
|
||||||
moved = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return moved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGUITreeViewNode::setExpanded( bool expanded )
|
void CGUITreeViewNode::setExpanded( bool expanded )
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#define __C_GUI_TREE_VIEW_H_INCLUDED__
|
#define __C_GUI_TREE_VIEW_H_INCLUDED__
|
||||||
|
|
||||||
#include "IGUITreeView.h"
|
#include "IGUITreeView.h"
|
||||||
#include "irrList.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -93,7 +92,7 @@ namespace gui
|
|||||||
|
|
||||||
//! returns the child item count
|
//! returns the child item count
|
||||||
virtual u32 getChildCount() const _IRR_OVERRIDE_
|
virtual u32 getChildCount() const _IRR_OVERRIDE_
|
||||||
{ return Children.getSize(); }
|
{ return Children.size(); }
|
||||||
|
|
||||||
//! removes all children (recursive) from this node
|
//! removes all children (recursive) from this node
|
||||||
virtual void clearChildren() _IRR_OVERRIDE_;
|
virtual void clearChildren() _IRR_OVERRIDE_;
|
||||||
@ -231,7 +230,10 @@ namespace gui
|
|||||||
void* Data;
|
void* Data;
|
||||||
IReferenceCounted* Data2;
|
IReferenceCounted* Data2;
|
||||||
bool Expanded;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "CIrrDeviceOSX.h"
|
#include "CIrrDeviceOSX.h"
|
||||||
|
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "CIrrDeviceSDL.h"
|
#include "CIrrDeviceSDL.h"
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
@ -26,28 +25,26 @@
|
|||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||||
|
#include "CSDLManager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static int SDLDeviceInstances = 0;
|
static int SDLDeviceInstances = 0;
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace video
|
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_
|
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||||
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
|
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
|
||||||
io::IFileSystem* io, CIrrDeviceSDL* device);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_OGLES2_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
|
#ifdef _IRR_COMPILE_WITH_OGLES2_
|
||||||
IVideoDriver* createOGLES2Driver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
|
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WEBGL1_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
|
#ifdef _IRR_COMPILE_WITH_WEBGL1_
|
||||||
IVideoDriver* createWebGL1Driver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
|
IVideoDriver* createWebGL1Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
|
||||||
#endif
|
#endif
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
|
|
||||||
@ -461,7 +458,8 @@ void CIrrDeviceSDL::createDriver()
|
|||||||
|
|
||||||
case video::EDT_OPENGL:
|
case video::EDT_OPENGL:
|
||||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||||
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
|
ContextManager = new video::CSDLManager(this);
|
||||||
|
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
|
||||||
#else
|
#else
|
||||||
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
|
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "CIrrDeviceWin32.h"
|
#include "CIrrDeviceWin32.h"
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
#include "irrList.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
|
@ -48,8 +48,7 @@ find_package(ZLIB REQUIRED)
|
|||||||
find_package(JPEG REQUIRED)
|
find_package(JPEG REQUIRED)
|
||||||
find_package(PNG REQUIRED)
|
find_package(PNG REQUIRED)
|
||||||
|
|
||||||
# To configure the features available in this Irrlicht build please edit
|
# To configure the features available in this Irrlicht build please edit include/IrrCompileConfig.h.
|
||||||
# include/IrrCompileConfig.h and re-run CMake from a clean state
|
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${PROJECT_SOURCE_DIR}/include)
|
set(CMAKE_REQUIRED_INCLUDES ${PROJECT_SOURCE_DIR}/include)
|
||||||
unset(OGLES1_ENABLED CACHE)
|
unset(OGLES1_ENABLED CACHE)
|
||||||
@ -58,6 +57,9 @@ unset(OGL_ENABLED CACHE)
|
|||||||
unset(XINPUT2_ENABLED CACHE)
|
unset(XINPUT2_ENABLED CACHE)
|
||||||
unset(SDL_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)
|
check_symbol_exists(_IRR_COMPILE_WITH_OGLES1_ "IrrCompileConfig.h" OGLES1_ENABLED)
|
||||||
if(OGLES1_ENABLED)
|
if(OGLES1_ENABLED)
|
||||||
# only tested on Android, probably works on Linux (is this needed anywhere else?)
|
# 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")
|
set(OpenGL_GL_PREFERENCE "LEGACY")
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
check_symbol_exists(_IRR_LINUX_X11_XINPUT2_ "IrrCompileConfig.h" XINPUT2_ENABLED)
|
if(NOT ANDROID AND NOT APPLE)
|
||||||
if(XINPUT2_ENABLED)
|
check_symbol_exists(_IRR_LINUX_X11_XINPUT2_ "IrrCompileConfig.h" XINPUT2_ENABLED)
|
||||||
|
if(XINPUT2_ENABLED)
|
||||||
find_library(XINPUT_LIBRARY Xi REQUIRED)
|
find_library(XINPUT_LIBRARY Xi REQUIRED)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
check_symbol_exists(_IRR_COMPILE_WITH_SDL_DEVICE_ "IrrCompileConfig.h" SDL_ENABLED)
|
check_symbol_exists(_IRR_COMPILE_WITH_SDL_DEVICE_ "IrrCompileConfig.h" SDL_ENABLED)
|
||||||
if(SDL_ENABLED)
|
if(SDL_ENABLED)
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
find_package(SDL2 CONFIG REQUIRED)
|
||||||
@ -185,6 +188,7 @@ set(IRRDRVROBJ
|
|||||||
CGLXManager.cpp
|
CGLXManager.cpp
|
||||||
CWGLManager.cpp
|
CWGLManager.cpp
|
||||||
CEGLManager.cpp
|
CEGLManager.cpp
|
||||||
|
CSDLManager.cpp
|
||||||
mt_opengl_loader.cpp
|
mt_opengl_loader.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
#include "CMeshBuffer.h"
|
#include "CMeshBuffer.h"
|
||||||
#include "SAnimatedMesh.h"
|
#include "SAnimatedMesh.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "irrMap.h"
|
|
||||||
#include "triangle3d.h"
|
#include "triangle3d.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -1789,8 +1789,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
buf->Vertices.reallocate(vcount);
|
buf->Vertices.reallocate(vcount);
|
||||||
buf->Indices.reallocate(icount);
|
buf->Indices.reallocate(icount);
|
||||||
|
|
||||||
core::map<const video::S3DVertex, const u16> sind; // search index for fast operation
|
std::map<const video::S3DVertex, const u16> sind; // search index for fast operation
|
||||||
typedef core::map<const video::S3DVertex, const u16>::Node snode;
|
typedef std::map<const video::S3DVertex, const u16>::iterator snode;
|
||||||
|
|
||||||
// Main algorithm
|
// Main algorithm
|
||||||
u32 highest = 0;
|
u32 highest = 0;
|
||||||
@ -1820,45 +1820,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
// Output the best triangle
|
// Output the best triangle
|
||||||
u16 newind = buf->Vertices.size();
|
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->Vertices.push_back(v[tc[highest].ind[0]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[0]], newind);
|
sind.emplace(v[tc[highest].ind[0]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[1]]);
|
s = sind.find(v[tc[highest].ind[1]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[1]], newind);
|
sind.emplace(v[tc[highest].ind[1]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[2]]);
|
s = sind.find(v[tc[highest].ind[2]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[2]], newind);
|
sind.emplace(v[tc[highest].ind[2]], newind);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
vc[tc[highest].ind[0]].NumActiveTris--;
|
vc[tc[highest].ind[0]].NumActiveTris--;
|
||||||
@ -1901,8 +1901,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
buf->Vertices.reallocate(vcount);
|
buf->Vertices.reallocate(vcount);
|
||||||
buf->Indices.reallocate(icount);
|
buf->Indices.reallocate(icount);
|
||||||
|
|
||||||
core::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation
|
std::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation
|
||||||
typedef core::map<const video::S3DVertex2TCoords, const u16>::Node snode;
|
typedef std::map<const video::S3DVertex2TCoords, const u16>::iterator snode;
|
||||||
|
|
||||||
// Main algorithm
|
// Main algorithm
|
||||||
u32 highest = 0;
|
u32 highest = 0;
|
||||||
@ -1932,45 +1932,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
// Output the best triangle
|
// Output the best triangle
|
||||||
u16 newind = buf->Vertices.size();
|
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->Vertices.push_back(v[tc[highest].ind[0]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[0]], newind);
|
sind.emplace(v[tc[highest].ind[0]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[1]]);
|
s = sind.find(v[tc[highest].ind[1]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[1]], newind);
|
sind.emplace(v[tc[highest].ind[1]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[2]]);
|
s = sind.find(v[tc[highest].ind[2]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[2]], newind);
|
sind.emplace(v[tc[highest].ind[2]], newind);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
vc[tc[highest].ind[0]].NumActiveTris--;
|
vc[tc[highest].ind[0]].NumActiveTris--;
|
||||||
@ -2014,8 +2014,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
buf->Vertices.reallocate(vcount);
|
buf->Vertices.reallocate(vcount);
|
||||||
buf->Indices.reallocate(icount);
|
buf->Indices.reallocate(icount);
|
||||||
|
|
||||||
core::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation
|
std::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation
|
||||||
typedef core::map<const video::S3DVertexTangents, const u16>::Node snode;
|
typedef std::map<const video::S3DVertexTangents, const u16>::iterator snode;
|
||||||
|
|
||||||
// Main algorithm
|
// Main algorithm
|
||||||
u32 highest = 0;
|
u32 highest = 0;
|
||||||
@ -2045,45 +2045,45 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
|||||||
// Output the best triangle
|
// Output the best triangle
|
||||||
u16 newind = buf->Vertices.size();
|
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->Vertices.push_back(v[tc[highest].ind[0]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[0]], newind);
|
sind.emplace(v[tc[highest].ind[0]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[1]]);
|
s = sind.find(v[tc[highest].ind[1]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
buf->Vertices.push_back(v[tc[highest].ind[1]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[1]], newind);
|
sind.emplace(v[tc[highest].ind[1]], newind);
|
||||||
newind++;
|
newind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sind.find(v[tc[highest].ind[2]]);
|
s = sind.find(v[tc[highest].ind[2]]);
|
||||||
|
|
||||||
if (!s)
|
if (s == sind.end())
|
||||||
{
|
{
|
||||||
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
buf->Vertices.push_back(v[tc[highest].ind[2]]);
|
||||||
buf->Indices.push_back(newind);
|
buf->Indices.push_back(newind);
|
||||||
sind.insert(v[tc[highest].ind[2]], newind);
|
sind.emplace(v[tc[highest].ind[2]], newind);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->Indices.push_back(s->getValue());
|
buf->Indices.push_back(s->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
vc[tc[highest].ind[0]].NumActiveTris--;
|
vc[tc[highest].ind[0]].NumActiveTris--;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "IGPUProgrammingServices.h"
|
#include "IGPUProgrammingServices.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "irrMap.h"
|
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
#include "IMesh.h"
|
#include "IMesh.h"
|
||||||
#include "IMeshBuffer.h"
|
#include "IMeshBuffer.h"
|
||||||
|
@ -70,9 +70,9 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
|||||||
|
|
||||||
const u32 WORD_BUFFER_LENGTH = 512;
|
const u32 WORD_BUFFER_LENGTH = 512;
|
||||||
|
|
||||||
core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > vertexBuffer(1000);
|
core::array<core::vector3df> vertexBuffer(1000);
|
||||||
core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > normalsBuffer(1000);
|
core::array<core::vector3df> normalsBuffer(1000);
|
||||||
core::array<core::vector2df, core::irrAllocatorFast<core::vector2df> > textureCoordBuffer(1000);
|
core::array<core::vector2df> textureCoordBuffer(1000);
|
||||||
|
|
||||||
SObjMtl * currMtl = new SObjMtl();
|
SObjMtl * currMtl = new SObjMtl();
|
||||||
Materials.push_back(currMtl);
|
Materials.push_back(currMtl);
|
||||||
@ -250,16 +250,16 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int vertLocation;
|
int vertLocation;
|
||||||
core::map<video::S3DVertex, int>::Node* n = currMtl->VertMap.find(v);
|
auto n = currMtl->VertMap.find(v);
|
||||||
if (n)
|
if (n != currMtl->VertMap.end())
|
||||||
{
|
{
|
||||||
vertLocation = n->getValue();
|
vertLocation = n->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currMtl->Meshbuffer->Vertices.push_back(v);
|
currMtl->Meshbuffer->Vertices.push_back(v);
|
||||||
vertLocation = currMtl->Meshbuffer->Vertices.size() -1;
|
vertLocation = currMtl->Meshbuffer->Vertices.size() -1;
|
||||||
currMtl->VertMap.insert(v, vertLocation);
|
currMtl->VertMap.emplace(v, vertLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
faceCorners.push_back(vertLocation);
|
faceCorners.push_back(vertLocation);
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
#ifndef __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
|
#ifndef __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
|
||||||
#define __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
|
#define __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include "IMeshLoader.h"
|
#include "IMeshLoader.h"
|
||||||
#include "IFileSystem.h"
|
#include "IFileSystem.h"
|
||||||
#include "ISceneManager.h"
|
#include "ISceneManager.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "SMeshBuffer.h"
|
#include "SMeshBuffer.h"
|
||||||
#include "irrMap.h"
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ private:
|
|||||||
Meshbuffer->Material = o.Meshbuffer->Material;
|
Meshbuffer->Material = o.Meshbuffer->Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::map<video::S3DVertex, int> VertMap;
|
std::map<video::S3DVertex, int> VertMap;
|
||||||
scene::SMeshBuffer *Meshbuffer;
|
scene::SMeshBuffer *Meshbuffer;
|
||||||
core::stringc Name;
|
core::stringc Name;
|
||||||
core::stringc Group;
|
core::stringc Group;
|
||||||
|
@ -441,9 +441,8 @@ COGLES2Driver::~COGLES2Driver()
|
|||||||
const E_VERTEX_TYPE vType = mb->getVertexType();
|
const E_VERTEX_TYPE vType = mb->getVertexType();
|
||||||
const u32 vertexSize = getVertexPitchFromType(vType);
|
const u32 vertexSize = getVertexPitchFromType(vType);
|
||||||
|
|
||||||
//buffer vertex data, and convert colours...
|
const void *buffer = vertices;
|
||||||
core::array<c8> buffer(vertexSize * vertexCount);
|
size_t bufferSize = vertexSize * vertexCount;
|
||||||
memcpy(buffer.pointer(), vertices, vertexSize * vertexCount);
|
|
||||||
|
|
||||||
//get or create buffer
|
//get or create buffer
|
||||||
bool newBuffer = false;
|
bool newBuffer = false;
|
||||||
@ -453,7 +452,7 @@ COGLES2Driver::~COGLES2Driver()
|
|||||||
if (!HWBuffer->vbo_verticesID) return false;
|
if (!HWBuffer->vbo_verticesID) return false;
|
||||||
newBuffer = true;
|
newBuffer = true;
|
||||||
}
|
}
|
||||||
else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize)
|
else if (HWBuffer->vbo_verticesSize < bufferSize)
|
||||||
{
|
{
|
||||||
newBuffer = true;
|
newBuffer = true;
|
||||||
}
|
}
|
||||||
@ -462,15 +461,15 @@ COGLES2Driver::~COGLES2Driver()
|
|||||||
|
|
||||||
// copy data to graphics card
|
// copy data to graphics card
|
||||||
if (!newBuffer)
|
if (!newBuffer)
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, buffer.const_pointer());
|
glBufferSubData(GL_ARRAY_BUFFER, 0, bufferSize, buffer);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HWBuffer->vbo_verticesSize = vertexCount * vertexSize;
|
HWBuffer->vbo_verticesSize = bufferSize;
|
||||||
|
|
||||||
if (HWBuffer->Mapped_Vertex == scene::EHM_STATIC)
|
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
|
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);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
@ -112,12 +112,12 @@ bool COGLES1Driver::genericDriverInit(const core::dimension2d<u32>& screenSize,
|
|||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
UserClipPlane.reallocate(MaxUserClipPlanes);
|
UserClipPlane.reallocate(MaxUserClipPlanes);
|
||||||
UserClipPlaneEnabled.reallocate(MaxUserClipPlanes);
|
UserClipPlaneEnabled.resize(MaxUserClipPlanes);
|
||||||
|
|
||||||
for (s32 i = 0; i < MaxUserClipPlanes; ++i)
|
for (s32 i = 0; i < MaxUserClipPlanes; ++i)
|
||||||
{
|
{
|
||||||
UserClipPlane.push_back(core::plane3df());
|
UserClipPlane.push_back(core::plane3df());
|
||||||
UserClipPlaneEnabled.push_back(false);
|
UserClipPlaneEnabled[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i = 0; i < ETS_COUNT; ++i)
|
for (s32 i = 0; i < ETS_COUNT; ++i)
|
||||||
|
@ -363,7 +363,7 @@ namespace video
|
|||||||
|
|
||||||
SMaterial Material, LastMaterial;
|
SMaterial Material, LastMaterial;
|
||||||
core::array<core::plane3df> UserClipPlane;
|
core::array<core::plane3df> UserClipPlane;
|
||||||
core::array<bool> UserClipPlaneEnabled;
|
std::vector<bool> UserClipPlaneEnabled;
|
||||||
|
|
||||||
core::stringc VendorName;
|
core::stringc VendorName;
|
||||||
|
|
||||||
|
@ -20,10 +20,6 @@
|
|||||||
|
|
||||||
#include "mt_opengl.h"
|
#include "mt_opengl.h"
|
||||||
|
|
||||||
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
|
|
||||||
#include "CIrrDeviceSDL.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace video
|
namespace video
|
||||||
@ -32,7 +28,6 @@ namespace video
|
|||||||
// Statics variables
|
// Statics variables
|
||||||
const u16 COpenGLDriver::Quad2DIndices[4] = { 0, 1, 2, 3 };
|
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)
|
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
|
||||||
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), CacheHandler(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
|
: 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),
|
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");
|
setDebugName("COpenGLDriver");
|
||||||
#endif
|
#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()
|
bool COpenGLDriver::initDriver()
|
||||||
{
|
{
|
||||||
@ -267,11 +245,6 @@ bool COpenGLDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth,
|
|||||||
if (ContextManager)
|
if (ContextManager)
|
||||||
ContextManager->activateContext(videoData, true);
|
ContextManager->activateContext(videoData, true);
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
|
||||||
if (SDLDevice)
|
|
||||||
glFrontFace(GL_CW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);
|
clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -288,14 +261,6 @@ bool COpenGLDriver::endScene()
|
|||||||
if (ContextManager)
|
if (ContextManager)
|
||||||
status = ContextManager->swapBuffers();
|
status = ContextManager->swapBuffers();
|
||||||
|
|
||||||
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
|
|
||||||
if (SDLDevice)
|
|
||||||
{
|
|
||||||
SDLDevice->SwapWindow();
|
|
||||||
status = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// todo: console device present
|
// todo: console device present
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -4437,7 +4402,6 @@ namespace irr
|
|||||||
namespace video
|
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)
|
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
|
||||||
{
|
{
|
||||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||||
@ -4454,22 +4418,6 @@ namespace video
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#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
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
@ -44,13 +44,7 @@ namespace video
|
|||||||
EOFPS_DISABLE_TO_ENABLE // switch from programmable to fixed pipeline.
|
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);
|
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();
|
bool initDriver();
|
||||||
|
|
||||||
@ -520,10 +514,6 @@ namespace video
|
|||||||
S3DVertex Quad2DVertices[4];
|
S3DVertex Quad2DVertices[4];
|
||||||
static const u16 Quad2DIndices[4];
|
static const u16 Quad2DIndices[4];
|
||||||
|
|
||||||
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
|
|
||||||
CIrrDeviceSDL *SDLDevice;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IContextManager* ContextManager;
|
IContextManager* ContextManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
56
source/Irrlicht/CSDLManager.cpp
Normal file
56
source/Irrlicht/CSDLManager.cpp
Normal 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
|
53
source/Irrlicht/CSDLManager.h
Normal file
53
source/Irrlicht/CSDLManager.h
Normal 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
|
@ -855,7 +855,7 @@ ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* st
|
|||||||
ISceneNode* node = 0;
|
ISceneNode* node = 0;
|
||||||
|
|
||||||
const ISceneNodeList& list = start->getChildren();
|
const ISceneNodeList& list = start->getChildren();
|
||||||
ISceneNodeList::ConstIterator it = list.begin();
|
ISceneNodeList::const_iterator it = list.begin();
|
||||||
for (; it!=list.end(); ++it)
|
for (; it!=list.end(); ++it)
|
||||||
{
|
{
|
||||||
node = getSceneNodeFromName(name, *it);
|
node = getSceneNodeFromName(name, *it);
|
||||||
@ -879,7 +879,7 @@ ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
|
|||||||
ISceneNode* node = 0;
|
ISceneNode* node = 0;
|
||||||
|
|
||||||
const ISceneNodeList& list = start->getChildren();
|
const ISceneNodeList& list = start->getChildren();
|
||||||
ISceneNodeList::ConstIterator it = list.begin();
|
ISceneNodeList::const_iterator it = list.begin();
|
||||||
for (; it!=list.end(); ++it)
|
for (; it!=list.end(); ++it)
|
||||||
{
|
{
|
||||||
node = getSceneNodeFromId(id, *it);
|
node = getSceneNodeFromId(id, *it);
|
||||||
@ -903,7 +903,7 @@ ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, IS
|
|||||||
ISceneNode* node = 0;
|
ISceneNode* node = 0;
|
||||||
|
|
||||||
const ISceneNodeList& list = start->getChildren();
|
const ISceneNodeList& list = start->getChildren();
|
||||||
ISceneNodeList::ConstIterator it = list.begin();
|
ISceneNodeList::const_iterator it = list.begin();
|
||||||
for (; it!=list.end(); ++it)
|
for (; it!=list.end(); ++it)
|
||||||
{
|
{
|
||||||
node = getSceneNodeFromType(type, *it);
|
node = getSceneNodeFromType(type, *it);
|
||||||
@ -925,7 +925,7 @@ void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array<sce
|
|||||||
outNodes.push_back(start);
|
outNodes.push_back(start);
|
||||||
|
|
||||||
const ISceneNodeList& list = start->getChildren();
|
const ISceneNodeList& list = start->getChildren();
|
||||||
ISceneNodeList::ConstIterator it = list.begin();
|
ISceneNodeList::const_iterator it = list.begin();
|
||||||
|
|
||||||
for (; it!=list.end(); ++it)
|
for (; it!=list.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -231,6 +231,9 @@ namespace scene
|
|||||||
|
|
||||||
struct DefaultNodeEntry
|
struct DefaultNodeEntry
|
||||||
{
|
{
|
||||||
|
DefaultNodeEntry()
|
||||||
|
{ }
|
||||||
|
|
||||||
DefaultNodeEntry(ISceneNode* n) :
|
DefaultNodeEntry(ISceneNode* n) :
|
||||||
Node(n), TextureValue(0)
|
Node(n), TextureValue(0)
|
||||||
{
|
{
|
||||||
@ -251,6 +254,9 @@ namespace scene
|
|||||||
//! sort on distance (center) to camera
|
//! sort on distance (center) to camera
|
||||||
struct TransparentNodeEntry
|
struct TransparentNodeEntry
|
||||||
{
|
{
|
||||||
|
TransparentNodeEntry()
|
||||||
|
{ }
|
||||||
|
|
||||||
TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera)
|
TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera)
|
||||||
: Node(n)
|
: Node(n)
|
||||||
{
|
{
|
||||||
|
@ -1042,7 +1042,7 @@ void CSkinnedMesh::finalize()
|
|||||||
|
|
||||||
for (i=0; i<LocalBuffers.size(); ++i)
|
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());
|
Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,9 @@ private:
|
|||||||
core::array<SJoint*> AllJoints;
|
core::array<SJoint*> AllJoints;
|
||||||
core::array<SJoint*> RootJoints;
|
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;
|
core::aabbox3d<f32> BoundingBox;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user