Modernization of several core classes #5036
DNKpp
started this conversation in
Engine Core
Replies: 1 comment 3 replies
-
See also #3058. Note that Godot's philosophy is to prefer the use of simple C-like constructs over using modern C++ constructs. This makes the codebase easier to understand for people who aren't C++ experts (we have a lot of contributors for whom C++ is not their primary language).
This was proposed in godotengine/godot#44382 and was rejected. |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
As I'm quite new to godot, I wanted to get a picture of some of the engine internals. I was very surprises when I discovered many copy-paste code, lots of manual raw loops, which in fact mimic stl algorithms, and some questionable class designs. Don't get me wrong, I'm not in the position right now to make a general statement about the code quality of godot, but there are definitely core classes (CowData, Vector, Array, Variant) which can be modernized. Making more use of the stl leads to less maintainable code and will most likely as fast or even faster than now.
But lets start the discussion at
Vector
. https://github.com/godotengine/godot/blob/master/core/templates/vector.hBetter Iterator Support
The first improvement could be extended the use of iterators, as those are very powerful abstractions over tedious manual indices. Yes, that's probably a matter of taste, but as c++ (and especially c++20) sees iterators as one of their core-concepts, it's totally worth getting used to them. Especially if we can get rid of some hard to understandable code. As you can see,
Vector
already has(Const)Iterators
but they are in fact nothing else than pointers. We can get rid of both classes by simply adding:This will make our iterators instantly a
RandomAccessIterator
.and as we support bidirectional iteration,
The iterator functions are then simply that:
Note: The
cbegin
,cend
, etc. aren't of course not explicitly necessary, but as Vector is often making a deep copy when working with.ptrw()
, I recommend adding them, because users can then easily select the immutable iterators.Extended iterator support will at least come in handy, when godot moves to c++20, but are also currently a big deal with the existing stl algorithms and libraries such as
ranges-v3
.Make use of the iterators
The
Vector
class implements many algorithms manually, which we can simply replace with stl counterparts:The
Vector
also offers a binary search, which is implemented in an other file. We can get rid of the include and replace them withOne interesting thing is, that the class documentation recommends using
Vector
for "large arrays", but then uses the insertion sort as sorting algorithm, which scales quite bad for larger ranges.std::sort
uses the quicksort algorithm, which is far more efficent for larger arrays, thus the wholearray_sort.h
header can be removed and the sort simply implemented via stl:What the hacks?!
From my point of view, there are several design flaws within that class.
const
vsnon-const
get
FunctionIn contrast to the
const ref
returned by theconst
overload ofget
, the non-constget
Function always returns a copy of the retrieved value, because theVector
trys to only expose immutable data. I don't think that's a nice and clean design as this has its own flaws and may lead to surprising results for users of that class, as both overloads in fact do different things. I suggest removing thenon-const get
.VectorWriteProxy
VectorWriteProxy
is one of the dirties tricks I have ever seen in c++. I think we can do better and simply get rid of theoperator []
overloads, as we already haveget
andset
functions, which reflect our use-case very well. In fact this is simply another redundance.Crazy Copy Constructor
The copy constructor is a huge hack. If someone tries copying the
Vector
, they will simply receive a completely independent emptyVector
. There should be a better solution, even if its simply deleting the copy.Explicit function aliases
push_back
andappend
are simply aliases for each other. I think godot 4 alpha is a good time for removing redundant functionalities. I would probably go with theappend
and rename theappend_array
also toappend
. But that's clearly a matter of taste.Erase seems unintuitive
erase
searches for a value and erases it once. Wouldn't it be more intuitive if it erases all appearances of that value?So, what now?
I invested some time and applied most of the changes I have in mind for that vector class, without changing too much of the interface. Have a look here: https://pastebin.com/HiSmw4A4
Note, that isn't tested yet, may contain some compile errors and is not finally thought about, but it's probably enough to get the idea what I'm talking about. Is that something the godot team is interested in? Then I would make a more complete pull request and have also a look at the other mentioned classes.
Greetings
Beta Was this translation helpful? Give feedback.
All reactions