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
86aa12e8
Commit
86aa12e8
authored
Jan 14, 2020
by
ChibiDenDen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Keep a weak reference to orphan subclasses to reuse on class reload
parent
3d88a7bb
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 @
86aa12e8
...
...
@@ -915,14 +915,43 @@ GDScript::GDScript() :
#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
()
{
for
(
Map
<
StringName
,
GDScriptFunction
*>::
Element
*
E
=
member_functions
.
front
();
E
;
E
=
E
->
next
())
{
memdelete
(
E
->
get
());
}
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
}
_save_orphaned_subclasses
();
#ifdef DEBUG_ENABLED
if
(
GDScriptLanguage
::
get_singleton
()
->
lock
)
{
...
...
@@ -2176,6 +2205,22 @@ GDScriptLanguage::~GDScriptLanguage() {
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 ***************/
RES
ResourceFormatLoaderGDScript
::
load
(
const
String
&
p_path
,
const
String
&
p_original_path
,
Error
*
r_error
)
{
...
...
modules/gdscript/gdscript.h
View file @
86aa12e8
...
...
@@ -132,6 +132,8 @@ class GDScript : public Script {
bool
_update_exports
();
void
_save_orphaned_subclasses
();
protected
:
bool
_get
(
const
StringName
&
p_name
,
Variant
&
r_ret
)
const
;
bool
_set
(
const
StringName
&
p_name
,
const
Variant
&
p_value
);
...
...
@@ -355,6 +357,8 @@ class GDScriptLanguage : public ScriptLanguage {
bool
profiling
;
uint64_t
script_frame_time
;
Map
<
String
,
ObjectID
>
orphan_subclasses
;
public
:
int
calls
;
...
...
@@ -506,6 +510,9 @@ public:
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
;
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
();
};
...
...
modules/gdscript/gdscript_compiler.cpp
View file @
86aa12e8
...
...
@@ -2123,15 +2123,21 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C
StringName
name
=
p_class
->
subclasses
[
i
]
->
name
;
Ref
<
GDScript
>
subclass
;
String
fully_qualified_name
=
p_script
->
fully_qualified_name
+
"::"
+
name
;
if
(
old_subclasses
.
has
(
name
))
{
subclass
=
old_subclasses
[
name
];
}
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
->
fully_qualified_name
=
p_script
->
fully_qualified_name
+
"::"
+
name
;
subclass
->
fully_qualified_name
=
fully_qualified_
name
;
p_script
->
subclasses
.
insert
(
name
,
subclass
);
_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