This commit is contained in:
Cory Petkovsek 2021-11-11 11:59:12 +01:00 committed by GitHub
commit b83429182c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 103 additions and 89 deletions

View file

@ -42,9 +42,7 @@ class RID_OwnerBase;
class RID_Data {
friend class RID_OwnerBase;
#ifndef DEBUG_ENABLED
RID_OwnerBase *_owner;
#endif
uint32_t _id;
public:
@ -61,6 +59,8 @@ class RID {
public:
_FORCE_INLINE_ RID_Data *get_data() const { return _data; }
//_FORCE_INLINE_ void erase(RID &p_rid) { _data = nullptr; } // Useful to have?
_FORCE_INLINE_ bool operator==(const RID &p_rid) const {
return _data == p_rid._data;
}
@ -92,63 +92,41 @@ protected:
p_rid._data = p_data;
refcount.ref();
p_data->_id = refcount.get();
#ifndef DEBUG_ENABLED
p_data->_owner = this;
#endif
}
#ifndef DEBUG_ENABLED
_FORCE_INLINE_ void _free(RID &p_rid) {
p_rid._data = nullptr;
}
_FORCE_INLINE_ bool _is_owner(const RID &p_rid) const {
return this == p_rid._data->_owner;
}
_FORCE_INLINE_ void _remove_owner(RID &p_rid) {
p_rid._data->_owner = NULL;
p_rid._data->_owner = nullptr;
}
#endif
public:
virtual void get_owned_list(List<RID> *p_owned) = 0;
static void init_rid();
virtual ~RID_OwnerBase() {}
};
template <class T>
class RID_Owner : public RID_OwnerBase {
public:
#ifdef DEBUG_ENABLED
mutable Set<RID_Data *> id_map;
#endif
public:
_FORCE_INLINE_ RID make_rid(T *p_data) {
RID rid;
_set_data(rid, p_data);
#ifdef DEBUG_ENABLED
id_map.insert(p_data);
#endif
return rid;
}
_FORCE_INLINE_ T *get(const RID &p_rid) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V(!p_rid.is_valid(), nullptr);
ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()), nullptr);
#endif
return static_cast<T *>(p_rid.get_data());
}
_FORCE_INLINE_ T *getornull(const RID &p_rid) {
#ifdef DEBUG_ENABLED
if (p_rid.get_data()) {
ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()), nullptr);
}
#endif
return static_cast<T *>(p_rid.get_data());
}
@ -160,30 +138,16 @@ public:
if (p_rid.get_data() == nullptr) {
return false;
}
#ifdef DEBUG_ENABLED
return id_map.has(p_rid.get_data());
#else
return _is_owner(p_rid);
#endif
}
void free(RID p_rid) {
#ifdef DEBUG_ENABLED
id_map.erase(p_rid.get_data());
#else
void free(RID &p_rid) {
_remove_owner(p_rid);
#endif
_free(p_rid);
}
void get_owned_list(List<RID> *p_owned) {
#ifdef DEBUG_ENABLED
for (typename Set<RID_Data *>::Element *E = id_map.front(); E; E = E->next()) {
RID r;
_set_data(r, static_cast<T *>(E->get()));
p_owned->push_back(r);
}
#endif
// Used to be a debug only function disabled during release mode. Now deprecated.
}
};

View file

@ -630,6 +630,18 @@
<argument index="0" name="rid" type="RID" />
<description>
Destroys any of the objects created by PhysicsServer. If the [RID] passed is not one of the objects that can be created by PhysicsServer, an error will be sent to the console.
Note: After freeing the object, the RID now has a reference to invalid memory. It is not safe to free an invalid RID. Make sure to reset it before using it again by assigning it to `RID()`.
[code]
var r:RID = PhysicsServer.space_create()
PhysicsServer.free_rid(r)
print("ID: ", r.get_id()) # It is not safe to access or free an invalid RID
r = RID() # Reset the RID so it's safe to use or free again
print("ID: ", r.get_id())
Output:
ID: 157
ID: 0
[/code]
</description>
</method>
<method name="generic_6dof_joint_get_flag">

View file

@ -962,6 +962,18 @@
<argument index="0" name="rid" type="RID" />
<description>
Tries to free an object in the VisualServer.
Note: After freeing the object, the RID now has a reference to invalid memory. It is not safe to free an invalid RID. Make sure to reset it before using it again by assigning it to `RID()`.
[code]
var r:RID = VisualServer.get_test_cube()
VisualServer.free_rid(r)
print("ID: ", r.get_id()) # It is not safe to access or free an invalid RID
r = RID() # Reset the RID so it's safe to use or free again
print("ID: ", r.get_id())
Output:
ID: 157
ID: 0
[/code]
</description>
</method>
<method name="get_render_info">

View file

@ -3830,7 +3830,7 @@ void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
scene_pass = p_pass;
}
bool RasterizerSceneGLES2::free(RID p_rid) {
bool RasterizerSceneGLES2::free(RID &p_rid) {
if (light_instance_owner.owns(p_rid)) {
LightInstance *light_instance = light_instance_owner.getptr(p_rid);

View file

@ -764,7 +764,7 @@ public:
virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
virtual bool free(RID p_rid);
virtual bool free(RID &p_rid);
virtual void set_scene_pass(uint64_t p_pass);
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw);

View file

@ -5827,7 +5827,7 @@ VS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const {
}
}
bool RasterizerStorageGLES2::free(RID p_rid) {
bool RasterizerStorageGLES2::free(RID &p_rid) {
if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);
_render_target_clear(rt);

View file

@ -1324,7 +1324,7 @@ public:
virtual VS::InstanceType get_base_type(RID p_rid) const;
virtual bool free(RID p_rid);
virtual bool free(RID &p_rid);
struct Frame {
RenderTarget *current_rt;

View file

@ -4849,7 +4849,7 @@ void RasterizerSceneGLES3::set_scene_pass(uint64_t p_pass) {
scene_pass = p_pass;
}
bool RasterizerSceneGLES3::free(RID p_rid) {
bool RasterizerSceneGLES3::free(RID &p_rid) {
if (light_instance_owner.owns(p_rid)) {
LightInstance *light_instance = light_instance_owner.getptr(p_rid);

View file

@ -855,7 +855,7 @@ public:
bool _element_needs_directional_add(RenderList::Element *e);
virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
virtual bool free(RID p_rid);
virtual bool free(RID &p_rid);
virtual void set_scene_pass(uint64_t p_pass);
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw);

View file

@ -7727,7 +7727,7 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
return VS::INSTANCE_NONE;
}
bool RasterizerStorageGLES3::free(RID p_rid) {
bool RasterizerStorageGLES3::free(RID &p_rid) {
if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);
_render_target_clear(rt);

View file

@ -1480,7 +1480,7 @@ public:
virtual VS::InstanceType get_base_type(RID p_rid) const;
virtual bool free(RID p_rid);
virtual bool free(RID &p_rid);
struct Frame {
RenderTarget *current_rt;

View file

@ -1292,7 +1292,7 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
void AnimationPlayerEditor::_free_onion_layers() {
for (int i = 0; i < onion.captures.size(); i++) {
if (onion.captures[i].is_valid()) {
VS::get_singleton()->free(onion.captures[i]);
VS::get_singleton()->free(onion.captures.get(i));
}
}
onion.captures.clear();

View file

@ -5860,9 +5860,16 @@ void SpatialEditor::_finish_indicators() {
}
void SpatialEditor::_finish_grid() {
for (int i = 0; i < 3; i++) {
VisualServer::get_singleton()->free(grid_instance[i]);
VisualServer::get_singleton()->free(grid[i]);
for (int a = 0; a < 3; a++) {
if(grid_enable[a]) {
int c = (a + 2) % 3;
if (grid_instance[c].is_valid() && grid_instance[c].get_id() > 0) {
VisualServer::get_singleton()->free(grid_instance[c]);
}
if (grid[c].is_valid() && grid[c].get_id() > 0) {
VisualServer::get_singleton()->free(grid[c]);
}
}
}
}

View file

@ -90,7 +90,7 @@ bool EditorSpatialGizmo::is_editable() const {
void EditorSpatialGizmo::clear() {
for (int i = 0; i < instances.size(); i++) {
if (instances[i].instance.is_valid()) {
VS::get_singleton()->free(instances[i].instance);
VS::get_singleton()->free(instances.get(i).instance);
}
}
@ -740,7 +740,7 @@ void EditorSpatialGizmo::free() {
for (int i = 0; i < instances.size(); i++) {
if (instances[i].instance.is_valid()) {
VS::get_singleton()->free(instances[i].instance);
VS::get_singleton()->free(instances.get(i).instance);
}
instances.write[i].instance = RID();
}

View file

@ -1474,7 +1474,11 @@ bool BulletPhysicsServer::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis
return generic_6dof_joint->get_flag(p_axis, p_flag);
}
void BulletPhysicsServer::free(RID p_rid) {
void BulletPhysicsServer::free(RID &p_rid) {
if (!p_rid.is_valid() || p_rid.get_id() == 0) {
return;
}
if (shape_owner.owns(p_rid)) {
ShapeBullet *shape = shape_owner.get(p_rid);
@ -1528,7 +1532,7 @@ void BulletPhysicsServer::free(RID p_rid) {
space_owner.free(p_rid);
bulletdelete(space);
} else {
ERR_FAIL_MSG("Invalid ID.");
ERR_FAIL_MSG("Invalid RID.");
}
}

View file

@ -377,7 +377,7 @@ public:
/* MISC */
virtual void free(RID p_rid);
virtual void free(RID &p_rid);
virtual void set_active(bool p_active) {
active = p_active;

View file

@ -416,8 +416,8 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
VS::get_singleton()->free(g.multimesh_instances[i].instance);
VS::get_singleton()->free(g.multimesh_instances[i].multimesh);
VS::get_singleton()->free(g.multimesh_instances.get(i).instance);
VS::get_singleton()->free(g.multimesh_instances.get(i).multimesh);
}
g.multimesh_instances.clear();
@ -633,8 +633,8 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
VS::get_singleton()->free(g.multimesh_instances[i].instance);
VS::get_singleton()->free(g.multimesh_instances[i].multimesh);
VS::get_singleton()->free(g.multimesh_instances.get(i).instance);
VS::get_singleton()->free(g.multimesh_instances.get(i).multimesh);
}
g.multimesh_instances.clear();
}
@ -949,7 +949,7 @@ Vector3 GridMap::_get_offset() const {
void GridMap::clear_baked_meshes() {
for (int i = 0; i < baked_meshes.size(); i++) {
VS::get_singleton()->free(baked_meshes[i].instance);
VS::get_singleton()->free(baked_meshes.get(i).instance);
}
baked_meshes.clear();

View file

@ -1200,7 +1200,11 @@ bool PhysicsServerSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_a
return generic_6dof_joint->get_flag(p_axis, p_flag);
}
void PhysicsServerSW::free(RID p_rid) {
void PhysicsServerSW::free(RID &p_rid) {
if (!p_rid.is_valid() || p_rid.get_id() == 0) {
return;
}
_update_shapes(); //just in case
if (shape_owner.owns(p_rid)) {
@ -1273,7 +1277,7 @@ void PhysicsServerSW::free(RID p_rid) {
memdelete(joint);
} else {
ERR_FAIL_MSG("Invalid ID.");
ERR_FAIL_MSG("Invalid RID.");
}
};

View file

@ -355,7 +355,7 @@ public:
/* MISC */
virtual void free(RID p_rid);
virtual void free(RID &p_rid);
virtual void set_active(bool p_active);
virtual void init();

View file

@ -642,7 +642,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("joint_get_type", "joint"), &Physics2DServer::joint_get_type);
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &Physics2DServer::free);
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &Physics2DServer::free_rid);
ClassDB::bind_method(D_METHOD("set_active", "active"), &Physics2DServer::set_active);

View file

@ -548,6 +548,7 @@ public:
/* MISC */
virtual void free(RID p_rid) = 0;
virtual void free_rid(RID p_rid) { free(p_rid); } // gdscript binding
virtual void set_active(bool p_active) = 0;
virtual void init() = 0;

View file

@ -720,7 +720,7 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("generic_6dof_joint_set_flag", "joint", "axis", "flag", "enable"), &PhysicsServer::generic_6dof_joint_set_flag);
ClassDB::bind_method(D_METHOD("generic_6dof_joint_get_flag", "joint", "axis", "flag"), &PhysicsServer::generic_6dof_joint_get_flag);
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &PhysicsServer::free);
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &PhysicsServer::free_rid);
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer::set_active);

View file

@ -721,7 +721,8 @@ public:
/* MISC */
virtual void free(RID p_rid) = 0;
virtual void free(RID &p_rid) = 0;
virtual void free_rid(RID p_rid) { free(p_rid); } // gdscript binding
virtual void set_active(bool p_active) = 0;
virtual void init() = 0;

View file

@ -169,7 +169,7 @@ public:
virtual void set_scene_pass(uint64_t p_pass) = 0;
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) = 0;
virtual bool free(RID p_rid) = 0;
virtual bool free(RID &p_rid) = 0;
virtual ~RasterizerScene() {}
};
@ -595,7 +595,7 @@ public:
virtual void canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) = 0;
virtual VS::InstanceType get_base_type(RID p_rid) const = 0;
virtual bool free(RID p_rid) = 0;
virtual bool free(RID &p_rid) = 0;
virtual bool has_os_feature(const String &p_feature) const = 0;

View file

@ -1242,7 +1242,7 @@ void VisualServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_po
}
}
bool VisualServerCanvas::free(RID p_rid) {
bool VisualServerCanvas::free(RID &p_rid) {
if (canvas_owner.owns(p_rid)) {
Canvas *canvas = canvas_owner.get(p_rid);
ERR_FAIL_COND_V(!canvas, false);

View file

@ -253,7 +253,7 @@ public:
void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, VS::CanvasOccluderPolygonCullMode p_mode);
bool free(RID p_rid);
bool free(RID &p_rid);
VisualServerCanvas();
~VisualServerCanvas();
};

View file

@ -64,7 +64,11 @@ void VisualServerRaster::_draw_margins() {
/* FREE */
void VisualServerRaster::free(RID p_rid) {
void VisualServerRaster::free(RID &p_rid) {
if (! p_rid.is_valid() || p_rid.get_id() == 0) {
return;
}
if (VSG::storage->free(p_rid)) {
return;
}
@ -195,6 +199,7 @@ void VisualServerRaster::call_set_use_vsync(bool p_enable) {
bool VisualServerRaster::is_low_end() const {
return VSG::rasterizer->is_low_end();
}
VisualServerRaster::VisualServerRaster() {
VSG::canvas = memnew(VisualServerCanvas);
VSG::viewport = memnew(VisualServerViewport);

View file

@ -724,7 +724,7 @@ public:
/* FREE */
virtual void free(RID p_rid); ///< free RIDs associated with the visual server
virtual void free(RID &p_rid); ///< free RIDs associated with the visual server
/* EVENT QUEUING */

View file

@ -4028,7 +4028,7 @@ void VisualServerScene::update_dirty_instances() {
}
}
bool VisualServerScene::free(RID p_rid) {
bool VisualServerScene::free(RID &p_rid) {
if (camera_owner.owns(p_rid)) {
Camera *camera = camera_owner.get(p_rid);
@ -4047,8 +4047,6 @@ bool VisualServerScene::free(RID p_rid) {
memdelete(scenario);
} else if (instance_owner.owns(p_rid)) {
// delete the instance
update_dirty_instances();
Instance *instance = instance_owner.get(p_rid);
@ -4063,26 +4061,32 @@ bool VisualServerScene::free(RID p_rid) {
instance_owner.free(p_rid);
memdelete(instance);
} else if (room_owner.owns(p_rid)) {
Room *room = room_owner.get(p_rid);
room_owner.free(p_rid);
memdelete(room);
} else if (portal_owner.owns(p_rid)) {
Portal *portal = portal_owner.get(p_rid);
portal_owner.free(p_rid);
memdelete(portal);
} else if (ghost_owner.owns(p_rid)) {
Ghost *ghost = ghost_owner.get(p_rid);
ghost_owner.free(p_rid);
memdelete(ghost);
} else if (roomgroup_owner.owns(p_rid)) {
RoomGroup *roomgroup = roomgroup_owner.get(p_rid);
roomgroup_owner.free(p_rid);
memdelete(roomgroup);
} else if (occluder_owner.owns(p_rid)) {
Occluder *ro = occluder_owner.get(p_rid);
occluder_owner.free(p_rid);
memdelete(ro);
} else {
return false;
}

View file

@ -755,7 +755,7 @@ public:
void render_probes();
bool free(RID p_rid);
bool free(RID &p_rid);
private:
bool _use_bvh;

View file

@ -710,7 +710,7 @@ void VisualServerViewport::viewport_set_debug_draw(RID p_viewport, VS::ViewportD
viewport->debug_draw = p_draw;
}
bool VisualServerViewport::free(RID p_rid) {
bool VisualServerViewport::free(RID &p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.getornull(p_rid);

View file

@ -198,7 +198,7 @@ public:
void set_default_clear_color(const Color &p_color);
void draw_viewports();
bool free(RID p_rid);
bool free(RID &p_rid);
VisualServerViewport();
virtual ~VisualServerViewport() {}

View file

@ -643,7 +643,7 @@ public:
/* FREE */
FUNC1(free, RID)
FUNC1(free, RID &)
/* EVENT QUEUING */

View file

@ -2226,7 +2226,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("black_bars_set_margins", "left", "top", "right", "bottom"), &VisualServer::black_bars_set_margins);
ClassDB::bind_method(D_METHOD("black_bars_set_images", "left", "top", "right", "bottom"), &VisualServer::black_bars_set_images);
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &VisualServer::free); // shouldn't conflict with Object::free()
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &VisualServer::free_rid); // shouldn't conflict with Object::free()
ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &VisualServer::request_frame_drawn_callback);
ClassDB::bind_method(D_METHOD("has_changed"), &VisualServer::has_changed);

View file

@ -1092,8 +1092,8 @@ public:
/* FREE */
virtual void free(RID p_rid) = 0; ///< free RIDs associated with the visual server
virtual void free(RID &p_rid) = 0; ///< free RIDs associated with the visual server
virtual void free_rid(RID p_rid) { free(p_rid); } // for gdscript binding
virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) = 0;
/* EVENT QUEUING */