Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
cd7b51b9
Unverified
Commit
cd7b51b9
authored
Jan 16, 2020
by
Rémi Verschelde
Committed by
GitHub
Jan 16, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #35102 from ChibiDenDen/reuse_orphaned_subclass
#34161: Keep a weak reference to orphan subclasses to reuse on class reload
parents
9986f380
86aa12e8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
5 deletions
+63
-5
gdscript.cpp
modules/gdscript/gdscript.cpp
+48
-3
gdscript.h
modules/gdscript/gdscript.h
+7
-0
gdscript_compiler.cpp
modules/gdscript/gdscript_compiler.cpp
+8
-2
No files found.
modules/gdscript/gdscript.cpp
View file @
cd7b51b9
...
@@ -915,14 +915,43 @@ GDScript::GDScript() :
...
@@ -915,14 +915,43 @@ GDScript::GDScript() :
#endif
#endif
}
}
void
GDScript
::
_save_orphaned_subclasses
()
{
struct
ClassRefWithName
{
ObjectID
id
;
String
fully_qualified_name
;
};
Vector
<
ClassRefWithName
>
weak_subclasses
;
// collect subclasses ObjectID and name
for
(
Map
<
StringName
,
Ref
<
GDScript
>
>::
Element
*
E
=
subclasses
.
front
();
E
;
E
=
E
->
next
())
{
E
->
get
()
->
_owner
=
NULL
;
//bye, you are no longer owned cause I died
ClassRefWithName
subclass
;
subclass
.
id
=
E
->
get
()
->
get_instance_id
();
subclass
.
fully_qualified_name
=
E
->
get
()
->
fully_qualified_name
;
weak_subclasses
.
push_back
(
subclass
);
}
// clear subclasses to allow unused subclasses to be deleted
subclasses
.
clear
();
// subclasses are also held by constants, clear those as well
constants
.
clear
();
// keep orphan subclass only for subclasses that are still in use
for
(
int
i
=
0
;
i
<
weak_subclasses
.
size
();
i
++
)
{
ClassRefWithName
subclass
=
weak_subclasses
[
i
];
Object
*
obj
=
ObjectDB
::
get_instance
(
subclass
.
id
);
if
(
!
obj
)
continue
;
// subclass is not released
GDScriptLanguage
::
get_singleton
()
->
add_orphan_subclass
(
subclass
.
fully_qualified_name
,
subclass
.
id
);
}
}
GDScript
::~
GDScript
()
{
GDScript
::~
GDScript
()
{
for
(
Map
<
StringName
,
GDScriptFunction
*>::
Element
*
E
=
member_functions
.
front
();
E
;
E
=
E
->
next
())
{
for
(
Map
<
StringName
,
GDScriptFunction
*>::
Element
*
E
=
member_functions
.
front
();
E
;
E
=
E
->
next
())
{
memdelete
(
E
->
get
());
memdelete
(
E
->
get
());
}
}
for
(
Map
<
StringName
,
Ref
<
GDScript
>
>::
Element
*
E
=
subclasses
.
front
();
E
;
E
=
E
->
next
())
{
_save_orphaned_subclasses
();
E
->
get
()
->
_owner
=
NULL
;
//bye, you are no longer owned cause I died
}
#ifdef DEBUG_ENABLED
#ifdef DEBUG_ENABLED
if
(
GDScriptLanguage
::
get_singleton
()
->
lock
)
{
if
(
GDScriptLanguage
::
get_singleton
()
->
lock
)
{
...
@@ -2176,6 +2205,22 @@ GDScriptLanguage::~GDScriptLanguage() {
...
@@ -2176,6 +2205,22 @@ GDScriptLanguage::~GDScriptLanguage() {
singleton
=
NULL
;
singleton
=
NULL
;
}
}
void
GDScriptLanguage
::
add_orphan_subclass
(
const
String
&
p_qualified_name
,
const
ObjectID
&
p_subclass
)
{
orphan_subclasses
[
p_qualified_name
]
=
p_subclass
;
}
Ref
<
GDScript
>
GDScriptLanguage
::
get_orphan_subclass
(
const
String
&
p_qualified_name
)
{
Map
<
String
,
ObjectID
>::
Element
*
orphan_subclass_element
=
orphan_subclasses
.
find
(
p_qualified_name
);
if
(
!
orphan_subclass_element
)
return
Ref
<
GDScript
>
();
ObjectID
orphan_subclass
=
orphan_subclass_element
->
get
();
Object
*
obj
=
ObjectDB
::
get_instance
(
orphan_subclass
);
orphan_subclasses
.
erase
(
orphan_subclass_element
);
if
(
!
obj
)
return
Ref
<
GDScript
>
();
return
Ref
<
GDScript
>
(
Object
::
cast_to
<
GDScript
>
(
obj
));
}
/*************** RESOURCE ***************/
/*************** RESOURCE ***************/
RES
ResourceFormatLoaderGDScript
::
load
(
const
String
&
p_path
,
const
String
&
p_original_path
,
Error
*
r_error
)
{
RES
ResourceFormatLoaderGDScript
::
load
(
const
String
&
p_path
,
const
String
&
p_original_path
,
Error
*
r_error
)
{
...
...
modules/gdscript/gdscript.h
View file @
cd7b51b9
...
@@ -132,6 +132,8 @@ class GDScript : public Script {
...
@@ -132,6 +132,8 @@ class GDScript : public Script {
bool
_update_exports
();
bool
_update_exports
();
void
_save_orphaned_subclasses
();
protected
:
protected
:
bool
_get
(
const
StringName
&
p_name
,
Variant
&
r_ret
)
const
;
bool
_get
(
const
StringName
&
p_name
,
Variant
&
r_ret
)
const
;
bool
_set
(
const
StringName
&
p_name
,
const
Variant
&
p_value
);
bool
_set
(
const
StringName
&
p_name
,
const
Variant
&
p_value
);
...
@@ -355,6 +357,8 @@ class GDScriptLanguage : public ScriptLanguage {
...
@@ -355,6 +357,8 @@ class GDScriptLanguage : public ScriptLanguage {
bool
profiling
;
bool
profiling
;
uint64_t
script_frame_time
;
uint64_t
script_frame_time
;
Map
<
String
,
ObjectID
>
orphan_subclasses
;
public
:
public
:
int
calls
;
int
calls
;
...
@@ -506,6 +510,9 @@ public:
...
@@ -506,6 +510,9 @@ public:
virtual
bool
handles_global_class_type
(
const
String
&
p_type
)
const
;
virtual
bool
handles_global_class_type
(
const
String
&
p_type
)
const
;
virtual
String
get_global_class_name
(
const
String
&
p_path
,
String
*
r_base_type
=
NULL
,
String
*
r_icon_path
=
NULL
)
const
;
virtual
String
get_global_class_name
(
const
String
&
p_path
,
String
*
r_base_type
=
NULL
,
String
*
r_icon_path
=
NULL
)
const
;
void
add_orphan_subclass
(
const
String
&
p_qualified_name
,
const
ObjectID
&
p_subclass
);
Ref
<
GDScript
>
get_orphan_subclass
(
const
String
&
p_qualified_name
);
GDScriptLanguage
();
GDScriptLanguage
();
~
GDScriptLanguage
();
~
GDScriptLanguage
();
};
};
...
...
modules/gdscript/gdscript_compiler.cpp
View file @
cd7b51b9
...
@@ -2123,15 +2123,21 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C
...
@@ -2123,15 +2123,21 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C
StringName
name
=
p_class
->
subclasses
[
i
]
->
name
;
StringName
name
=
p_class
->
subclasses
[
i
]
->
name
;
Ref
<
GDScript
>
subclass
;
Ref
<
GDScript
>
subclass
;
String
fully_qualified_name
=
p_script
->
fully_qualified_name
+
"::"
+
name
;
if
(
old_subclasses
.
has
(
name
))
{
if
(
old_subclasses
.
has
(
name
))
{
subclass
=
old_subclasses
[
name
];
subclass
=
old_subclasses
[
name
];
}
else
{
}
else
{
subclass
.
instance
();
Ref
<
GDScript
>
orphan_subclass
=
GDScriptLanguage
::
get_singleton
()
->
get_orphan_subclass
(
fully_qualified_name
);
if
(
orphan_subclass
.
is_valid
())
{
subclass
=
orphan_subclass
;
}
else
{
subclass
.
instance
();
}
}
}
subclass
->
_owner
=
p_script
;
subclass
->
_owner
=
p_script
;
subclass
->
fully_qualified_name
=
p_script
->
fully_qualified_name
+
"::"
+
name
;
subclass
->
fully_qualified_name
=
fully_qualified_
name
;
p_script
->
subclasses
.
insert
(
name
,
subclass
);
p_script
->
subclasses
.
insert
(
name
,
subclass
);
_make_scripts
(
subclass
.
ptr
(),
p_class
->
subclasses
[
i
],
false
);
_make_scripts
(
subclass
.
ptr
(),
p_class
->
subclasses
[
i
],
false
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment