You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Add C# source generator for a new ScriptPath attribute
This source generator adds a newly introduced attribute,
`ScriptPath` to all classes that:
- Are top-level classes (not inner/nested).
- Have the `partial` modifier.
- Inherit `Godot.Object`.
- The class name matches the file name.
A build error is thrown if the generator finds a class that meets these
conditions but is not declared `partial`, unless the class is annotated
with the `DisableGodotGenerators` attribute.
We also generate an `AssemblyHasScripts` assembly attribute which Godot
uses to get all the script classes in the assembly, eliminating the need
for Godot to search them. We can also avoid searching in assemblies that
don't have this attribute. This will be good for performance in the
future once we support multiple assemblies with Godot script classes.
This is an example of what the generated code looks like:
```
using Godot;
namespace Foo {
[ScriptPathAttribute("res://Player.cs")]
// Multiple partial declarations are allowed
[ScriptPathAttribute("res://Foo/Player.cs")]
partial class Player {}
}
[assembly:AssemblyHasScripts(new System.Type[] { typeof(Foo.Player) })]
```
The new attributes replace script metadata which we were generating by
determining the namespace of script classes with a very simple parser.
This fixes several issues with the old approach related to parser
errors and conditional compilation.
It also makes the task part of the MSBuild project build, rather than
a separate step executed by the Godot editor.
This commit is contained in:
@@ -66,6 +66,18 @@ TScriptInstance *cast_script_instance(ScriptInstance *p_inst) {
|
||||
|
||||
#define CAST_CSHARP_INSTANCE(m_inst) (cast_script_instance<CSharpInstance, CSharpLanguage>(m_inst))
|
||||
|
||||
struct DotNetScriptLookupInfo {
|
||||
String class_namespace;
|
||||
String class_name;
|
||||
GDMonoClass *script_class = nullptr;
|
||||
|
||||
DotNetScriptLookupInfo() {} // Required by HashMap...
|
||||
|
||||
DotNetScriptLookupInfo(const String &p_class_namespace, const String &p_class_name, GDMonoClass *p_script_class) :
|
||||
class_namespace(p_class_namespace), class_name(p_class_name), script_class(p_script_class) {
|
||||
}
|
||||
};
|
||||
|
||||
class CSharpScript : public Script {
|
||||
GDCLASS(CSharpScript, Script);
|
||||
|
||||
@@ -390,16 +402,15 @@ class CSharpLanguage : public ScriptLanguage {
|
||||
|
||||
int lang_idx = -1;
|
||||
|
||||
Dictionary scripts_metadata;
|
||||
bool scripts_metadata_invalidated = true;
|
||||
HashMap<String, DotNetScriptLookupInfo> dotnet_script_lookup_map;
|
||||
|
||||
void lookup_script_for_class(GDMonoClass *p_class);
|
||||
|
||||
// For debug_break and debug_break_parse
|
||||
int _debug_parse_err_line = -1;
|
||||
String _debug_parse_err_file;
|
||||
String _debug_error;
|
||||
|
||||
void _load_scripts_metadata();
|
||||
|
||||
friend class GDMono;
|
||||
void _on_scripts_domain_unloaded();
|
||||
|
||||
@@ -436,19 +447,14 @@ public:
|
||||
void reload_assemblies(bool p_soft_reload);
|
||||
#endif
|
||||
|
||||
_FORCE_INLINE_ Dictionary get_scripts_metadata_or_nothing() {
|
||||
return scripts_metadata_invalidated ? Dictionary() : scripts_metadata;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
|
||||
if (scripts_metadata_invalidated) {
|
||||
_load_scripts_metadata();
|
||||
}
|
||||
return scripts_metadata;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
|
||||
|
||||
void lookup_scripts_in_assembly(GDMonoAssembly *p_assembly);
|
||||
|
||||
const DotNetScriptLookupInfo *lookup_dotnet_script(const String &p_script_path) const {
|
||||
return dotnet_script_lookup_map.getptr(p_script_path);
|
||||
}
|
||||
|
||||
String get_name() const override;
|
||||
|
||||
/* LANGUAGE FUNCTIONS */
|
||||
|
||||
Reference in New Issue
Block a user