Skip to content

Commit

Permalink
Merge pull request #38083 from reduz/use-typed-arrays
Browse files Browse the repository at this point in the history
Add proper type to most public API uses of Array
  • Loading branch information
akien-mga authored Apr 21, 2020
2 parents 4f03e30 + f8ef38e commit cb1ae08
Show file tree
Hide file tree
Showing 26 changed files with 156 additions and 165 deletions.
33 changes: 29 additions & 4 deletions core/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,37 @@ void Array::_assign(const Array &p_array) {
} else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway
_p->array = p_array._p->array;
} else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid
for (int i = 0; i < p_array._p->array.size(); i++) {
if (!_p->typed.validate(p_array._p->array[i], "assign")) {
return;
if (_p->typed.type == Variant::OBJECT) {
//for objects, it needs full validation, either can be converted or fail
for (int i = 0; i < p_array._p->array.size(); i++) {
if (!_p->typed.validate(p_array._p->array[i], "assign")) {
return;
}
}
_p->array = p_array._p->array; //then just copy, which is cheap anyway

} else {
//for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case.
Vector<Variant> new_array;
new_array.resize(p_array._p->array.size());
for (int i = 0; i < p_array._p->array.size(); i++) {
Variant src_val = p_array._p->array[i];
if (src_val.get_type() == _p->typed.type) {
new_array.write[i] = src_val;
} else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) {
Variant *ptr = &src_val;
Callable::CallError ce;
new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
}
} else {
ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
}
}

_p->array = new_array;
}
_p->array = p_array._p->array; //then just copy, which is cheap anyway
} else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
_ref(p_array);
} else {
Expand Down
32 changes: 19 additions & 13 deletions core/typed_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class TypedArray : public Array {
_FORCE_INLINE_ void operator=(const Array &p_array) {
_assign(p_array);
}
_FORCE_INLINE_ TypedArray(const Variant &p_variant) :
Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
}
_FORCE_INLINE_ TypedArray(const Array &p_array) :
Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) {
}
Expand All @@ -27,19 +30,22 @@ class TypedArray : public Array {

//specialization for the rest of variant types

#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
template <> \
class TypedArray<m_type> : public Array { \
public: \
_FORCE_INLINE_ void operator=(const Array &p_array) { \
_assign(p_array); \
} \
_FORCE_INLINE_ TypedArray(const Array &p_array) : \
Array(p_array, m_variant_type, StringName(), Variant()) { \
} \
_FORCE_INLINE_ TypedArray() { \
set_typed(m_variant_type, StringName(), Variant()); \
} \
#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
template <> \
class TypedArray<m_type> : public Array { \
public: \
_FORCE_INLINE_ void operator=(const Array &p_array) { \
_assign(p_array); \
} \
_FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
} \
_FORCE_INLINE_ TypedArray(const Array &p_array) : \
Array(p_array, m_variant_type, StringName(), Variant()) { \
} \
_FORCE_INLINE_ TypedArray() { \
set_typed(m_variant_type, StringName(), Variant()); \
} \
};

MAKE_TYPED_ARRAY(bool, Variant::BOOL)
Expand Down
4 changes: 2 additions & 2 deletions drivers/vulkan/rendering_device_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3327,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
}

// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) {
RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) {

_THREAD_SAFE_METHOD_

Expand Down Expand Up @@ -3402,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo

//validate with buffer
{
const VertexDescription &atf = vd.vertex_formats[i];
const VertexAttribute &atf = vd.vertex_formats[i];

uint32_t element_size = get_format_vertex_size(atf.format);
ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated
Expand Down
18 changes: 9 additions & 9 deletions drivers/vulkan/rendering_device_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,19 +332,19 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID_Owner<Buffer, true> vertex_buffer_owner;

struct VertexDescriptionKey {
Vector<VertexDescription> vertex_formats;
Vector<VertexAttribute> vertex_formats;
bool operator==(const VertexDescriptionKey &p_key) const {
int vdc = vertex_formats.size();
int vdck = p_key.vertex_formats.size();

if (vdc != vdck) {
return false;
} else {
const VertexDescription *a_ptr = vertex_formats.ptr();
const VertexDescription *b_ptr = p_key.vertex_formats.ptr();
const VertexAttribute *a_ptr = vertex_formats.ptr();
const VertexAttribute *b_ptr = p_key.vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
const VertexDescription &a = a_ptr[i];
const VertexDescription &b = b_ptr[i];
const VertexAttribute &a = a_ptr[i];
const VertexAttribute &b = b_ptr[i];

if (a.location != b.location) {
return false;
Expand All @@ -369,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t hash() const {
int vdc = vertex_formats.size();
uint32_t h = hash_djb2_one_32(vdc);
const VertexDescription *ptr = vertex_formats.ptr();
const VertexAttribute *ptr = vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
const VertexDescription &vd = ptr[i];
const VertexAttribute &vd = ptr[i];
h = hash_djb2_one_32(vd.location, h);
h = hash_djb2_one_32(vd.offset, h);
h = hash_djb2_one_32(vd.format, h);
Expand All @@ -393,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache;

struct VertexDescriptionCache {
Vector<VertexDescription> vertex_formats;
Vector<VertexAttribute> vertex_formats;
VkVertexInputBindingDescription *bindings;
VkVertexInputAttributeDescription *attributes;
VkPipelineVertexInputStateCreateInfo create_info;
Expand Down Expand Up @@ -1016,7 +1016,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());

// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats);
virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats);
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers);

virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false);
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() {
return ret;
}

Array EditorSelection::get_selected_nodes() {
TypedArray<Node> EditorSelection::get_selected_nodes() {

Array ret;
TypedArray<Node> ret;

for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {

Expand Down
2 changes: 1 addition & 1 deletion editor/editor_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ class EditorSelection : public Object {
static void _bind_methods();

public:
Array get_selected_nodes();
TypedArray<Node> get_selected_nodes();
void add_node(Node *p_node);
void remove_node(Node *p_node);
bool is_selected(Node *) const;
Expand Down
8 changes: 4 additions & 4 deletions scene/2d/area_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const {
return monitorable;
}

Array Area2D::get_overlapping_bodies() const {
TypedArray<Node2D> Area2D::get_overlapping_bodies() const {

ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
Array ret;
TypedArray<Node2D> ret;
ret.resize(body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
Expand All @@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const {
return ret;
}

Array Area2D::get_overlapping_areas() const {
TypedArray<Area2D> Area2D::get_overlapping_areas() const {

ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
Array ret;
TypedArray<Area2D> ret;
ret.resize(area_map.size());
int idx = 0;
for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
Expand Down
4 changes: 2 additions & 2 deletions scene/2d/area_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ class Area2D : public CollisionObject2D {
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;

Array get_overlapping_bodies() const; //function for script
Array get_overlapping_areas() const; //function for script
TypedArray<Node2D> get_overlapping_bodies() const; //function for script
TypedArray<Area2D> get_overlapping_areas() const; //function for script

bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
Expand Down
4 changes: 2 additions & 2 deletions scene/2d/navigation_region_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const {
return vertices;
}

void NavigationPolygon::_set_polygons(const Array &p_array) {
void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) {

{
MutexLock lock(navmesh_generation);
Expand All @@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const {
return ret;
}

void NavigationPolygon::_set_outlines(const Array &p_array) {
void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) {

outlines.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
Expand Down
4 changes: 2 additions & 2 deletions scene/2d/navigation_region_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ class NavigationPolygon : public Resource {
protected:
static void _bind_methods();

void _set_polygons(const Array &p_array);
void _set_polygons(const TypedArray<Vector<int32_t>> &p_array);
Array _get_polygons() const;

void _set_outlines(const Array &p_array);
void _set_outlines(const TypedArray<Vector<int32_t>> &p_array);
Array _get_outlines() const;

public:
Expand Down
6 changes: 3 additions & 3 deletions scene/2d/physics_body_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) :
set_pickable(false);
}

Array PhysicsBody2D::get_collision_exceptions() {
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
Expand Down Expand Up @@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons
return ccd_mode;
}

Array RigidBody2D::get_colliding_bodies() const {
TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const {

ERR_FAIL_COND_V(!contact_monitor, Array());

Array ret;
TypedArray<Node2D> ret;
ret.resize(contact_monitor->body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
Expand Down
4 changes: 2 additions & 2 deletions scene/2d/physics_body_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class PhysicsBody2D : public CollisionObject2D {
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;

Array get_collision_exceptions();
TypedArray<PhysicsBody2D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);

Expand Down Expand Up @@ -256,7 +256,7 @@ class RigidBody2D : public PhysicsBody2D {
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
void add_torque(float p_torque);

Array get_colliding_bodies() const; //function for script
TypedArray<Node2D> get_colliding_bodies() const; //function for script

virtual String get_configuration_warning() const;

Expand Down
6 changes: 3 additions & 3 deletions scene/2d/tile_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1705,13 +1705,13 @@ TypedArray<Vector2i> TileMap::get_used_cells() const {
return a;
}

Array TileMap::get_used_cells_by_id(int p_id) const {
TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const {

Array a;
TypedArray<Vector2i> a;
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {

if (E->value().id == p_id) {
Vector2 p(E->key().x, E->key().y);
Vector2i p(E->key().x, E->key().y);
a.push_back(p);
}
}
Expand Down
2 changes: 1 addition & 1 deletion scene/2d/tile_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class TileMap : public Node2D {
bool is_centered_textures_enabled() const;

TypedArray<Vector2i> get_used_cells() const;
Array get_used_cells_by_id(int p_id) const;
TypedArray<Vector2i> get_used_cells_by_id(int p_id) const;
Rect2 get_used_rect(); // Not const because of cache

void set_occluder_light_mask(int p_mask);
Expand Down
4 changes: 2 additions & 2 deletions scene/3d/area_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const {
return monitoring;
}

Array Area3D::get_overlapping_bodies() const {
TypedArray<Node3D> Area3D::get_overlapping_bodies() const {

ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
Expand Down Expand Up @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const {
return monitorable;
}

Array Area3D::get_overlapping_areas() const {
TypedArray<Area3D> Area3D::get_overlapping_areas() const {

ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
Expand Down
4 changes: 2 additions & 2 deletions scene/3d/area_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ class Area3D : public CollisionObject3D {
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;

Array get_overlapping_bodies() const;
Array get_overlapping_areas() const; //function for script
TypedArray<Node3D> get_overlapping_bodies() const;
TypedArray<Area3D> get_overlapping_areas() const; //function for script

bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
Expand Down
2 changes: 1 addition & 1 deletion scene/3d/physics_body_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}

Array PhysicsBody3D::get_collision_exceptions() {
TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
Expand Down
2 changes: 1 addition & 1 deletion scene/3d/physics_body_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class PhysicsBody3D : public CollisionObject3D {
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;

Array get_collision_exceptions();
TypedArray<PhysicsBody3D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);

Expand Down
12 changes: 5 additions & 7 deletions scene/3d/skeleton_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "core/engine.h"
#include "core/message_queue.h"
#include "core/project_settings.h"
#include "core/type_info.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/surface_tool.h"

Expand Down Expand Up @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect
}
}

void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) {
set_physics_process_internal(false);

Vector<int> sim_bones;
Expand All @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
sim_bones.resize(p_bones.size());
int c = 0;
for (int i = sim_bones.size() - 1; 0 <= i; --i) {
Variant::Type type = p_bones.get(i).get_type();
if (Variant::STRING == type || Variant::STRING_NAME == type) {
int bone_id = find_bone(p_bones.get(i));
if (bone_id != -1)
sim_bones.write[c++] = bone_id;
}
int bone_id = find_bone(p_bones[i]);
if (bone_id != -1)
sim_bones.write[c++] = bone_id;
}
sim_bones.resize(c);
}
Expand Down
Loading

0 comments on commit cb1ae08

Please sign in to comment.