2023-01-05 13:25:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  bindings_generator.cpp                                                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                         This file is part of:                          */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                             GODOT ENGINE                               */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                        https://godotengine.org                         */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* a copy of this software and associated documentation files (the        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* "Software"), to deal in the Software without restriction, including    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* the following conditions:                                              */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The above copyright notice and this permission notice shall be         */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* included in all copies or substantial portions of the Software.        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2018-01-05 00:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "bindings_generator.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-28 01:07:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-13 16:56:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "../godotsharp_defs.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../utils/naming_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../utils/path_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../utils/string_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/config/engine.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/core_constants.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-09-11 18:13:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/io/compression.h" 
  
						 
					
						
							
								
									
										
										
										
											2021-06-11 14:51:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/io/dir_access.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/io/file_access.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-09-11 18:13:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/os/os.h" 
  
						 
					
						
							
								
									
										
										
										
											2021-02-22 11:06:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "main/main.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringBuilder  & operator < < ( StringBuilder  & r_sb ,  const  String  & p_string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_sb . append ( p_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  r_sb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								StringBuilder  & operator < < ( StringBuilder  & r_sb ,  const  char  * p_cstring )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_sb . append ( p_cstring ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  r_sb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_INDENT "    "  // 4 whitespaces
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define INDENT1 CS_INDENT 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define INDENT2 INDENT1 INDENT1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define INDENT3 INDENT2 INDENT1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define INDENT4 INDENT3 INDENT1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define MEMBER_BEGIN "\n" INDENT1 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define OPEN_BLOCK "{\n" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define CLOSE_BLOCK "}\n" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define OPEN_BLOCK_L1 INDENT1 OPEN_BLOCK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK 
  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CLOSE_BLOCK_L1 INDENT1 CLOSE_BLOCK 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define BINDINGS_GLOBAL_SCOPE_CLASS "GD" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define BINDINGS_NATIVE_NAME_FIELD "NativeName" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_PARAM_MEMORYOWN "memoryOwn" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define CS_PARAM_METHODBIND "method" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define CS_PARAM_INSTANCE "ptr" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_STATIC_METHOD_GETINSTANCE "GetPtr" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define CS_METHOD_CALL "Call" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_PROPERTY_SINGLETON "Singleton" 
  
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_SINGLETON_INSTANCE_SUFFIX "Instance" 
  
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_METHOD_INVOKE_GODOT_CLASS_METHOD "InvokeGodotClassMethod" 
  
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_METHOD_HAS_GODOT_CLASS_METHOD "HasGodotClassMethod" 
  
						 
					
						
							
								
									
										
										
										
											2023-01-13 20:59:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_METHOD_HAS_GODOT_CLASS_SIGNAL "HasGodotClassSignal" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define CS_STATIC_FIELD_NATIVE_CTOR "NativeCtor" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define CS_STATIC_FIELD_METHOD_BIND_PREFIX "MethodBind" 
  
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX "MethodProxyName_" 
  
						 
					
						
							
								
									
										
										
										
											2023-01-13 20:59:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX "SignalProxyName_" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ICALL_PREFIX "godot_icall_" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define ICALL_CLASSDB_GET_METHOD "ClassDB_get_method" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ICALL_CLASSDB_GET_CONSTRUCTOR "ClassDB_get_constructor" 
  
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_LOCAL_RET "ret" 
  
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define C_LOCAL_VARARG_RET "vararg_ret" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define C_LOCAL_PTRCALL_ARGS "call_args" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_CLASS_NATIVE_FUNCS "NativeFuncs" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_NS_MONOUTILS "InteropUtils" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_UNMANAGED_GET_MANAGED C_NS_MONOUTILS ".UnmanagedGetManaged" 
  
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define C_METHOD_ENGINE_GET_SINGLETON C_NS_MONOUTILS ".EngineGetSingleton" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_NS_MONOMARSHAL "Marshaling" 
  
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define C_METHOD_MONOSTR_TO_GODOT C_NS_MONOMARSHAL ".ConvertStringToNative" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MONOSTR_FROM_GODOT C_NS_MONOMARSHAL ".ConvertStringToManaged" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL ".ConvertSystemArrayToNative" #m_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL ".ConvertNative" #m_type "ToSystemArray" 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define C_METHOD_MANAGED_TO_CALLABLE C_NS_MONOMARSHAL ".ConvertCallableToNative" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MANAGED_FROM_CALLABLE C_NS_MONOMARSHAL ".ConvertCallableToManaged" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL ".ConvertSignalToNative" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL ".ConvertSignalToManaged" 
  
						 
					
						
							
								
									
										
										
										
											2018-02-22 13:13:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 17:28:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Types that will be ignored by the generator and won't be available in C#.
  
						 
					
						
							
								
									
										
										
										
											2023-04-12 00:35:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// This must be kept in sync with `ignored_types` in csharp_script.cpp
  
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  Vector < String >  ignored_types  =  { } ;  
						 
					
						
							
								
									
										
										
										
											2022-03-18 17:28:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : TypeInterface : : postsetup_enum_type ( BindingsGenerator : : TypeInterface  & r_enum_itype )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// C interface for enums is the same as that of 'uint32_t'. Remember to apply
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// any of the changes done here to the 'uint32_t' type interface as well.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_enum_itype . cs_type  =  r_enum_itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_enum_itype . cs_in_expr  =  " (int)%0 " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_enum_itype . cs_out  =  " %5return (%2)%0(%1); " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r_enum_itype . c_in  =  " %5%0 %1_in = %1; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 21:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_enum_itype . c_out  =  " %5return (%0)(%1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_enum_itype . c_type  =  " long " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r_enum_itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_enum_itype . c_type_in  =  " int " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_enum_itype . c_type_out  =  r_enum_itype . c_type_in ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_enum_itype . class_doc  =  & EditorHelp : : get_doc_data ( ) - > class_list [ r_enum_itype . proxy_name ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  fix_doc_description ( const  String  & p_bbcode )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This seems to be the correct way to do this. It's the same EditorHelp does.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p_bbcode . dedent ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. replace ( " \t " ,  " " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. replace ( " \r " ,  " " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  BindingsGenerator : : bbcode_to_xml ( const  String  & p_bbcode ,  const  TypeInterface  * p_itype )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Based on the version in EditorHelp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_bbcode . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 09:12:06 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DocTools  * doc  =  EditorHelp : : get_doc_data ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  bbcode  =  p_bbcode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StringBuilder  xml_output ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xml_output . append ( " <para> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									List < String >  tag_stack ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  code_tag  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  line_del  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( pos  <  bbcode . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  brk_pos  =  bbcode . find ( " [ " ,  pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( brk_pos  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											brk_pos  =  bbcode . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( brk_pos  >  pos )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! line_del )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  text  =  bbcode . substr ( pos ,  brk_pos  -  pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( code_tag  | |  tag_stack . size ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( text . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Vector < String >  lines  =  text . split ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													for  ( int  i  =  0 ;  i  <  lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															xml_output . append ( " <para> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														xml_output . append ( lines [ i ] . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( i  ! =  lines . size ( )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															xml_output . append ( " </para> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( brk_pos  = =  bbcode . length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ;  // nothing else to add
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  brk_end  =  bbcode . find ( " ] " ,  brk_pos  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( brk_end  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! line_del )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  text  =  bbcode . substr ( brk_pos ,  bbcode . length ( )  -  brk_pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( code_tag  | |  tag_stack . size ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( text . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Vector < String >  lines  =  text . split ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													for  ( int  i  =  0 ;  i  <  lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															xml_output . append ( " <para> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														xml_output . append ( lines [ i ] . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( i  ! =  lines . size ( )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															xml_output . append ( " </para> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  tag  =  bbcode . substr ( brk_pos  +  1 ,  brk_end  -  brk_pos  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tag . begins_with ( " / " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  tag_ok  =  tag_stack . size ( )  & &  tag_stack . front ( ) - > get ( )  = =  tag . substr ( 1 ,  tag . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! tag_ok )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! line_del )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( " [ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pos  =  brk_pos  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											code_tag  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( tag  = =  " /url " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </a> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /code " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /codeblock " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </code> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /b " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </b> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /i " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </i> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /csharp " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </code> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												line_del  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " /codeblocks " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												line_del  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( code_tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " [ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_pos  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( tag . begins_with ( " method  " )  | |  tag . begins_with ( " member  " )  | |  tag . begins_with ( " signal  " )  | |  tag . begins_with ( " enum  " )  | |  tag . begins_with ( " constant  " )  | |  tag . begins_with ( " theme_item  " )  | |  tag . begins_with ( " param  " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 19:01:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  int  tag_end  =  tag . find ( "   " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  String  link_tag  =  tag . substr ( 0 ,  tag_end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  String  link_target  =  tag . substr ( tag_end  +  1 ,  tag . length ( ) ) . lstrip ( "   " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  Vector < String >  link_target_parts  =  link_target . split ( " . " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( link_target_parts . size ( )  < =  0  | |  link_target_parts . size ( )  >  2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_PRINT ( " Invalid reference format: ' "  +  tag  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  TypeInterface  * target_itype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											StringName  target_cname ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( link_target_parts . size ( )  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_itype  =  _get_type_or_null ( TypeReference ( link_target_parts [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! target_itype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													target_itype  =  _get_type_or_null ( TypeReference ( " _ "  +  link_target_parts [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_cname  =  link_target_parts [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_itype  =  p_itype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_cname  =  link_target_parts [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( link_tag  = =  " method " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_method ( xml_output ,  target_itype ,  target_cname ,  link_target ,  link_target_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " member " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_member ( xml_output ,  target_itype ,  target_cname ,  link_target ,  link_target_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " signal " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_signal ( xml_output ,  target_itype ,  target_cname ,  link_target ,  link_target_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " enum " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_enum ( xml_output ,  target_itype ,  target_cname ,  link_target ,  link_target_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 21:17:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " constant " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_constant ( xml_output ,  target_itype ,  target_cname ,  link_target ,  link_target_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:24:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " theme_item " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We do not declare theme_items in any way in C#, so there is nothing to reference
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_undeclared ( xml_output ,  link_target ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( link_tag  = =  " param " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_append_xml_undeclared ( xml_output ,  snake_to_camel_case ( link_target ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( doc - > class_list . has ( tag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( tag  = =  " Array "  | |  tag  = =  " Dictionary " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE_COLLECTIONS  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " bool "  | |  tag  = =  " int " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " float " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef REAL_T_IS_DOUBLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  " double " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  " float " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " Variant " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" Godot.Variant \" /> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " String " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" string \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " Nil " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <see langword= \" null \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( tag . begins_with ( " @ " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-27 20:01:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// @GlobalScope, @GDScript, etc
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " </c> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedByteArray " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" byte \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											 
										 
										
											2020-02-24 15:20:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedInt32Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" int \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedInt64Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" long \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											 
										 
										
											2020-02-24 15:20:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedFloat32Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" float \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedFloat64Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" double \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedStringArray " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" string \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedVector2Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " .Vector2 \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedVector3Array " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " .Vector3 \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tag  = =  " PackedColorArray " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " .Color \" />[] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  TypeInterface  * target_itype  =  _get_type_or_null ( TypeReference ( tag ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! target_itype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													target_itype  =  _get_type_or_null ( TypeReference ( " _ "  +  tag ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( target_itype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ERR_PRINT ( " Cannot resolve type reference in documentation: ' "  +  tag  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( " <c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( " </c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " b " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											xml_output . append ( " <b> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " i " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											xml_output . append ( " <i> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " code " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " <c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											code_tag  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " codeblock " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " <code> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											code_tag  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " codeblocks " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											line_del  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " csharp " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " <code> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											line_del  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											code_tag  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 13:41:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " kbd " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// keyboard combinations are not supported in xml comments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " center " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 13:41:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// center alignment is not supported in xml comments
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " br " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " \n " ) ;  // FIXME: Should use <para> instead. Luckily this tag isn't used for now.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " u " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// underline is not supported in Rider xml comments
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " s " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// strikethrough is not supported in xml comments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " url " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  end  =  bbcode . find ( " [ " ,  brk_end ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( end  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												end  =  bbcode . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  url  =  bbcode . substr ( brk_end  +  1 ,  end  -  brk_end  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " <a href= \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( url ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " \" > " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( url ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag . begins_with ( " url= " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  url  =  tag . substr ( 4 ,  tag . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " <a href= \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( url ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " \" > " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( " url " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " img " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  end  =  bbcode . find ( " [ " ,  brk_end ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( end  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												end  =  bbcode . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  image  =  bbcode . substr ( brk_end  +  1 ,  end  -  brk_end  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Not supported. Just append the bbcode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " [img] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( image ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " [/img] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag . begins_with ( " color= " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Not supported.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( " color " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag . begins_with ( " font= " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Not supported.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( " font " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 18:40:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! line_del )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " [ " ) ;  // ignore
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pos  =  brk_pos  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xml_output . append ( " </para> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  xml_output . as_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_method ( StringBuilder  & p_xml_output ,  const  TypeInterface  * p_target_itype ,  const  StringName  & p_target_cname ,  const  String  & p_link_target ,  const  Vector < String >  & p_link_target_parts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_link_target_parts [ 0 ]  = =  name_cache . type_at_GlobalScope )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											OS : : get_singleton ( ) - > print ( " Cannot resolve @GlobalScope method reference in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO Map what we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! p_target_itype  | |  ! p_target_itype - > is_object_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_target_itype )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve method reference for non-GodotObject type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve type from method reference in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO Map what we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_target_cname  = =  " _init " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The _init method is not declared in C#, reference the constructor instead
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " () \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  MethodInterface  * target_imethod  =  p_target_itype - > find_method_by_name ( p_target_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( target_imethod )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( target_imethod - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! p_target_itype - > is_intentionally_ignored ( p_link_target ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ERR_PRINT ( " Cannot resolve method reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_member ( StringBuilder  & p_xml_output ,  const  TypeInterface  * p_target_itype ,  const  StringName  & p_target_cname ,  const  String  & p_link_target ,  const  Vector < String >  & p_link_target_parts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_link_target . find ( " / " )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! p_target_itype  | |  ! p_target_itype - > is_object_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_target_itype )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve member reference for non-GodotObject type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve type from member reference in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO Map what we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  TypeInterface  * current_itype  =  p_target_itype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  PropertyInterface  * target_iprop  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( target_iprop  = =  nullptr  & &  current_itype  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											target_iprop  =  current_itype - > find_property_by_name ( p_target_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( target_iprop  = =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												current_itype  =  _get_type_or_null ( TypeReference ( current_itype - > base_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( target_iprop )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( current_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( target_iprop - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! p_target_itype - > is_intentionally_ignored ( p_link_target ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_PRINT ( " Cannot resolve member reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_signal ( StringBuilder  & p_xml_output ,  const  TypeInterface  * p_target_itype ,  const  StringName  & p_target_cname ,  const  String  & p_link_target ,  const  Vector < String >  & p_link_target_parts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p_target_itype  | |  ! p_target_itype - > is_object_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_target_itype )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve signal reference for non-GodotObject type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve type from signal reference in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO Map what we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  SignalInterface  * target_isignal  =  p_target_itype - > find_signal_by_name ( p_target_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( target_isignal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( target_isignal - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! p_target_itype - > is_intentionally_ignored ( p_link_target ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_PRINT ( " Cannot resolve signal reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_enum ( StringBuilder  & p_xml_output ,  const  TypeInterface  * p_target_itype ,  const  StringName  & p_target_cname ,  const  String  & p_link_target ,  const  Vector < String >  & p_link_target_parts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  StringName  search_cname  =  ! p_target_itype  ?  p_target_cname  :  StringName ( p_target_itype - > name  +  " . "  +  ( String ) p_target_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HashMap < StringName ,  TypeInterface > : : ConstIterator  enum_match  =  enum_types . find ( search_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! enum_match  & &  search_cname  ! =  p_target_cname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										enum_match  =  enum_types . find ( p_target_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( enum_match )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  & target_enum_itype  =  enum_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( target_enum_itype . proxy_name ) ;  // Includes nesting class if any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! p_target_itype - > is_intentionally_ignored ( p_link_target ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_PRINT ( " Cannot resolve enum reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_constant ( StringBuilder  & p_xml_output ,  const  TypeInterface  * p_target_itype ,  const  StringName  & p_target_cname ,  const  String  & p_link_target ,  const  Vector < String >  & p_link_target_parts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_link_target_parts [ 0 ]  = =  name_cache . type_at_GlobalScope )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_constant_in_global_scope ( p_xml_output ,  p_target_cname ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! p_target_itype  | |  ! p_target_itype - > is_object_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Search in @GlobalScope as a last resort if no class was specified
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_link_target_parts . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_append_xml_constant_in_global_scope ( p_xml_output ,  p_target_cname ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( OS : : get_singleton ( ) - > is_stdout_verbose ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_target_itype )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve constant reference for non-GodotObject type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve type from constant reference in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO Map what we can
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Try to find the constant in the current class
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_target_itype - > is_singleton_instance )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Constants and enums are declared in the static singleton class.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_target_itype  =  & obj_types [ p_target_itype - > cname ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  ConstantInterface  * target_iconst  =  find_constant_by_name ( p_target_cname ,  p_target_itype - > constants ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Found constant in current class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( target_iconst - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Try to find as enum constant in the current class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  EnumInterface  * target_ienum  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( const  EnumInterface  & ienum  :  p_target_itype - > enums )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_ienum  =  & ienum ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												target_iconst  =  find_constant_by_name ( p_target_cname ,  target_ienum - > constants ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( p_target_itype - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( target_ienum - > cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( target_iconst - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p_link_target_parts . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Also search in @GlobalScope as a last resort if no class was specified
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_append_xml_constant_in_global_scope ( p_xml_output ,  p_target_cname ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! p_target_itype - > is_intentionally_ignored ( p_link_target ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ERR_PRINT ( " Cannot resolve constant reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-03 23:35:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_constant_in_global_scope ( StringBuilder  & p_xml_output ,  const  String  & p_target_cname ,  const  String  & p_link_target )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Try to find as a global constant
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  ConstantInterface  * target_iconst  =  find_constant_by_name ( p_target_cname ,  global_constants ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Found global constant
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . "  BINDINGS_GLOBAL_SCOPE_CLASS  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( target_iconst - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Try to find as global enum constant
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  EnumInterface  * target_ienum  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  EnumInterface  & ienum  :  global_enums )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											target_ienum  =  & ienum ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											target_iconst  =  find_constant_by_name ( p_target_cname ,  target_ienum - > constants ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( target_iconst )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( target_ienum - > cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( target_iconst - > proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_xml_output . append ( " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_PRINT ( " Cannot resolve global constant reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_append_xml_undeclared ( p_xml_output ,  p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _append_xml_undeclared ( StringBuilder  & p_xml_output ,  const  String  & p_link_target )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_xml_output . append ( " <c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_xml_output . append ( p_link_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_xml_output . append ( " </c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  BindingsGenerator : : _determine_enum_prefix ( const  EnumInterface  & p_ienum )  {  
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CRASH_COND ( p_ienum . constants . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  ConstantInterface  & front_iconstant  =  p_ienum . constants . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < String >  front_parts  =  front_iconstant . name . split ( " _ " ,  /* p_allow_empty: */  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  candidate_len  =  front_parts . size ( )  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( candidate_len  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-26 21:31:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  ConstantInterface  & iconstant  :  p_ienum . constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector < String >  parts  =  iconstant . name . split ( " _ " ,  /* p_allow_empty: */  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  candidate_len  & &  i  <  parts . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( front_parts [ i ]  ! =  parts [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// HARDCODED: Some Flag enums have the prefix 'FLAG_' for everything except 'FLAGS_DEFAULT' (same for 'METHOD_FLAG_' and'METHOD_FLAGS_DEFAULT').
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  hardcoded_exc  =  ( i  = =  candidate_len  -  1  & &  ( ( front_parts [ i ]  = =  " FLAGS "  & &  parts [ i ]  = =  " FLAG " )  | |  ( front_parts [ i ]  = =  " FLAG "  & &  parts [ i ]  = =  " FLAGS " ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! hardcoded_exc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										candidate_len  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( candidate_len  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  candidate_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _apply_prefix_to_enum_constants ( BindingsGenerator : : EnumInterface  & p_ienum ,  int  p_prefix_length )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_prefix_length  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( ConstantInterface  & iconstant  :  p_ienum . constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  curr_prefix_length  =  p_prefix_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  constant_name  =  iconstant . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < String >  parts  =  constant_name . split ( " _ " ,  /* p_allow_empty: */  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( parts . size ( )  < =  curr_prefix_length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 10:32:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( is_digit ( parts [ curr_prefix_length ] [ 0 ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// The name of enum constants may begin with a numeric digit when strip from the enum prefix,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so we make the prefix for this constant one word shorter in those cases.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( curr_prefix_length  =  curr_prefix_length  -  1 ;  curr_prefix_length  >  0 ;  curr_prefix_length - - )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 10:32:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! is_digit ( parts [ curr_prefix_length ] [ 0 ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											constant_name  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  curr_prefix_length ;  i  <  parts . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( i  >  curr_prefix_length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													constant_name  + =  " _ " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												constant_name  + =  parts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											iconstant . proxy_name  =  snake_to_pascal_case ( constant_name ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _populate_method_icalls_table ( const  TypeInterface  & p_itype )  {  
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  MethodInterface  & imethod  :  p_itype . methods )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( imethod . is_virtual )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  * return_type  =  _get_type_or_null ( imethod . return_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( return_type ,  ERR_BUG ) ;  // Return type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  im_unique_sig  =  get_ret_unique_sig ( return_type )  +  " ,CallMethodBind " ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-25 23:44:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! imethod . is_static )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											im_unique_sig  + =  " ,CallInstance " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Get arguments information
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  ArgumentInterface  & iarg  :  imethod . arguments )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  TypeInterface  * arg_type  =  _get_type_or_null ( iarg . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Argument type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											im_unique_sig  + =  " , " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											im_unique_sig  + =  get_arg_unique_sig ( * arg_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// godot_icall_{argc}_{icallcount}
 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-25 23:44:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  icall_method  =  ICALL_PREFIX ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										icall_method  + =  itos ( imethod . arguments . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										icall_method  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										icall_method  + =  itos ( method_icalls . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										InternalCall  im_icall  =  InternalCall ( p_itype . api_type ,  icall_method ,  im_unique_sig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										im_icall . is_vararg  =  imethod . is_vararg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										im_icall . is_static  =  imethod . is_static ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										im_icall . return_type  =  imethod . return_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  List < ArgumentInterface > : : Element  * F  =  imethod . arguments . front ( ) ;  F ;  F  =  F - > next ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											im_icall . argument_types . push_back ( F - > get ( ) . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										List < InternalCall > : : Element  * match  =  method_icalls . find ( im_icall ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( match )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p_itype . api_type  ! =  ClassDB : : API_EDITOR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												match - > get ( ) . editor_only  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											method_icalls_map . insert ( & imethod ,  & match - > get ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											List < InternalCall > : : Element  * added  =  method_icalls . push_back ( im_icall ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											method_icalls_map . insert ( & imethod ,  & added - > get ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _generate_array_extensions ( StringBuilder  & p_output )  {  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " namespace  "  BINDINGS_NAMESPACE  " ; \n \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " using System; \n \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The class where we put the extensions doesn't matter, so just use "GD".
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " public static partial class  "  BINDINGS_GLOBAL_SCOPE_CLASS  " \n { " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ARRAY_IS_EMPTY(m_type)                                                                          \ 
  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n "  INDENT1  " /// <summary> \n " ) ;                                                     \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// Returns true if this  "  # m_type  "  array is empty or doesn't exist. \n " ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// </summary> \n " ) ;                                                         \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <param name= \" instance \" >The  "  # m_type  "  array check.</param> \n " ) ;      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <returns>Whether or not the array is empty.</returns> \n " ) ;              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " public static bool IsEmpty(this  "  # m_type  " [] instance) \n " ) ;                \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( OPEN_BLOCK_L1 ) ;                                                                      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT2  " return instance == null || instance.Length == 0; \n " ) ;                       \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ARRAY_JOIN(m_type)                                                                                          \ 
  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n "  INDENT1  " /// <summary> \n " ) ;                                                                 \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// Converts this  "  # m_type  "  array to a string delimited by the given string. \n " ) ;     \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// </summary> \n " ) ;                                                                     \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <param name= \" instance \" >The  "  # m_type  "  array to convert.</param> \n " ) ;             \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <param name= \" delimiter \" >The delimiter to use between items.</param> \n " ) ;          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <returns>A single string with all items.</returns> \n " ) ;                             \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " public static string Join(this  "  # m_type  " [] instance, string delimiter =  \" ,  \" ) \n " ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( OPEN_BLOCK_L1 ) ;                                                                                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT2  " return String.Join(delimiter, instance); \n " ) ;                                           \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ARRAY_STRINGIFY(m_type)                                                                          \ 
  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n "  INDENT1  " /// <summary> \n " ) ;                                                      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// Converts this  "  # m_type  "  array to a string with brackets. \n " ) ;          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// </summary> \n " ) ;                                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <param name= \" instance \" >The  "  # m_type  "  array to convert.</param> \n " ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " /// <returns>A single string with all items.</returns> \n " ) ;                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  " public static string Stringify(this  "  # m_type  " [] instance) \n " ) ;             \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( OPEN_BLOCK_L1 ) ;                                                                       \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT2  " return  \" [ \"  + instance.Join() +  \" ] \" ; \n " ) ;                                 \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( INDENT1  CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ARRAY_ALL(m_type)  \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_IS_EMPTY ( m_type )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_JOIN ( m_type )      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_STRINGIFY ( m_type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( byte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( int ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( long ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( float ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( double ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( Color ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector2I ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector3I ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
											 
										 
										
											2022-07-20 01:11:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector4 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector4I ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef ARRAY_ALL 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef ARRAY_IS_EMPTY 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef ARRAY_JOIN 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef ARRAY_STRINGIFY 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( CLOSE_BLOCK ) ;  // End of GD class.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _generate_global_constants ( StringBuilder  & p_output )  {  
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Constants (in partial GD class)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " namespace  "  BINDINGS_NAMESPACE  " ; \n \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n #pragma warning disable CS1591 // Disable warning:  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" 'Missing XML comment for publicly visible type or member' \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " public static partial class  "  BINDINGS_GLOBAL_SCOPE_CLASS  " \n { " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  ConstantInterface  & iconstant  :  global_constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( iconstant . const_doc  & &  iconstant . const_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( iconstant . const_doc - > description ) ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( MEMBER_BEGIN  " public const long  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( iconstant . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( "  =  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( itos ( iconstant . value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( " ; " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! global_constants . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( CLOSE_BLOCK ) ;  // end of GD class
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Enums
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 15:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  EnumInterface  & ienum  :  global_enums )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CRASH_COND ( ienum . constants . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  enum_proxy_name  =  ienum . cname . operator  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  enum_in_static_class  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( enum_proxy_name . find ( " . " )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_in_static_class  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  enum_class_name  =  enum_proxy_name . get_slicec ( ' . ' ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_proxy_name  =  enum_proxy_name . get_slicec ( ' . ' ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CRASH_COND ( enum_class_name  ! =  " Variant " ) ;  // Hard-coded...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_log ( " Declaring global enum '%s' inside struct '%s' \n " ,  enum_proxy_name . utf8 ( ) . get_data ( ) ,  enum_class_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " \n public partial struct  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( pascal_to_pascal_case ( enum_class_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " \n "  OPEN_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 20:25:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ienum . is_flags )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " \n [System.Flags] " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 20:25:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " \n public enum  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( pascal_to_pascal_case ( enum_proxy_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( "  : long " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " \n "  OPEN_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  ConstantInterface  & last  =  ienum . constants . back ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  ConstantInterface  & iconstant  :  ienum . constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iconstant . const_doc  & &  iconstant . const_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( iconstant . const_doc - > description ) ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( INDENT1  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p_output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( INDENT1  " /// </summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( INDENT1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( iconstant . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( "  =  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( itos ( iconstant . value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( & iconstant  ! =  & last  ?  " , \n "  :  " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( enum_in_static_class )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n #pragma warning restore CS1591 \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : generate_cs_core_project ( const  String  & p_proj_dir )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! initialized ,  ERR_UNCONFIGURED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 11:08:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Ref < DirAccess >  da  =  DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( da . is_null ( ) ,  ERR_CANT_CREATE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! DirAccess : : exists ( p_proj_dir ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  da - > make_dir_recursive ( p_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 10:28:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( err  ! =  OK ,  ERR_CANT_CREATE ,  " Cannot create directory ' "  +  p_proj_dir  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									da - > change_dir ( p_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									da - > make_dir ( " Generated " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									da - > make_dir ( " Generated/GodotObjects " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  base_gen_dir  =  path : : join ( p_proj_dir ,  " Generated " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  godot_objects_gen_dir  =  path : : join ( base_gen_dir ,  " GodotObjects " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < String >  compile_items ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate source file for global scope constants and enums
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										StringBuilder  constants_source ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_generate_global_constants ( constants_source ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  output_file  =  path : : join ( base_gen_dir ,  BINDINGS_GLOBAL_SCOPE_CLASS  " _constants.cs " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  save_err  =  _save_file ( output_file ,  constants_source ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( save_err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  save_err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										compile_items . push_back ( output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 05:17:39 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate source file for array extensions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StringBuilder  extensions_source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_generate_array_extensions ( extensions_source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  output_file  =  path : : join ( base_gen_dir ,  BINDINGS_GLOBAL_SCOPE_CLASS  " _extensions.cs " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  save_err  =  _save_file ( output_file ,  extensions_source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( save_err  ! =  OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  save_err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										compile_items . push_back ( output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  KeyValue < StringName ,  TypeInterface >  & E  :  obj_types )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  TypeInterface  & itype  =  E . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( itype . api_type  = =  ClassDB : : API_EDITOR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  output_file  =  path : : join ( godot_objects_gen_dir ,  itype . proxy_name  +  " .cs " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 19:06:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  err  =  _generate_cs_type ( itype ,  output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  = =  ERR_SKIP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										compile_items . push_back ( output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate native calls
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  cs_icalls_content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " namespace  "  BINDINGS_NAMESPACE  " ; \n \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " using System; \n " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 " using System.Diagnostics.CodeAnalysis; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " using System.Runtime.InteropServices; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " using Godot.NativeInterop; \n " 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" InconsistentNaming \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" RedundantUnsafeContext \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" RedundantNameQualifier \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [System.Runtime.CompilerServices.SkipLocalsInit] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " internal static class  "  BINDINGS_CLASS_NATIVECALLS  " \n { " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( MEMBER_BEGIN  " internal static ulong godot_api_hash =  " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( String : : num_uint64 ( ClassDB : : get_api_hash ( ClassDB : : API_CORE ) )  +  " ; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( MEMBER_BEGIN  " private const int VarArgsSpanThreshold = 10; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  InternalCall  & icall  :  method_icalls )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( icall . editor_only )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  _generate_cs_native_calls ( icall ,  cs_icalls_content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  internal_methods_file  =  path : : join ( base_gen_dir ,  BINDINGS_CLASS_NATIVECALLS  " .cs " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Error  err  =  _save_file ( internal_methods_file ,  cs_icalls_content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									compile_items . push_back ( internal_methods_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate GeneratedIncludes.props
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  includes_props_content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									includes_props_content . append ( " <Project> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  "   <ItemGroup> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  compile_items . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  include  =  path : : relative_to ( compile_items [ i ] ,  p_proj_dir ) . replace ( " / " ,  " \\ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										includes_props_content . append ( "     <Compile Include= \" "  +  include  +  " \"  /> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									includes_props_content . append ( "   </ItemGroup> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  " </Project> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  includes_props_file  =  path : : join ( base_gen_dir ,  " GeneratedIncludes.props " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  _save_file ( includes_props_file ,  includes_props_content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-24 16:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : generate_cs_editor_project ( const  String  & p_proj_dir )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! initialized ,  ERR_UNCONFIGURED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 11:08:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Ref < DirAccess >  da  =  DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( da . is_null ( ) ,  ERR_CANT_CREATE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! DirAccess : : exists ( p_proj_dir ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  da - > make_dir_recursive ( p_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( err  ! =  OK ,  ERR_CANT_CREATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									da - > change_dir ( p_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									da - > make_dir ( " Generated " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									da - > make_dir ( " Generated/GodotObjects " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  base_gen_dir  =  path : : join ( p_proj_dir ,  " Generated " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  godot_objects_gen_dir  =  path : : join ( base_gen_dir ,  " GodotObjects " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Vector < String >  compile_items ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  KeyValue < StringName ,  TypeInterface >  & E  :  obj_types )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  TypeInterface  & itype  =  E . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( itype . api_type  ! =  ClassDB : : API_EDITOR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  output_file  =  path : : join ( godot_objects_gen_dir ,  itype . proxy_name  +  " .cs " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 19:06:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  err  =  _generate_cs_type ( itype ,  output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  = =  ERR_SKIP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										compile_items . push_back ( output_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate native calls
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  cs_icalls_content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " namespace  "  BINDINGS_NAMESPACE  " ; \n \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " using System; \n " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 " using System.Diagnostics.CodeAnalysis; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " using System.Runtime.InteropServices; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 " using Godot.NativeInterop; \n " 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" InconsistentNaming \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" RedundantUnsafeContext \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [SuppressMessage( \" ReSharper \" ,  \" RedundantNameQualifier \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " [System.Runtime.CompilerServices.SkipLocalsInit] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( " internal static class  "  BINDINGS_CLASS_NATIVECALLS_EDITOR  " \n "  OPEN_BLOCK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs_icalls_content . append ( INDENT1  " internal static ulong godot_api_hash =  " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( String : : num_uint64 ( ClassDB : : get_api_hash ( ClassDB : : API_EDITOR ) )  +  " ; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( MEMBER_BEGIN  " private const int VarArgsSpanThreshold = 10; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  InternalCall  & icall  :  method_icalls )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! icall . editor_only )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  _generate_cs_native_calls ( icall ,  cs_icalls_content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs_icalls_content . append ( CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  internal_methods_file  =  path : : join ( base_gen_dir ,  BINDINGS_CLASS_NATIVECALLS_EDITOR  " .cs " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Error  err  =  _save_file ( internal_methods_file ,  cs_icalls_content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									compile_items . push_back ( internal_methods_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate GeneratedIncludes.props
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  includes_props_content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									includes_props_content . append ( " <Project> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  "   <ItemGroup> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  compile_items . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  include  =  path : : relative_to ( compile_items [ i ] ,  p_proj_dir ) . replace ( " / " ,  " \\ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										includes_props_content . append ( "     <Compile Include= \" "  +  include  +  " \"  /> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									includes_props_content . append ( "   </ItemGroup> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																  " </Project> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  includes_props_file  =  path : : join ( base_gen_dir ,  " GeneratedIncludes.props " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  _save_file ( includes_props_file ,  includes_props_content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : generate_cs_api ( const  String  & p_output_dir )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! initialized ,  ERR_UNCONFIGURED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-08 15:16:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  output_dir  =  path : : abspath ( path : : realpath ( p_output_dir ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 11:08:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Ref < DirAccess >  da  =  DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( da . is_null ( ) ,  ERR_CANT_CREATE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! DirAccess : : exists ( output_dir ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  da - > make_dir_recursive ( output_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( err  ! =  OK ,  ERR_CANT_CREATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Error  proj_err ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate GodotSharp source files
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-29 19:34:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  core_proj_dir  =  output_dir . path_join ( CORE_API_ASSEMBLY_NAME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									proj_err  =  generate_cs_core_project ( core_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( proj_err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_PRINT ( " Generation of the Core API C# project failed. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  proj_err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate GodotSharpEditor source files
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-29 19:34:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  editor_proj_dir  =  output_dir . path_join ( EDITOR_API_ASSEMBLY_NAME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									proj_err  =  generate_cs_editor_project ( editor_proj_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( proj_err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_PRINT ( " Generation of the Editor API C# project failed. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 01:05:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  proj_err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-28 19:12:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_log ( " The Godot API sources were successfully generated \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// FIXME: There are some members that hide other inherited members.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// - In the case of both members being the same kind, the new one must be declared
  
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// explicitly as 'new' to avoid the warning (and we must print a message about it).
  
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// - In the case of both members being of a different kind, then the new one must
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be renamed to avoid the name collision (and we must print a warning about it).
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// - Csc warning e.g.:
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ObjectType/LineEdit.cs(140,38): warning CS0108: 'LineEdit.FocusMode' hides inherited member 'Control.FocusMode'. Use the new keyword if hiding was intended.
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _generate_cs_type ( const  TypeInterface  & itype ,  const  String  & p_output_file )  {  
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CRASH_COND ( ! itype . is_object_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  is_derived_type  =  itype . base_name  ! =  StringName ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! is_derived_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Some GodotObject assertions
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CRASH_COND ( itype . cname  ! =  name_cache . type_Object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CRASH_COND ( ! itype . is_instantiable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CRASH_COND ( itype . api_type  ! =  ClassDB : : API_CORE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 18:03:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CRASH_COND ( itype . is_ref_counted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CRASH_COND ( itype . is_singleton ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_log ( " Generating %s.cs... \n " ,  itype . proxy_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  output ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " namespace  "  BINDINGS_NAMESPACE  " ; \n \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " using System; \n " ) ;  // IntPtr
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output . append ( " using System.Diagnostics; \n " ) ;  // DebuggerBrowsable
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " using Godot.NativeInterop; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-16 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " #pragma warning disable CS1591 // Disable warning:  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " 'Missing XML comment for publicly visible type or member' \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " #pragma warning disable CS1573 // Disable warning:  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " 'Parameter has no matching param tag in the XML comment' \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-16 17:22:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " \n #nullable disable \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									const  DocData : : ClassDoc  * class_doc  =  itype . class_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( class_doc  & &  class_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( class_doc - > description ) ,  & itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output . append ( " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( " /// </summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( class_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( " [Obsolete( \" This class is deprecated. \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We generate a `GodotClassName` attribute if the engine class name is not the same as the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// generated C# class name. This allows introspection code to find the name associated with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the class. If the attribute is not present, the C# class name can be used instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( itype . name  ! =  itype . proxy_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  " [GodotClassName( \" "  < <  itype . name  < <  " \" )] \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " public  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( " static partial class  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Even if the class is not instantiable, we can't declare it abstract because
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the engine can still instantiate them and return them via the scripting API.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Example: `SceneTreeTimer` returned from `SceneTree.create_timer`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// See the reverted commit: ef5672d3f94a7321ed779c922088bb72adbb1521
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( " partial class  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( itype . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_derived_type  & &  ! itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( obj_types . has ( itype . base_name ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											TypeInterface  base_type  =  obj_types [ itype . base_name ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( "  :  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( base_type . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( base_type . is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// If the type is a singleton, use the instance type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( CS_SINGLETON_INSTANCE_SUFFIX ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_PRINT ( " Base type ' "  +  itype . base_name . operator  String ( )  +  " ' does not exist, for class ' "  +  itype . name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " \n { " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add constants
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  ConstantInterface  & iconstant  :  itype . constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( iconstant . const_doc  & &  iconstant . const_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( iconstant . const_doc - > description ) ,  & itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( iconstant . const_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( MEMBER_BEGIN  " [Obsolete( \" This constant is deprecated. \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " public const long  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( iconstant . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( "  =  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( itos ( iconstant . value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( " ; " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( itype . constants . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add enums
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  EnumInterface  & ienum  :  itype . enums )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( ienum . constants . is_empty ( ) ,  ERR_BUG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 20:25:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ienum . is_flags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( MEMBER_BEGIN  " [System.Flags] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " public enum  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( pascal_to_pascal_case ( ienum . cname . operator  String ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( "  : long " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  OPEN_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  ConstantInterface  & last  =  ienum . constants . back ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  ConstantInterface  & iconstant  :  ienum . constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iconstant . const_doc  & &  iconstant . const_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( iconstant . const_doc - > description ) ,  & itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output . append ( INDENT2  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														output . append ( INDENT2  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output . append ( INDENT2  " /// </summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( iconstant . const_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													output . append ( INDENT2  " [Obsolete( \" This enum member is deprecated. \" )] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( iconstant . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( "  =  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( itos ( iconstant . value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( & iconstant  ! =  & last  ?  " , \n "  :  " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( INDENT1  CLOSE_BLOCK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  PropertyInterface  & iprop  :  itype . properties )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  prop_err  =  _generate_cs_property ( itype ,  iprop ,  output ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( prop_err  ! =  OK ,  prop_err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Failed to generate property ' "  +  iprop . cname . operator  String ( )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" ' for class ' "  +  itype . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-04 20:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add native name static field and cached type.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_derived_type  & &  ! itype . is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " private static readonly System.Type CachedType = typeof( "  < <  itype . proxy_name  < <  " ); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( MEMBER_BEGIN  " private static readonly StringName  "  BINDINGS_NATIVE_NAME_FIELD  "  =  \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output . append ( itype . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output . append ( " \" ; \n " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( itype . is_singleton  | |  itype . is_compat_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add the Singleton static property.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  instance_type_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( itype . is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											StringName  instance_name  =  itype . name  +  CS_SINGLETON_INSTANCE_SUFFIX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instance_type_name  =  obj_types . has ( instance_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													?  obj_types [ instance_name ] . proxy_name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													:  " GodotObject " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instance_type_name  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " private static  "  +  instance_type_name  +  "  singleton; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public static  "  +  instance_type_name  +  "   "  CS_PROPERTY_SINGLETON  "  => \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " singleton  \ ? \ ?= ( "  +  instance_type_name  +  " ) " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  C_METHOD_ENGINE_GET_SINGLETON  " ( \" "  < <  itype . name  < <  " \" ); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// IMPORTANT: We also generate the static fields for GodotObject instead of declaring
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// them manually in the `GodotObject.base.cs` partial class declaration, because they're
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// required by other static fields in this generated partial class declaration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Static fields are initialized in order of declaration, but when they're in different
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// partial class declarations then it becomes harder to tell (Rider warns about this).
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( itype . is_instantiable )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Add native constructor static field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  MEMBER_BEGIN  < <  " [DebuggerBrowsable(DebuggerBrowsableState.Never)] \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  INDENT1  " private static readonly unsafe delegate* unmanaged<IntPtr>  " 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_NATIVE_CTOR  "  =  "  ICALL_CLASSDB_GET_CONSTRUCTOR 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:23:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  " ( "  BINDINGS_NATIVE_NAME_FIELD  " ); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_derived_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Add default constructor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( itype . is_instantiable )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output  < <  MEMBER_BEGIN  " public  "  < <  itype . proxy_name  < <  " () : this( " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   < <  ( itype . memory_own  ?  " true "  :  " false " )  < <  " ) \n "  OPEN_BLOCK_L1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   < <  INDENT2  " unsafe \n "  INDENT2  OPEN_BLOCK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   < <  INDENT3  " _ConstructAndInitialize( "  CS_STATIC_FIELD_NATIVE_CTOR  " ,  " 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   < <  BINDINGS_NATIVE_NAME_FIELD  " , CachedType, refCounted:  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   < <  ( itype . is_ref_counted  ?  " true "  :  " false " )  < <  " ); \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   < <  CLOSE_BLOCK_L2  CLOSE_BLOCK_L1 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Hide the constructor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( MEMBER_BEGIN  " internal  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( itype . proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												output . append ( " () {} \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Add.. em.. trick constructor. Sort of.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( MEMBER_BEGIN  " internal  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( itype . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( " (bool  "  CS_PARAM_MEMORYOWN  " ) : base( "  CS_PARAM_MEMORYOWN  " ) {} \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Methods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  method_bind_count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  method_err  =  _generate_cs_method ( itype ,  imethod ,  method_bind_count ,  output ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( method_err  ! =  OK ,  method_err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Failed to generate method ' "  +  imethod . name  +  " ' for class ' "  +  itype . name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Signals
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  SignalInterface  & isignal  :  itype . signals_ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  method_err  =  _generate_cs_signal ( itype ,  isignal ,  output ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( method_err  ! =  OK ,  method_err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Failed to generate signal ' "  +  isignal . name  +  " ' for class ' "  +  itype . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Script members look-up
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! itype . is_singleton  & &  ( is_derived_type  | |  itype . has_virtual_methods ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Generate method names cache fields
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! imethod . is_virtual )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  MEMBER_BEGIN  " // ReSharper disable once InconsistentNaming \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  INDENT1  " [DebuggerBrowsable(DebuggerBrowsableState.Never)] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT1  " private static readonly StringName  " 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX  < <  imethod . name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  "  =  \" "  < <  imethod . proxy_name  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-13 20:59:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Generate signal names cache fields
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  SignalInterface  & isignal  :  itype . signals_ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  MEMBER_BEGIN  " // ReSharper disable once InconsistentNaming \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT1  " [DebuggerBrowsable(DebuggerBrowsableState.Never)] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT1  " private static readonly StringName  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX  < <  isignal . name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  "  =  \" "  < <  isignal . proxy_name  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// TODO: Only generate HasGodotClassMethod and InvokeGodotClassMethod if there's any method
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Generate InvokeGodotClassMethod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Invokes the method with the given name, using the given arguments. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// This method is used by Godot to invoke methods from the engine side. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Do not call or override this method. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// </summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// <param name= \" method \" >Name of the method to invoke.</param> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// <param name= \" args \" >Arguments to use with the invoked method.</param> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// <param name= \" ret \" >Value returned by the invoked method.</param> \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  INDENT1  " protected internal  "  < <  ( is_derived_type  ?  " override "  :  " virtual " ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  "  bool  "  CS_METHOD_INVOKE_GODOT_CLASS_METHOD  " (in godot_string_name method,  " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  " NativeVariantPtrArgs args, out godot_variant ret) \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! imethod . is_virtual )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// We also call HasGodotClassMethod to ensure the method is overridden and avoid calling
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the stub implementation. This solution adds some extra overhead to calls, but it's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// much simpler than other solutions. This won't be a problem once we move to function
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// pointers of generated wrappers for each method, as lookup will only happen once.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// We check both native names (snake_case) and proxy names (PascalCase)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " if ((method ==  "  < <  CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX  < <  imethod . name 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  "  || method == MethodName. "  < <  imethod . proxy_name 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  " ) && args.Count ==  "  < <  itos ( imethod . arguments . size ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  "  &&  "  < <  CS_METHOD_HAS_GODOT_CLASS_METHOD  < <  " ((godot_string_name) " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX  < <  imethod . name  < <  " .NativeValue)) \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  INDENT2  " { \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( imethod . return_type . cname  ! =  name_cache . type_void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output  < <  INDENT3  " var callRet =  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output  < <  INDENT3 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  imethod . proxy_name  < <  " ( " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  imethod . arguments . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  ArgumentInterface  & iarg  =  imethod . arguments [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  TypeInterface  * arg_type  =  _get_type_or_null ( iarg . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Argument type not found
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													output  < <  " ,  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( arg_type - > cname  = =  name_cache . type_Array_generic  | |  arg_type - > cname  = =  name_cache . type_Dictionary_generic )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													String  arg_cs_type  =  arg_type - > cs_type  +  _get_generic_type_parameters ( * arg_type ,  iarg . type . generic_type_parameters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output  < <  " new  "  < <  arg_cs_type  < <  " ( "  < <  sformat ( arg_type - > cs_variant_to_managed ,  " args[ "  +  itos ( i )  +  " ] " ,  arg_type - > cs_type ,  arg_type - > name )  < <  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													output  < <  sformat ( arg_type - > cs_variant_to_managed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" args[ "  +  itos ( i )  +  " ] " ,  arg_type - > cs_type ,  arg_type - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  " ); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( imethod . return_type . cname  ! =  name_cache . type_void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  TypeInterface  * return_type  =  _get_type_or_null ( imethod . return_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_FAIL_NULL_V ( return_type ,  ERR_BUG ) ;  // Return type not found
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output  < <  INDENT3  " ret =  " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   < <  sformat ( return_type - > cs_managed_to_variant ,  " callRet " ,  return_type - > cs_type ,  return_type - > name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   < <  " ; \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													   < <  INDENT3  " return true; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												output  < <  INDENT3  " ret = default; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   < <  INDENT3  " return true; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " } \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_derived_type )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " return base. "  CS_METHOD_INVOKE_GODOT_CLASS_METHOD  " (method, args, out ret); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " ret = default; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT2  " return false; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Generate HasGodotClassMethod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Check if the type contains a method with the given name. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// This method is used by Godot to check if a method exists before invoking it. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Do not call or override this method. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// </summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// <param name= \" method \" >Name of the method to check for.</param> \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " protected internal  "  < <  ( is_derived_type  ?  " override "  :  " virtual " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  "  bool  "  CS_METHOD_HAS_GODOT_CLASS_METHOD  " (in godot_string_name method) \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! imethod . is_virtual )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// We check for native names (snake_case). If we detect one, we call HasGodotClassMethod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// again, but this time with the respective proxy name (PascalCase). It's the job of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// user derived classes to override the method and check for those. Our C# source
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// generators take care of generating those override methods.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " if (method == MethodName. "  < <  imethod . proxy_name 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  " ) \n "  INDENT2  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT3  " if ( "  CS_METHOD_HAS_GODOT_CLASS_METHOD  " ( " 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX  < <  imethod . name 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  " .NativeValue.DangerousSelfRef)) \n "  INDENT3  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT4  " return true; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT3  " } \n "  INDENT2  " } \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_derived_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " return base. "  CS_METHOD_HAS_GODOT_CLASS_METHOD  " (method); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " return false; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-13 20:59:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Generate HasGodotClassSignal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Check if the type contains a signal with the given name. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// This method is used by Godot to check if a signal exists before raising it. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// Do not call or override this method. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " /// </summary> \n " 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-05 20:00:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  INDENT1  " /// <param name= \" signal \" >Name of the signal to check for.</param> \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-13 20:59:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " protected internal  "  < <  ( is_derived_type  ?  " override "  :  " virtual " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  "  bool  "  CS_METHOD_HAS_GODOT_CLASS_SIGNAL  " (in godot_string_name signal) \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  SignalInterface  & isignal  :  itype . signals_ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// We check for native names (snake_case). If we detect one, we call HasGodotClassSignal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// again, but this time with the respective proxy name (PascalCase). It's the job of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// user derived classes to override the method and check for those. Our C# source
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// generators take care of generating those override methods.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  INDENT2  " if (signal == SignalName. "  < <  isignal . proxy_name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  " ) \n "  INDENT2  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT3  " if ( "  CS_METHOD_HAS_GODOT_CLASS_SIGNAL  " ( " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX  < <  isignal . name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  " .NativeValue.DangerousSelfRef)) \n "  INDENT3  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT4  " return true; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  INDENT3  " } \n "  INDENT2  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( is_derived_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  INDENT2  " return base. "  CS_METHOD_HAS_GODOT_CLASS_SIGNAL  " (signal); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output  < <  INDENT2  " return false; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//Generate StringName for all class members
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  is_inherit  =  ! itype . is_singleton  & &  obj_types . has ( itype . base_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//PropertyName
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// Cached StringNames for the properties and fields contained in this class, for fast lookup. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// </summary> \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public new class PropertyName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .PropertyName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public class PropertyName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  PropertyInterface  & iprop  :  itype . properties )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT2  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// Cached name for the ' "  < <  iprop . cname  < <  " ' property. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// </summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " public static readonly StringName  "  < <  iprop . proxy_name  < <  "  =  \" "  < <  iprop . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//MethodName
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// Cached StringNames for the methods contained in this class, for fast lookup. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// </summary> \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public new class MethodName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .MethodName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public class MethodName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT2  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// Cached name for the ' "  < <  imethod . cname  < <  " ' method. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// </summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " public static readonly StringName  "  < <  imethod . proxy_name  < <  "  =  \" "  < <  imethod . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//SignalName
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output  < <  MEMBER_BEGIN  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// Cached StringNames for the signals contained in this class, for fast lookup. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " /// </summary> \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public new class SignalName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .SignalName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT1  " public class SignalName " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  SignalInterface  & isignal  :  itype . signals_ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 14:14:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  INDENT2  " /// <summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// Cached name for the ' "  < <  isignal . cname  < <  " ' signal. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " /// </summary> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " public static readonly StringName  "  < <  isignal . proxy_name  < <  "  =  \" "  < <  isignal . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( CLOSE_BLOCK  /* class */ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									output . append ( " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " #pragma warning restore CS1591 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  " #pragma warning restore CS1573 \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  _save_file ( p_output_file ,  output ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _generate_cs_property ( const  BindingsGenerator : : TypeInterface  & p_itype ,  const  PropertyInterface  & p_iprop ,  StringBuilder  & p_output )  {  
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  MethodInterface  * setter  =  p_itype . find_method_by_name ( p_iprop . setter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Search it in base types too
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  TypeInterface  * current_type  =  & p_itype ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ! setter  & &  current_type - > base_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < StringName ,  TypeInterface > : : Iterator  base_match  =  obj_types . find ( current_type - > base_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 01:38:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( ! base_match ,  ERR_BUG ,  " Type not found ' "  +  current_type - > base_name  +  " '. Inherited by ' "  +  current_type - > name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										current_type  =  & base_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										setter  =  current_type - > find_method_by_name ( p_iprop . setter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  MethodInterface  * getter  =  p_itype . find_method_by_name ( p_iprop . getter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Search it in base types too
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_type  =  & p_itype ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ! getter  & &  current_type - > base_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < StringName ,  TypeInterface > : : Iterator  base_match  =  obj_types . find ( current_type - > base_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 01:38:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( ! base_match ,  ERR_BUG ,  " Type not found ' "  +  current_type - > base_name  +  " '. Inherited by ' "  +  current_type - > name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										current_type  =  & base_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getter  =  current_type - > find_method_by_name ( p_iprop . getter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! setter  & &  ! getter ,  ERR_BUG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( setter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  setter_argc  =  p_iprop . index  ! =  - 1  ?  2  :  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( setter - > arguments . size ( )  ! =  setter_argc ,  ERR_BUG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( getter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  getter_argc  =  p_iprop . index  ! =  - 1  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( getter - > arguments . size ( )  ! =  getter_argc ,  ERR_BUG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( getter  & &  setter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  ArgumentInterface  & setter_first_arg  =  setter - > arguments . back ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( getter - > return_type . cname  ! =  setter_first_arg . type . cname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Special case for Node::set_name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bool  whitelisted  =  getter - > return_type . cname  = =  name_cache . type_StringName  & & 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													setter_first_arg . type . cname  = =  name_cache . type_String ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! whitelisted ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Return type from getter doesn't match first argument of setter for property: ' "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															p_itype . name  +  " . "  +  String ( p_iprop . cname )  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  TypeReference  & proptype_name  =  getter  ?  getter - > return_type  :  setter - > arguments . back ( ) - > get ( ) . type ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  TypeInterface  * prop_itype  =  _get_type_or_singleton_or_null ( proptype_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( prop_itype ,  ERR_BUG ) ;  // Property type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( prop_itype - > is_singleton ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Property type is a singleton: ' "  +  p_itype . name  +  " . "  +  String ( p_iprop . cname )  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 00:14:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_itype . api_type  = =  ClassDB : : API_CORE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( prop_itype - > api_type  = =  ClassDB : : API_EDITOR ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Property ' "  +  p_itype . name  +  " . "  +  String ( p_iprop . cname )  +  " ' has type ' "  +  prop_itype - > name  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" ' from the editor API. Core API cannot have dependencies on the editor API. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_iprop . prop_doc  & &  p_iprop . prop_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( p_iprop . prop_doc - > description ) ,  & p_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_iprop . prop_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " [Obsolete( \" This property is deprecated. \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( MEMBER_BEGIN  " public  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " static  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  prop_cs_type  =  prop_itype - > cs_type  +  _get_generic_type_parameters ( * prop_itype ,  proptype_name . generic_type_parameters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( prop_cs_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( "   " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p_output . append ( p_iprop . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( " \n "  OPEN_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( getter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( INDENT2  " get \n "  OPEN_BLOCK_L2  INDENT3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " return  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( getter - > proxy_name  +  " ( " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_iprop . index  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  ArgumentInterface  & idx_arg  =  getter - > arguments . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx_arg . type . cname  ! =  name_cache . type_int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Assume the index parameter is an enum
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  TypeInterface  * idx_arg_type  =  _get_type_or_null ( idx_arg . type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												CRASH_COND ( idx_arg_type  = =  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 21:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( " ( "  +  idx_arg_type - > proxy_name  +  " )( "  +  itos ( p_iprop . index )  +  " ) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( itos ( p_iprop . index ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " ); \n "  CLOSE_BLOCK_L2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( setter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( INDENT2  " set \n "  OPEN_BLOCK_L2  INDENT3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( setter - > proxy_name  +  " ( " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_iprop . index  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  ArgumentInterface  & idx_arg  =  setter - > arguments . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx_arg . type . cname  ! =  name_cache . type_int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Assume the index parameter is an enum
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  TypeInterface  * idx_arg_type  =  _get_type_or_null ( idx_arg . type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												CRASH_COND ( idx_arg_type  = =  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 21:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( " ( "  +  idx_arg_type - > proxy_name  +  " )( "  +  itos ( p_iprop . index )  +  " ),  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( itos ( p_iprop . index )  +  " ,  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " value); \n "  CLOSE_BLOCK_L2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_output . append ( CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _generate_cs_method ( const  BindingsGenerator : : TypeInterface  & p_itype ,  const  BindingsGenerator : : MethodInterface  & p_imethod ,  int  & p_method_bind_count ,  StringBuilder  & p_output )  {  
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  TypeInterface  * return_type  =  _get_type_or_singleton_or_null ( p_imethod . return_type ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( return_type ,  ERR_BUG ) ;  // Return type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( return_type - > is_singleton ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Method return type is a singleton: ' "  +  p_itype . name  +  " . "  +  p_imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 00:14:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_itype . api_type  = =  ClassDB : : API_CORE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( return_type - > api_type  = =  ClassDB : : API_EDITOR ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Method ' "  +  p_itype . name  +  " . "  +  p_imethod . name  +  " ' has return type ' "  +  return_type - > name  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" ' from the editor API. Core API cannot have dependencies on the editor API. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  method_bind_field  =  CS_STATIC_FIELD_METHOD_BIND_PREFIX  +  itos ( p_method_bind_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  arguments_sig ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  cs_in_statements ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  cs_in_expr_is_unsafe  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  icall_params  =  method_bind_field ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_imethod . is_static )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  self_reference  =  " this " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											self_reference  =  CS_PROPERTY_SINGLETON ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . cs_in . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cs_in_statements  < <  sformat ( p_itype . cs_in ,  p_itype . c_type ,  self_reference , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													String ( ) ,  String ( ) ,  String ( ) ,  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										icall_params  + =  " ,  "  +  sformat ( p_itype . cs_in_expr ,  self_reference ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-25 23:44:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  default_args_doc ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Retrieve information from the arguments
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  ArgumentInterface  & first  =  p_imethod . arguments . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  ArgumentInterface  & iarg  :  p_imethod . arguments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  * arg_type  =  _get_type_or_singleton_or_null ( iarg . type ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Argument type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( arg_type - > is_singleton ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Argument type is a singleton: ' "  +  iarg . name  +  " ' of method ' "  +  p_itype . name  +  " . "  +  p_imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 00:14:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . api_type  = =  ClassDB : : API_CORE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( arg_type - > api_type  = =  ClassDB : : API_EDITOR ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Argument ' "  +  iarg . name  +  " ' of method ' "  +  p_itype . name  +  " . "  +  p_imethod . name  +  " ' has type ' "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															arg_type - > name  +  " ' from the editor API. Core API cannot have dependencies on the editor API. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( iarg . default_argument . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CRASH_COND_MSG ( ! _arg_default_value_is_assignable_to_type ( iarg . def_param_value ,  * arg_type ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Invalid default value for parameter ' "  +  iarg . name  +  " ' of method ' "  +  p_itype . name  +  " . "  +  p_imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  arg_cs_type  =  arg_type - > cs_type  +  _get_generic_type_parameters ( * arg_type ,  iarg . type . generic_type_parameters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Add the current arguments to the signature
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If the argument has a default value which is not a constant, we will make it Nullable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( & iarg  ! =  & first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												arguments_sig  + =  " ,  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iarg . def_param_mode  = =  ArgumentInterface : : NULLABLE_VAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												arguments_sig  + =  " Nullable< " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											arguments_sig  + =  arg_cs_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iarg . def_param_mode  = =  ArgumentInterface : : NULLABLE_VAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												arguments_sig  + =  " >  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												arguments_sig  + =  "   " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											arguments_sig  + =  iarg . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iarg . default_argument . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( iarg . def_param_mode  ! =  ArgumentInterface : : CONSTANT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													arguments_sig  + =  "  = null " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													arguments_sig  + =  "  =  "  +  sformat ( iarg . default_argument ,  arg_type - > cs_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										icall_params  + =  " ,  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( iarg . default_argument . size ( )  & &  iarg . def_param_mode  ! =  ArgumentInterface : : CONSTANT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The default value of an argument must be constant. Otherwise we make it Nullable and do the following:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Type arg_in = arg.HasValue ? arg.Value : <non-const default value>;
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  arg_or_defval_local  =  iarg . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arg_or_defval_local  + =  " OrDefVal " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cs_in_statements  < <  INDENT2  < <  arg_cs_type  < <  "   "  < <  arg_or_defval_local  < <  "  =  "  < <  iarg . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iarg . def_param_mode  = =  ArgumentInterface : : NULLABLE_VAL )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cs_in_statements  < <  " .HasValue ?  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cs_in_statements  < <  "  != null ?  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cs_in_statements  < <  iarg . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iarg . def_param_mode  = =  ArgumentInterface : : NULLABLE_VAL )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cs_in_statements  < <  " .Value :  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cs_in_statements  < <  "  :  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  cs_type  =  arg_cs_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 13:46:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( cs_type . ends_with ( " [] " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cs_type  =  cs_type . substr ( 0 ,  cs_type . length ( )  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  def_arg  =  sformat ( iarg . default_argument ,  cs_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cs_in_statements  < <  def_arg  < <  " ; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( arg_type - > cs_in . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cs_in_statements  < <  sformat ( arg_type - > cs_in ,  arg_type - > c_type ,  arg_or_defval_local , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														String ( ) ,  String ( ) ,  String ( ) ,  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( arg_type - > cs_in_expr . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												icall_params  + =  arg_or_defval_local ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												icall_params  + =  sformat ( arg_type - > cs_in_expr ,  arg_or_defval_local ,  arg_type - > c_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Apparently the name attribute must not include the @
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  param_tag_name  =  iarg . name . begins_with ( " @ " )  ?  iarg . name . substr ( 1 ,  iarg . name . length ( ) )  :  iarg . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 13:46:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Escape < and > in the attribute default value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  param_def_arg  =  def_arg . replacen ( " < " ,  " < " ) . replacen ( " > " ,  " > " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default_args_doc . append ( MEMBER_BEGIN  " /// <param name= \" "  +  param_tag_name  +  " \" >If the parameter is null, then the default value is <c> "  +  param_def_arg  +  " </c>.</param> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( arg_type - > cs_in . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cs_in_statements  < <  sformat ( arg_type - > cs_in ,  arg_type - > c_type ,  iarg . name , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														String ( ) ,  String ( ) ,  String ( ) ,  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											icall_params  + =  arg_type - > cs_in_expr . is_empty ( )  ?  iarg . name  :  sformat ( arg_type - > cs_in_expr ,  iarg . name ,  arg_type - > c_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cs_in_expr_is_unsafe  | =  arg_type - > cs_in_expr_is_unsafe ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 19:42:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Collect caller name for MethodBind
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_imethod . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										icall_params  + =  " , (godot_string_name)MethodName. "  +  p_imethod . proxy_name  +  " .NativeValue " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate method
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! p_imethod . is_virtual  & &  ! p_imethod . requires_object_call )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output  < <  MEMBER_BEGIN  " [DebuggerBrowsable(DebuggerBrowsableState.Never)] \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT1  " private static readonly IntPtr  "  < <  method_bind_field  < <  "  =  " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Singletons are static classes. They don't derive GodotObject,
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// so we need to specify the type to call the static method.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output  < <  " GodotObject. " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output  < <  ICALL_CLASSDB_GET_METHOD  " ( "  BINDINGS_NATIVE_NAME_FIELD  " , MethodName. " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  p_imethod . proxy_name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_imethod . method_doc  & &  p_imethod . method_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( p_imethod . method_doc - > description ) ,  & p_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-02 18:09:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_imethod . method_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_output . append ( MEMBER_BEGIN  " [Obsolete( \" This method is deprecated. \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-02 18:09:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( default_args_doc . get_string_length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( default_args_doc . as_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_imethod . is_deprecated )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p_imethod . deprecation_message . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-07 09:44:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												WARN_PRINT ( " An empty deprecation message is discouraged. Method: ' "  +  p_imethod . proxy_name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " [Obsolete( \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( p_imethod . deprecation_message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( MEMBER_BEGIN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( p_imethod . is_internal  ?  " internal  "  :  " public  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . is_singleton  | |  p_imethod . is_static )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " static  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( p_imethod . is_virtual )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " virtual  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( cs_in_expr_is_unsafe )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " unsafe  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  return_cs_type  =  return_type - > cs_type  +  _get_generic_type_parameters ( * return_type ,  p_imethod . return_type . generic_type_parameters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( return_cs_type  +  "   " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( p_imethod . proxy_name  +  " ( " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( arguments_sig  +  " ) \n "  OPEN_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_imethod . is_virtual )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Godot virtual method must be overridden, therefore we return a default value by default.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( return_type - > cname  = =  name_cache . type_void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( INDENT2  " return default; \n "  CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  OK ;  // Won't increment method bind count
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_imethod . requires_object_call )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Fallback to Godot's object.Call(string, params)
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( INDENT2  CS_METHOD_CALL  " ( \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( p_imethod . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( const  ArgumentInterface  & iarg  :  p_imethod . arguments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( " ,  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( iarg . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " ); \n "  CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  OK ;  // Won't increment method bind count
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < const  MethodInterface  * ,  const  InternalCall  * > : : ConstIterator  match  =  method_icalls_map . find ( & p_imethod ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( match ,  ERR_BUG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  InternalCall  * im_icall  =  match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-22 13:13:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  im_call  =  im_icall - > editor_only  ?  BINDINGS_CLASS_NATIVECALLS_EDITOR  :  BINDINGS_CLASS_NATIVECALLS ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										im_call  + =  " . " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										im_call  + =  im_icall - > name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_imethod . arguments . size ( )  & &  cs_in_statements . get_string_length ( )  >  0 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( cs_in_statements . as_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( return_type - > cname  = =  name_cache . type_void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output  < <  INDENT2  < <  im_call  < <  " ( "  < <  icall_params  < <  " ); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( return_type - > cs_out . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output  < <  INDENT2  " return  "  < <  im_call  < <  " ( "  < <  icall_params  < <  " ); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( sformat ( return_type - > cs_out ,  im_call ,  icall_params , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return_cs_type ,  return_type - > c_type_out ,  String ( ) ,  INDENT2 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_method_bind_count + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _generate_cs_signal ( const  BindingsGenerator : : TypeInterface  & p_itype ,  const  BindingsGenerator : : SignalInterface  & p_isignal ,  StringBuilder  & p_output )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  arguments_sig ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  delegate_type_params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p_isignal . arguments . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delegate_type_params  + =  " < " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Retrieve information from the arguments
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  ArgumentInterface  & first  =  p_isignal . arguments . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  ArgumentInterface  & iarg  :  p_isignal . arguments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  * arg_type  =  _get_type_or_singleton_or_null ( iarg . type ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Argument type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( arg_type - > is_singleton ,  ERR_BUG , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 00:14:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												" Argument type is a singleton: ' "  +  iarg . name  +  " ' of signal ' "  +  p_itype . name  +  " . "  +  p_isignal . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_itype . api_type  = =  ClassDB : : API_CORE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( arg_type - > api_type  = =  ClassDB : : API_EDITOR ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Argument ' "  +  iarg . name  +  " ' of signal ' "  +  p_itype . name  +  " . "  +  p_isignal . name  +  " ' has type ' "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															arg_type - > name  +  " ' from the editor API. Core API cannot have dependencies on the editor API. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Add the current arguments to the signature
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( & iarg  ! =  & first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											arguments_sig  + =  " ,  " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											delegate_type_params  + =  " ,  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arguments_sig  + =  arg_type - > cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arguments_sig  + =  "   " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arguments_sig  + =  iarg . name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delegate_type_params  + =  arg_type - > cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p_isignal . arguments . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delegate_type_params  + =  " > " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Generate signal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-16 09:30:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( " Represents the method that handles the  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . "  +  p_itype . proxy_name  +  " . "  +  p_isignal . proxy_name  +  " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( "  event of a  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( " <see cref= \" "  BINDINGS_NAMESPACE  " . "  +  p_itype . proxy_name  +  " \" /> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( "  class. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 13:24:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_isignal . is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_isignal . deprecation_message . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												WARN_PRINT ( " An empty deprecation message is discouraged. Signal: ' "  +  p_isignal . proxy_name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " [Obsolete( \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( p_isignal . deprecation_message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bool  is_parameterless  =  p_isignal . arguments . size ( )  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 13:24:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Delegate name is [SignalName]EventHandler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  delegate_name  =  is_parameterless  ?  " Action "  :  p_isignal . proxy_name  +  " EventHandler " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! is_parameterless )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Generate delegate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " public delegate void  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( delegate_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " ( " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( arguments_sig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " ); \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Generate Callable trampoline for the delegate
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Optimize Variant conversion callbacks
These callbacks are used for marshaling by callables and generic Godot
collections.
C# generics don't support specialization the way C++ templates do.
I knew NativeAOT could optimize away many type checks when the types
are known at compile time, but I didn't trust the JIT would do as good
a job, so I initially went with cached function pointers.
Well, it turns out the JIT is also very good at optimizing in this
scenario, so I'm changing the methods to do the conversion directly,
rather than returning a function pointer for the conversion.
The methods were moved to `VariantUtils`, and were renamed from
`GetFromVariantCallback/GetToVariantCallback` to `ConvertTo/CreateFrom`.
The new implementation looks like it goes through many `if` checks
at runtime to find the right branch for the type, but in practice it
works pretty much like template specialization. The JIT only generates
code for the relevant branch. Together with inlining, the result is
very close or the same as doing the conversion manually:
```cs
godot_variant variant;
int foo = variant.Int;
int bar = VariantUtils.ConvertTo<int>(variant);
```
If the type is a generic Godot collection, the conversion still goes
through a function pointer call.
The new code happens to be much shorter as well, with the file going
from 1057 lines to 407.
Side note: `Variant.cs` was mistakenly created in the wrong folder,
so I moved it to the `Core` folder.
											 
										 
										
											2022-11-06 01:27:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output  < <  MEMBER_BEGIN  " private static void  "  < <  p_isignal . proxy_name  < <  " Trampoline " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  " (object delegateObj, NativeVariantPtrArgs args, out godot_variant ret) \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT1  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT2  " Callable.ThrowIfArgCountMismatch(args,  "  < <  itos ( p_isignal . arguments . size ( ) )  < <  " ); \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT2  " (( "  < <  delegate_name  < <  " )delegateObj)( " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  idx  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( const  ArgumentInterface  & iarg  :  p_isignal . arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  TypeInterface  * arg_type  =  _get_type_or_null ( iarg . type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Argument type not found
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( idx  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_output  < <  " , " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Optimize Variant conversion callbacks
These callbacks are used for marshaling by callables and generic Godot
collections.
C# generics don't support specialization the way C++ templates do.
I knew NativeAOT could optimize away many type checks when the types
are known at compile time, but I didn't trust the JIT would do as good
a job, so I initially went with cached function pointers.
Well, it turns out the JIT is also very good at optimizing in this
scenario, so I'm changing the methods to do the conversion directly,
rather than returning a function pointer for the conversion.
The methods were moved to `VariantUtils`, and were renamed from
`GetFromVariantCallback/GetToVariantCallback` to `ConvertTo/CreateFrom`.
The new implementation looks like it goes through many `if` checks
at runtime to find the right branch for the type, but in practice it
works pretty much like template specialization. The JIT only generates
code for the relevant branch. Together with inlining, the result is
very close or the same as doing the conversion manually:
```cs
godot_variant variant;
int foo = variant.Int;
int bar = VariantUtils.ConvertTo<int>(variant);
```
If the type is a generic Godot collection, the conversion still goes
through a function pointer call.
The new code happens to be much shorter as well, with the file going
from 1057 lines to 407.
Side note: `Variant.cs` was mistakenly created in the wrong folder,
so I moved it to the `Core` folder.
											 
										 
										
											2022-11-06 01:27:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output  < <  sformat ( arg_type - > cs_variant_to_managed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" args[ "  +  itos ( idx )  +  " ] " ,  arg_type - > cs_type ,  arg_type - > name ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												idx + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  " ); \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT2  " ret = default; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 13:24:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_isignal . method_doc  & &  p_isignal . method_doc - > description . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  xml_summary  =  bbcode_to_xml ( fix_doc_description ( p_isignal . method_doc - > description ) ,  & p_itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < String >  summary_lines  =  xml_summary . length ( )  ?  xml_summary . split ( " \n " )  :  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( summary_lines . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_output . append ( MEMBER_BEGIN  " /// <summary> \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  summary_lines . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( INDENT1  " ///  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_output . append ( summary_lines [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_output . append ( " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p_output . append ( INDENT1  " /// </summary> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 12:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_isignal . method_doc - > is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_output . append ( MEMBER_BEGIN  " [Obsolete( \" This signal is deprecated. \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_isignal . is_deprecated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( MEMBER_BEGIN  " [Obsolete( \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( p_isignal . deprecation_message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output . append ( " \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Could we assume the StringName instance of signal name will never be freed (it's stored in ClassDB) before the managed world is unloaded?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If so, we could store the pointer we get from `data_unique_pointer()` instead of allocating StringName here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Generate event
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-26 00:49:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( MEMBER_BEGIN  " public  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " static  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! is_parameterless )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// `unsafe` is needed for taking the trampoline's function pointer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  " unsafe  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " event  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( delegate_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( "   " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_output . append ( p_isignal . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " \n "  OPEN_BLOCK_L1  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " add =>  "  CS_PROPERTY_SINGLETON  " .Connect(SignalName. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( " add => Connect(SignalName. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( is_parameterless )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Delegate type is Action. No need for custom trampoline.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  p_isignal . proxy_name  < <  " , Callable.From(value)); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  p_isignal . proxy_name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " , Callable.CreateWithUnsafeTrampoline(value, & "  < <  p_isignal . proxy_name  < <  " Trampoline)); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( INDENT2  " remove =>  "  CS_PROPERTY_SINGLETON  " .Disconnect(SignalName. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( INDENT2  " remove => Disconnect(SignalName. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Remove need for reflection to invoking callable delegates
We aim to make the C# API reflection-free, mainly for concerns about
performance, and to be able to target NativeAOT in refletion-free mode,
which reduces the binary size.
One of the main usages of reflection still left was the dynamic
invokation of callable delegates, and for some time I wasn't sure
I would find an alternative solution that I'd be happy with.
The new solution uses trampoline functions to invoke the delegates:
```
static void Trampoline(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)
{
    if (args.Count != 1)
        throw new ArgumentException($"Callable expected 1 arguments but received {args.Count}.");
    string res = ((Func<int, string>)delegateObj)(
        VariantConversionCallbacks.GetToManagedCallback<int>()(args[0])
    );
    ret = VariantConversionCallbacks.GetToVariantCallback<string>()(res);
}
Callable.CreateWithUnsafeTrampoline((int num) => "Foo" + num, &Trampoline);
```
Of course, this is too much boilerplate for user code. To improve this,
the `Callable.From` methods were added. These are overloads that take
`Action` and `Func` delegates, which covers the most common use cases:
lambdas and method groups:
```
// Lambda
Callable.From((int num) => "Foo" + num);
// Method group
string AppendNum(int num) => "Foo" + num;
Callable.From(AppendNum);
```
Unfortunately, due to limitations in the C# language, implicit
conversions from delegates to `Callable` are not supported.
`Callable.From` does not support custom delegates. These should be
uncommon, but the Godot C# API actually uses them for event signals.
As such, the bindings generator was updated to generate trampoline
functions for event signals. It was also optimized to use `Action`
instead of a custom delegate for parameterless signals, which removes
the need for the trampoline functions for those signals.
The change to reflection-free invokation removes one of the last needs
for `ConvertVariantToManagedObjectOfType`. The only remaining usage is
from calling script constructors with parameters from the engine
(`CreateManagedForGodotObjectScriptInstance`). Once that one is made
reflection-free, `ConvertVariantToManagedObjectOfType` can be removed.
											 
										 
										
											2022-10-28 22:59:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( is_parameterless )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Delegate type is Action. No need for custom trampoline.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  p_isignal . proxy_name  < <  " , Callable.From(value)); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_output  < <  p_isignal . proxy_name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " , Callable.CreateWithUnsafeTrampoline(value, & "  < <  p_isignal . proxy_name  < <  " Trampoline)); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( CLOSE_BLOCK_L1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _generate_cs_native_calls ( const  InternalCall  & p_icall ,  StringBuilder  & r_output )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  ret_void  =  p_icall . return_type . cname  = =  name_cache . type_void ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  TypeInterface  * return_type  =  _get_type_or_null ( p_icall . return_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( return_type ,  ERR_BUG ) ;  // Return type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StringBuilder  c_func_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StringBuilder  c_in_statements ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StringBuilder  c_args_var_content ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c_func_sig  < <  " IntPtr  "  CS_PARAM_METHODBIND ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_icall . is_static )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c_func_sig  + =  " , IntPtr  "  CS_PARAM_INSTANCE ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get arguments information
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  TypeReference  & arg_type_ref  :  p_icall . argument_types )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  TypeInterface  * arg_type  =  _get_type_or_null ( arg_type_ref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( arg_type ,  ERR_BUG ) ;  // Return type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  c_param_name  =  " arg "  +  itos ( i  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_icall . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( i  <  p_icall . get_arguments_count ( )  -  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												String  c_in_vararg  =  arg_type - > c_in_vararg ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( arg_type - > is_object_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromGodotObjectPtr(%1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_FAIL_COND_V_MSG ( c_in_vararg . is_empty ( ) ,  ERR_BUG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" VarArg support not implemented for parameter type:  "  +  arg_type - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c_in_statements 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< <  sformat ( c_in_vararg ,  return_type - > c_type ,  c_param_name , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																   String ( ) ,  String ( ) ,  String ( ) ,  INDENT3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< <  INDENT3  C_LOCAL_PTRCALL_ARGS  " [ "  < <  itos ( i ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														< <  " ] = new IntPtr(& "  < <  c_param_name  < <  " _in); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i  >  0 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												c_args_var_content  < <  " ,  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( arg_type - > c_in . size ( ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												c_in_statements  < <  sformat ( arg_type - > c_in ,  arg_type - > c_type ,  c_param_name , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														String ( ) ,  String ( ) ,  String ( ) ,  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c_args_var_content  < <  sformat ( arg_type - > c_arg_in ,  c_param_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c_func_sig  < <  " ,  "  < <  arg_type - > c_type_in  < <  "   "  < <  c_param_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 19:42:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Collect caller name for MethodBind
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_icall . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c_func_sig  < <  " , godot_string_name caller " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  icall_method  =  p_icall . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate icall function
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_output  < <  MEMBER_BEGIN  " internal static unsafe  "  < <  ( ret_void  ?  " void "  :  return_type - > c_type_out )  < <  "   " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 < <  icall_method  < <  " ( "  < <  c_func_sig . as_string ( )  < <  " )  "  OPEN_BLOCK ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ret_void  & &  ( ! p_icall . is_vararg  | |  return_type - > cname  ! =  name_cache . type_Variant ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  ptrcall_return_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  initialization ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( return_type - > is_object_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ptrcall_return_type  =  return_type - > is_ref_counted  ?  " godot_ref "  :  return_type - > c_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											initialization  =  "  = default " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ptrcall_return_type  =  return_type - > c_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_output  < <  INDENT2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( return_type - > is_ref_counted  | |  return_type - > c_type_is_disposable_struct )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  " using  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( initialization . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												initialization  =  "  = default " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( return_type - > c_ret_needs_default_initialization )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											initialization  =  "  = default " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_output  < <  ptrcall_return_type  < <  "   "  C_LOCAL_RET  < <  initialization  < <  " ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_icall . is_static )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_output  < <  INDENT2  " if ( "  CS_PARAM_INSTANCE  "  == IntPtr.Zero) \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 < <  INDENT3  " throw new ArgumentNullException(nameof( "  CS_PARAM_INSTANCE  " )); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  argc_str  =  itos ( p_icall . get_arguments_count ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									auto  generate_call_and_return_stmts  =  [ & ] ( const  char  * base_indent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_icall . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// MethodBind Call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  base_indent ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// VarArg methods always return Variant, but there are some cases in which MethodInfo provides
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// a specific return type. We trust this information is valid. We need a temporary local to keep
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the Variant alive until the method returns. Otherwise, if the returned Variant holds a RefPtr,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// it could be deleted too early. This is the case with GDScript.new() which returns OBJECT.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Alternatively, we could just return Variant, but that would result in a worse API.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ret_void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( return_type - > cname  ! =  name_cache . type_Variant )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-12 17:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Usually the return value takes ownership, but in this case the variant is only used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// for conversion to another return type. As such, the local variable takes ownership.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													r_output  < <  " using godot_variant  "  < <  C_LOCAL_VARARG_RET  "  =  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-12 17:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Variant's [c_out] takes ownership of the variant value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_output  < <  " godot_variant  "  < <  C_LOCAL_RET  "  =  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  C_CLASS_NATIVE_FUNCS  " .godotsharp_method_bind_call( " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  CS_PARAM_METHODBIND  " ,  "  < <  ( p_icall . is_static  ?  " IntPtr.Zero "  :  CS_PARAM_INSTANCE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ,  "  < <  ( p_icall . get_arguments_count ( )  ?  " (godot_variant**) "  C_LOCAL_PTRCALL_ARGS  :  " null " ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 19:42:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  " , total_length, out godot_variant_call_error vcall_error); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  base_indent  < <  " ExceptionUtils.DebugCheckCallError(caller " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ,  "  < <  ( p_icall . is_static  ?  " IntPtr.Zero "  :  CS_PARAM_INSTANCE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ,  "  < <  ( p_icall . get_arguments_count ( )  ?  " (godot_variant**) "  C_LOCAL_PTRCALL_ARGS  :  " null " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " , total_length, vcall_error); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-02 18:02:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ret_void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( return_type - > cname  ! =  name_cache . type_Variant )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( return_type - > cname  = =  name_cache . enum_Error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														r_output  < <  base_indent  < <  C_LOCAL_RET  "  = VariantUtils.ConvertToInt64( "  C_LOCAL_VARARG_RET  " ); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														// TODO: Use something similar to c_in_vararg (see usage above, with error if not implemented)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														CRASH_NOW_MSG ( " Custom VarArg return type not implemented:  "  +  return_type - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														r_output  < <  base_indent  < <  C_LOCAL_RET  "  =  "  C_LOCAL_VARARG_RET  " ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-02 18:02:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 00:41:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// MethodBind PtrCall
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  base_indent  < <  C_CLASS_NATIVE_FUNCS  " .godotsharp_method_bind_ptrcall( " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  CS_PARAM_METHODBIND  " ,  "  < <  ( p_icall . is_static  ?  " IntPtr.Zero "  :  CS_PARAM_INSTANCE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ,  "  < <  ( p_icall . get_arguments_count ( )  ?  C_LOCAL_PTRCALL_ARGS  :  " null " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  " ,  "  < <  ( ! ret_void  ?  " & "  C_LOCAL_RET  " ); \n "  :  " null); \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Return statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ret_void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( return_type - > c_out . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_output  < <  base_indent  < <  " return  "  C_LOCAL_RET  " ; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_output  < <  sformat ( return_type - > c_out ,  return_type - > c_type_out ,  C_LOCAL_RET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return_type - > name ,  String ( ) ,  String ( ) ,  base_indent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_icall . get_arguments_count ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_icall . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  vararg_arg  =  " arg "  +  argc_str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  real_argc_str  =  itos ( p_icall . get_arguments_count ( )  -  1 ) ;  // Arguments count without vararg
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_icall . get_arguments_count ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " int vararg_length =  "  < <  vararg_arg  < <  " .Length; \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT2  " int total_length =  "  < <  real_argc_str  < <  "  + vararg_length; \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ? \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-25 20:27:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT3  " stackalloc godot_variant.movable[VarArgsSpanThreshold] : \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT3  " new godot_variant.movable[vararg_length]; \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " Span<IntPtr>  "  C_LOCAL_PTRCALL_ARGS  " _span = total_length <= VarArgsSpanThreshold ? \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT3  " stackalloc IntPtr[VarArgsSpanThreshold] : \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT3  " new IntPtr[total_length]; \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " fixed (godot_variant.movable* varargs = &MemoryMarshal.GetReference(varargs_span)) \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT2  " fixed (IntPtr*  "  C_LOCAL_PTRCALL_ARGS  "  =  " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																" &MemoryMarshal.GetReference( "  C_LOCAL_PTRCALL_ARGS  " _span)) \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  OPEN_BLOCK_L2 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  c_in_statements . as_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT3  " for (int i = 0; i < vararg_length; i++)  "  OPEN_BLOCK 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT4  " varargs[i] =  "  < <  vararg_arg  < <  " [i].NativeVar; \n " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  INDENT4  C_LOCAL_PTRCALL_ARGS  " [ "  < <  real_argc_str  < <  "  + i] = new IntPtr(&varargs[i]); \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  CLOSE_BLOCK_L3 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											generate_call_and_return_stmts ( INDENT3 ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  CLOSE_BLOCK_L2 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_output  < <  c_in_statements . as_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " void**  "  C_LOCAL_PTRCALL_ARGS  "  = stackalloc void*[ " 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  argc_str  < <  " ] {  "  < <  c_args_var_content . as_string ( )  < <  "  }; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											generate_call_and_return_stmts ( INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										generate_call_and_return_stmts ( INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_output  < <  CLOSE_BLOCK_L1 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Error  BindingsGenerator : : _save_file ( const  String  & p_path ,  const  StringBuilder  & p_content )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Ref < FileAccess >  file  =  FileAccess : : open ( p_path ,  FileAccess : : WRITE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( file . is_null ( ) ,  ERR_FILE_CANT_WRITE ,  " Cannot open file: ' "  +  p_path  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									file - > store_string ( p_content . as_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-29 02:37:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  BindingsGenerator : : TypeInterface  * BindingsGenerator : : _get_type_or_null ( const  TypeReference  & p_typeref )  {  
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HashMap < StringName ,  TypeInterface > : : ConstIterator  builtin_type_match  =  builtin_types . find ( p_typeref . cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( builtin_type_match )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & builtin_type_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HashMap < StringName ,  TypeInterface > : : ConstIterator  obj_type_match  =  obj_types . find ( p_typeref . cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( obj_type_match )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & obj_type_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_typeref . is_enum )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < StringName ,  TypeInterface > : : ConstIterator  enum_match  =  enum_types . find ( p_typeref . cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( enum_match )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & enum_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < StringName ,  TypeInterface > : : ConstIterator  int_match  =  builtin_types . find ( name_cache . type_int ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( int_match ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & int_match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  BindingsGenerator : : TypeInterface  * BindingsGenerator : : _get_type_or_singleton_or_null ( const  TypeReference  & p_typeref )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  TypeInterface  * itype  =  _get_type_or_null ( p_typeref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( itype  = =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( itype - > is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StringName  instance_type_name  =  itype - > name  +  CS_SINGLETON_INSTANCE_SUFFIX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  & obj_types . find ( instance_type_name ) - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  itype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  String  BindingsGenerator : : _get_generic_type_parameters ( const  TypeInterface  & p_itype ,  const  List < TypeReference >  & p_generic_type_parameters )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_generic_type_parameters . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( p_itype . type_parameter_count  ! =  p_generic_type_parameters . size ( ) ,  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Generic type parameter count mismatch for type ' "  +  p_itype . name  +  " '. "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"  Found  "  +  itos ( p_generic_type_parameters . size ( ) )  +  " , but requires  "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													itos ( p_itype . type_parameter_count )  +  " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  params  =  " < " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  TypeReference  & param_type  :  p_generic_type_parameters )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  * param_itype  =  _get_type_or_singleton_or_null ( param_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( param_itype ,  " " ) ;  // Parameter type not found
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V_MSG ( param_itype - > is_singleton ,  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Generic type parameter is a singleton: ' "  +  param_itype - > name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_itype . api_type  = =  ClassDB : : API_CORE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( param_itype - > api_type  = =  ClassDB : : API_EDITOR ,  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Generic type parameter ' "  +  param_itype - > name  +  " ' has type from the editor API. "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															"  Core API cannot have dependencies on the editor API. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										params  + =  param_itype - > cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( i  <  p_generic_type_parameters . size ( )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											params  + =  " ,  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params  + =  " > " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringName  BindingsGenerator : : _get_type_name_from_meta ( Variant : : Type  p_type ,  GodotTypeInfo : : Metadata  p_meta )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_type  = =  Variant : : INT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  _get_int_type_name_from_meta ( p_meta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_type  = =  Variant : : FLOAT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  _get_float_type_name_from_meta ( p_meta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Variant : : get_type_name ( p_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringName  BindingsGenerator : : _get_int_type_name_from_meta ( GodotTypeInfo : : Metadata  p_meta )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_meta )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_INT8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " sbyte " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_INT16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " short " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_INT32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " int " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_INT64 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " long " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_UINT8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " byte " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_UINT16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " ushort " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_UINT32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " uint " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_INT_IS_UINT64 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " ulong " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Assume INT64
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " long " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								StringName  BindingsGenerator : : _get_float_type_name_from_meta ( GodotTypeInfo : : Metadata  p_meta )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_meta )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_REAL_IS_FLOAT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " float " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  GodotTypeInfo : : METADATA_REAL_IS_DOUBLE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Assume FLOAT64
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  BindingsGenerator : : _arg_default_value_is_assignable_to_type ( const  Variant  & p_val ,  const  TypeInterface  & p_arg_type )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_arg_type . name  = =  name_cache . type_Variant )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Variant can take anything
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_val . get_type ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : NIL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . is_object_type  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													name_cache . is_nullable_type ( p_arg_type . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_bool ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : INT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_sbyte  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_short  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_int  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_byte  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_ushort  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_uint  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_long  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_ulong  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_float  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_double  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . is_enum ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : FLOAT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_float  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_double ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : STRING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : STRING_NAME : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_String  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_StringName  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p_arg_type . name  = =  name_cache . type_NodePath ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : NODE_PATH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_NodePath ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : TRANSFORM2D : 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-28 03:36:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : TRANSFORM3D : 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : BASIS : 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-20 07:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : QUATERNION : 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PLANE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : AABB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : COLOR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : RECT2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR3 : 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-09 14:53:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : RID : 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_BYTE_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_INT32_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_INT64_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_FLOAT32_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_FLOAT64_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_STRING_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_VECTOR2_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_VECTOR3_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_COLOR_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : CALLABLE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : SIGNAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) )  | |  p_arg_type . cname  = =  name_cache . type_Array_generic ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : DICTIONARY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) )  | |  p_arg_type . cname  = =  name_cache . type_Dictionary_generic ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : OBJECT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . is_object_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR2I : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_Vector2  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : RECT2I : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_Rect2  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : VECTOR3I : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  p_arg_type . name  = =  name_cache . type_Vector3  | | 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p_arg_type . name  = =  Variant : : get_type_name ( p_val . get_type ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CRASH_NOW_MSG ( " Unexpected Variant type:  "  +  itos ( p_val . get_type ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 04:32:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  method_has_ptr_parameter ( MethodInfo  p_method_info )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_method_info . return_val . type  = =  Variant : : INT  & &  p_method_info . return_val . hint  = =  PROPERTY_HINT_INT_IS_POINTER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( PropertyInfo  arg  :  p_method_info . arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( arg . type  = =  Variant : : INT  & &  arg . hint  = =  PROPERTY_HINT_INT_IS_POINTER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  BindingsGenerator : : _populate_object_type_interfaces ( )  {  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									obj_types . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									List < StringName >  class_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ClassDB : : get_class_list ( & class_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									class_list . sort_custom < StringName : : AlphCompare > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( class_list . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										StringName  type_cname  =  class_list . front ( ) - > get ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ClassDB : : APIType  api_type  =  ClassDB : : get_api_type ( type_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( api_type  = =  ClassDB : : API_NONE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											class_list . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-18 17:28:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ignored_types . has ( type_cname ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_log ( " Ignoring type '%s' because it's in the list of ignored types \n " ,  String ( type_cname ) . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											class_list . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ClassDB : : is_class_exposed ( type_cname ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_log ( " Ignoring type '%s' because it's not exposed \n " ,  String ( type_cname ) . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											class_list . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-18 21:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ClassDB : : is_class_enabled ( type_cname ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_log ( " Ignoring type '%s' because it's not enabled \n " ,  String ( type_cname ) . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-18 21:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											class_list . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ClassDB : : ClassInfo  * class_info  =  ClassDB : : classes . getptr ( type_cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										TypeInterface  itype  =  TypeInterface : : create_object_type ( type_cname ,  pascal_to_pascal_case ( type_cname ) ,  api_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . base_name  =  ClassDB : : get_parent_class ( type_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-24 18:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . is_singleton  =  Engine : : get_singleton ( ) - > has_singleton ( type_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-08 15:13:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . is_instantiable  =  class_info - > creation_func  & &  ! itype . is_singleton ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 18:03:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . is_ref_counted  =  ClassDB : : is_parent_class ( type_cname ,  name_cache . type_RefCounted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . memory_own  =  itype . is_ref_counted ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( itype . is_singleton  & &  compat_singletons . has ( itype . cname ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . is_singleton  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . is_compat_singleton  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_out  =  " %5return  " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										itype . c_out  + =  C_METHOD_UNMANAGED_GET_MANAGED ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_out  + =  itype . is_ref_counted  ?  " (%1.Reference); \n "  :  " (%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_in_expr  =  " GodotObject. "  CS_STATIC_METHOD_GETINSTANCE  " (%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_out  =  " %5return (%2)%0(%1); " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-23 15:14:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_type  =  " IntPtr " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_type_out  =  " GodotObject " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Populate properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										List < PropertyInfo >  property_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ClassDB : : get_property_list ( type_cname ,  & property_list ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < StringName ,  StringName >  accessor_methods ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  PropertyInfo  & property  :  property_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-08 12:51:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( property . usage  &  PROPERTY_USAGE_GROUP  | |  property . usage  &  PROPERTY_USAGE_SUBGROUP  | |  property . usage  &  PROPERTY_USAGE_CATEGORY  | |  ( property . type  = =  Variant : : NIL  & &  property . usage  &  PROPERTY_USAGE_ARRAY ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 20:54:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( property . name . find ( " / " )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											PropertyInterface  iprop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											iprop . cname  =  property . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											iprop . setter  =  ClassDB : : get_property_setter ( type_cname ,  iprop . cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											iprop . getter  =  ClassDB : : get_property_getter ( type_cname ,  iprop . cname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iprop . setter  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												accessor_methods [ iprop . setter ]  =  iprop . cname ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( iprop . getter  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												accessor_methods [ iprop . getter ]  =  iprop . cname ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bool  valid  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											iprop . index  =  ClassDB : : get_property_index ( type_cname ,  iprop . cname ,  & valid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 20:54:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! valid ,  false ,  " Invalid property: ' "  +  itype . name  +  " . "  +  String ( iprop . cname )  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											iprop . proxy_name  =  escape_csharp_keyword ( snake_to_pascal_case ( iprop . cname ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Prevent the property and its enclosing type from sharing the same name
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( iprop . proxy_name  = =  itype . proxy_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_log ( " Name of property '%s' is ambiguous with the name of its enclosing class '%s'. Renaming property to '%s_' \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														iprop . proxy_name . utf8 ( ) . get_data ( ) ,  itype . proxy_name . utf8 ( ) . get_data ( ) ,  iprop . proxy_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												iprop . proxy_name  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											iprop . prop_doc  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  itype . class_doc - > properties . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  DocData : : PropertyDoc  & prop_doc  =  itype . class_doc - > properties [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( prop_doc . name  = =  iprop . cname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iprop . prop_doc  =  & prop_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . properties . push_back ( iprop ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Populate methods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										List < MethodInfo >  virtual_method_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ClassDB : : get_virtual_methods ( type_cname ,  & virtual_method_list ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										List < MethodInfo >  method_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ClassDB : : get_method_list ( type_cname ,  & method_list ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										method_list . sort ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  MethodInfo  & method_info  :  method_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											int  argc  =  method_info . arguments . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 12:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( method_info . name . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  cname  =  method_info . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( blacklisted_methods . find ( itype . cname )  & &  blacklisted_methods [ itype . cname ] . find ( cname ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 04:32:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( method_has_ptr_parameter ( method_info ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Pointers are not supported.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-24 11:40:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												itype . ignored_members . insert ( method_info . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-17 04:32:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											MethodInterface  imethod ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											imethod . name  =  method_info . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											imethod . cname  =  cname ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 01:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( method_info . flags  &  METHOD_FLAG_STATIC )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . is_static  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( method_info . flags  &  METHOD_FLAG_VIRTUAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												imethod . is_virtual  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												itype . has_virtual_methods  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PropertyInfo  return_info  =  method_info . return_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											MethodBind  * m  =  imethod . is_virtual  ?  nullptr  :  ClassDB : : get_method ( type_cname ,  method_info . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											imethod . is_vararg  =  m  & &  m - > is_vararg ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! m  & &  ! imethod . is_virtual )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_FAIL_COND_V_MSG ( ! virtual_method_list . find ( method_info ) ,  false , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														" Missing MethodBind for non-virtual method: ' "  +  itype . name  +  " . "  +  imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// A virtual method without the virtual flag. This is a special case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// There is no method bind, so let's fallback to Godot's object.Call(string, params)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . requires_object_call  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// The method Object.free is registered as a virtual method, but without the virtual flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// This is because this method is not supposed to be overridden, but called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We assume the return type is void.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . return_type . cname  =  name_cache . type_void ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Actually, more methods like this may be added in the future, which could return
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// something different. Let's put this check to notify us if that ever happens.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( itype . cname  ! =  name_cache . type_Object  | |  imethod . name  ! =  " free " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-07 09:44:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													WARN_PRINT ( " Notification: New unexpected virtual non-overridable method found. " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															   "  We only expected Object.free, but found ' "  + 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															itype . name  +  " . "  +  imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( return_info . type  = =  Variant : : INT  & &  return_info . usage  &  ( PROPERTY_USAGE_CLASS_IS_ENUM  |  PROPERTY_USAGE_CLASS_IS_BITFIELD ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  return_info . class_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . return_type . is_enum  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( return_info . class_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  return_info . class_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bool  bad_reference_hint  =  ! imethod . is_virtual  & &  return_info . hint  ! =  PROPERTY_HINT_RESOURCE_TYPE  & & 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 15:19:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ClassDB : : is_parent_class ( return_info . class_name ,  name_cache . type_RefCounted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_FAIL_COND_V_MSG ( bad_reference_hint ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														String ( )  +  " Return type is reference but hint is not ' "  _STR ( PROPERTY_HINT_RESOURCE_TYPE )  " '. "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																"  Are you returning a reference type by pointer? Method: ' "  +  itype . name  +  " . "  +  imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( return_info . type  = =  Variant : : ARRAY  & &  return_info . hint  = =  PROPERTY_HINT_ARRAY_TYPE )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  Variant : : get_type_name ( return_info . type )  +  " _@generic " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . generic_type_parameters . push_back ( TypeReference ( return_info . hint_string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( return_info . hint  = =  PROPERTY_HINT_RESOURCE_TYPE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  return_info . hint_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( return_info . type  = =  Variant : : NIL  & &  return_info . usage  &  PROPERTY_USAGE_NIL_IS_VARIANT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  name_cache . type_Variant ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( return_info . type  = =  Variant : : NIL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  name_cache . type_void ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 03:51:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  _get_type_name_from_meta ( return_info . type ,  m  ?  m - > get_argument_meta ( - 1 )  :  ( GodotTypeInfo : : Metadata ) method_info . return_val_metadata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  argc ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PropertyInfo  arginfo  =  method_info . arguments [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												String  orig_arg_name  =  arginfo . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ArgumentInterface  iarg ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												iarg . name  =  orig_arg_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( arginfo . type  = =  Variant : : INT  & &  arginfo . usage  &  ( PROPERTY_USAGE_CLASS_IS_ENUM  |  PROPERTY_USAGE_CLASS_IS_BITFIELD ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . class_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iarg . type . is_enum  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  if  ( arginfo . class_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . class_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( arginfo . type  = =  Variant : : ARRAY  & &  arginfo . hint  = =  PROPERTY_HINT_ARRAY_TYPE )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  Variant : : get_type_name ( arginfo . type )  +  " _@generic " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . generic_type_parameters . push_back ( TypeReference ( arginfo . hint_string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  if  ( arginfo . hint  = =  PROPERTY_HINT_RESOURCE_TYPE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . hint_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  if  ( arginfo . type  = =  Variant : : NIL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  name_cache . type_Variant ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 03:51:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  _get_type_name_from_meta ( arginfo . type ,  m  ?  m - > get_argument_meta ( i )  :  ( GodotTypeInfo : : Metadata ) method_info . get_argument_meta ( i ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												iarg . name  =  escape_csharp_keyword ( snake_to_camel_case ( iarg . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( m  & &  m - > has_default_argument ( i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													bool  defval_ok  =  _arg_default_value_from_variant ( m - > get_default_argument ( i ) ,  iarg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ERR_FAIL_COND_V_MSG ( ! defval_ok ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" Cannot determine default value for argument ' "  +  orig_arg_name  +  " ' of method ' "  +  itype . name  +  " . "  +  imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . add_argument ( iarg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( imethod . is_vararg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ArgumentInterface  ivararg ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ivararg . type . cname  =  name_cache . type_VarArg ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ivararg . name  =  " @args " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . add_argument ( ivararg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											imethod . proxy_name  =  escape_csharp_keyword ( snake_to_pascal_case ( imethod . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Prevent the method and its enclosing type from sharing the same name
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( imethod . proxy_name  = =  itype . proxy_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												_log ( " Name of method '%s' is ambiguous with the name of its enclosing class '%s'. Renaming method to '%s_' \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														imethod . proxy_name . utf8 ( ) . get_data ( ) ,  itype . proxy_name . utf8 ( ) . get_data ( ) ,  imethod . proxy_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . proxy_name  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											HashMap < StringName ,  StringName > : : Iterator  accessor  =  accessor_methods . find ( imethod . cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( accessor )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// We only make internal an accessor method if it's in the same class as the property.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// It's easier this way, but also we don't know if an accessor method in a different class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// could have other purposes, so better leave those untouched.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . is_internal  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( itype . class_doc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  itype . class_doc - > methods . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( itype . class_doc - > methods [ i ] . name  = =  imethod . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														imethod . method_doc  =  & itype . class_doc - > methods [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( itype . find_property_by_name ( imethod . cname ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Method name conflicts with property: ' "  +  itype . name  +  " . "  +  imethod . name  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Methods starting with an underscore are ignored unless they're used as a property setter or getter
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ! imethod . is_virtual  & &  imethod . name [ 0 ]  = =  ' _ ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( const  PropertyInterface  & iprop  :  itype . properties )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 02:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( iprop . setter  = =  imethod . name  | |  iprop . getter  = =  imethod . name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														imethod . is_internal  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														itype . methods . push_back ( imethod ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												itype . methods . push_back ( imethod ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Populate signals
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  HashMap < StringName ,  MethodInfo >  & signal_map  =  class_info - > signal_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  KeyValue < StringName ,  MethodInfo >  & E  :  signal_map )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											SignalInterface  isignal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  MethodInfo  & method_info  =  E . value ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											isignal . name  =  method_info . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											isignal . cname  =  method_info . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  argc  =  method_info . arguments . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  argc ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PropertyInfo  arginfo  =  method_info . arguments [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  orig_arg_name  =  arginfo . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ArgumentInterface  iarg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												iarg . name  =  orig_arg_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( arginfo . type  = =  Variant : : INT  & &  arginfo . usage  &  ( PROPERTY_USAGE_CLASS_IS_ENUM  |  PROPERTY_USAGE_CLASS_IS_BITFIELD ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . class_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iarg . type . is_enum  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( arginfo . class_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . class_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( arginfo . type  = =  Variant : : ARRAY  & &  arginfo . hint  = =  PROPERTY_HINT_ARRAY_TYPE )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  Variant : : get_type_name ( arginfo . type )  +  " _@generic " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . generic_type_parameters . push_back ( TypeReference ( arginfo . hint_string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( arginfo . hint  = =  PROPERTY_HINT_RESOURCE_TYPE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iarg . type . cname  =  arginfo . hint_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( arginfo . type  = =  Variant : : NIL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iarg . type . cname  =  name_cache . type_Variant ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 03:51:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  _get_type_name_from_meta ( arginfo . type ,  ( GodotTypeInfo : : Metadata ) method_info . get_argument_meta ( i ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												iarg . name  =  escape_csharp_keyword ( snake_to_camel_case ( iarg . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												isignal . add_argument ( iarg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											isignal . proxy_name  =  escape_csharp_keyword ( snake_to_pascal_case ( isignal . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Prevent the signal and its enclosing type from sharing the same name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( isignal . proxy_name  = =  itype . proxy_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_log ( " Name of signal '%s' is ambiguous with the name of its enclosing class '%s'. Renaming signal to '%s_' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														isignal . proxy_name . utf8 ( ) . get_data ( ) ,  itype . proxy_name . utf8 ( ) . get_data ( ) ,  isignal . proxy_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												isignal . proxy_name  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( itype . find_property_by_proxy_name ( isignal . proxy_name )  | |  itype . find_method_by_proxy_name ( isignal . proxy_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// ClassDB allows signal names that conflict with method or property names.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// While registering a signal with a conflicting name is considered wrong,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// it may still happen and it may take some time until someone fixes the name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We can't allow the bindings to be in a broken state while we wait for a fix;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// that's why we must handle this possibility by renaming the signal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												isignal . proxy_name  + =  " Signal " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( itype . class_doc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  itype . class_doc - > signals . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													const  DocData : : MethodDoc  & signal_doc  =  itype . class_doc - > signals [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( signal_doc . name  = =  isignal . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														isignal . method_doc  =  & signal_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . signals_ . push_back ( isignal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Populate enums and constants
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										List < String >  constants ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ClassDB : : get_integer_constant_list ( type_cname ,  & constants ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  HashMap < StringName ,  ClassDB : : ClassInfo : : EnumInfo >  & enum_map  =  class_info - > enum_map ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  KeyValue < StringName ,  ClassDB : : ClassInfo : : EnumInfo >  & E  :  enum_map )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											StringName  enum_proxy_cname  =  E . key ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  enum_proxy_name  =  pascal_to_pascal_case ( enum_proxy_cname . operator  String ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 12:47:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( itype . find_property_by_proxy_name ( enum_proxy_name )  | |  itype . find_method_by_proxy_name ( enum_proxy_name )  | |  itype . find_signal_by_proxy_name ( enum_proxy_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// In case the enum name conflicts with other PascalCase members,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// we append 'Enum' to the enum name in those cases.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We have several conflicts between enums and PascalCase properties.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												enum_proxy_name  + =  " Enum " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												enum_proxy_cname  =  StringName ( enum_proxy_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EnumInterface  ienum ( enum_proxy_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 20:25:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ienum . is_flags  =  E . value . is_bitfield ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 11:16:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  List < StringName >  & enum_constants  =  E . value . constants ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( const  StringName  & constant_cname  :  enum_constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												String  constant_name  =  constant_cname . operator  String ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int64_t  * value  =  class_info - > constant_map . getptr ( constant_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_FAIL_NULL_V ( value ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												constants . erase ( constant_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConstantInterface  iconstant ( constant_name ,  snake_to_pascal_case ( constant_name ,  true ) ,  * value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												iconstant . const_doc  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  i  =  0 ;  i  <  itype . class_doc - > constants . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													const  DocData : : ConstantDoc  & const_doc  =  itype . class_doc - > constants [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( const_doc . name  = =  iconstant . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														iconstant . const_doc  =  & const_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ienum . constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  prefix_length  =  _determine_enum_prefix ( ienum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_apply_prefix_to_enum_constants ( ienum ,  prefix_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . enums . push_back ( ienum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											TypeInterface  enum_itype ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . is_enum  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . name  =  itype . name  +  " . "  +  String ( E . key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . cname  =  StringName ( enum_itype . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . proxy_name  =  itype . proxy_name  +  " . "  +  enum_proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											TypeInterface : : postsetup_enum_type ( enum_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_types . insert ( enum_itype . cname ,  enum_itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( const  String  & constant_name  :  constants )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64_t  * value  =  class_info - > constant_map . getptr ( StringName ( constant_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_NULL_V ( value ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 12:47:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  constant_proxy_name  =  snake_to_pascal_case ( constant_name ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( itype . find_property_by_proxy_name ( constant_proxy_name )  | |  itype . find_method_by_proxy_name ( constant_proxy_name )  | |  itype . find_signal_by_proxy_name ( constant_proxy_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// In case the constant name conflicts with other PascalCase members,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// we append 'Constant' to the constant name in those cases.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												constant_proxy_name  + =  " Constant " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ConstantInterface  iconstant ( constant_name ,  constant_proxy_name ,  * value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											iconstant . const_doc  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( int  i  =  0 ;  i  <  itype . class_doc - > constants . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  DocData : : ConstantDoc  & const_doc  =  itype . class_doc - > constants [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( const_doc . name  = =  iconstant . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													iconstant . const_doc  =  & const_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 16:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( itype . is_singleton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Add singleton instance type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . proxy_name  + =  CS_SINGLETON_INSTANCE_SUFFIX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . is_singleton  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . is_singleton_instance  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Remove constants and enums, those will remain in the static class.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . constants . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . enums . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											obj_types . insert ( itype . name  +  CS_SINGLETON_INSTANCE_SUFFIX ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										class_list . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  BindingsGenerator : : _arg_default_value_from_variant ( const  Variant  & p_val ,  ArgumentInterface  & r_iarg )  {  
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_iarg . def_param_value  =  p_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_iarg . default_argument  =  p_val . operator  String ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_val . get_type ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : NIL : 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 17:34:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Either Object type or Variant
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " default " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Atomic types
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  bool ( p_val )  ?  " true "  :  " false " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : INT : 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( r_iarg . type . cname  ! =  name_cache . type_int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 21:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " (%s)( "  +  r_iarg . default_argument  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											 
										 
										
											2020-02-24 15:20:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : FLOAT : 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( r_iarg . type . cname  = =  name_cache . type_float )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  + =  " f " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : STRING : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : STRING_NAME : 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : NODE_PATH : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( r_iarg . type . cname  = =  name_cache . type_StringName  | |  r_iarg . type . cname  = =  name_cache . type_NodePath )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( r_iarg . default_argument . length ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_iarg . default_argument  =  " (%s) \" "  +  r_iarg . default_argument  +  " \" " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_REF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// No need for a special `in` statement to change `null` to `""`. Marshaling takes care of this already.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													r_iarg . default_argument  =  " null " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												CRASH_COND ( r_iarg . type . cname  ! =  name_cache . type_String ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " \" "  +  r_iarg . default_argument  +  " \" " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PLANE :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Plane  plane  =  p_val . operator  Plane ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-25 09:54:50 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new Plane(new Vector3 "  +  plane . normal . operator  String ( )  +  " ,  "  +  rtos ( plane . d )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : AABB :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AABB  aabb  =  p_val . operator  : : AABB ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new Aabb(new Vector3 "  +  aabb . position . operator  String ( )  +  " , new Vector3 "  +  aabb . size . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : RECT2 :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Rect2  rect  =  p_val . operator  Rect2 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 01:13:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new Rect2(new Vector2 "  +  rect . position . operator  String ( )  +  " , new Vector2 "  +  rect . size . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : RECT2I :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Rect2i  rect  =  p_val . operator  Rect2i ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new Rect2I(new Vector2I "  +  rect . position . operator  String ( )  +  " , new Vector2I "  +  rect . size . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : COLOR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR2 : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : VECTOR2I : 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR3 : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : VECTOR3I : 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new %s "  +  r_iarg . default_argument ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
											
												Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
											 
										 
										
											2022-07-20 01:11:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : VECTOR4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : VECTOR4I : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " new %s "  +  r_iarg . default_argument ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : OBJECT : 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . is_zero ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' can only have null/zero as the default value. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " null " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : DICTIONARY : 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . operator  Dictionary ( ) . is_empty ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Default value of type 'Dictionary' must be an empty dictionary. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The [cs_in] expression already interprets null values as empty dictionaries.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " null " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : CONSTANT ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-09 14:53:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : RID : 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( r_iarg . type . cname  ! =  name_cache . type_RID ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' cannot have a default value of type ' "  +  String ( name_cache . type_RID )  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . is_zero ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' can only have null/zero as the default value. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " default " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  Variant : : ARRAY : 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . operator  Array ( ) . is_empty ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Default value of type 'Array' must be an empty array. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The [cs_in] expression already interprets null values as empty arrays.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " null " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : CONSTANT ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 13:46:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_BYTE_ARRAY : 
							 
						 
					
						
							
								
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											 
										 
										
											2020-02-24 15:20:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_INT32_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_INT64_ARRAY : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_FLOAT32_ARRAY : 
							 
						 
					
						
							
								
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											 
										 
										
											2020-02-24 15:20:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_FLOAT64_ARRAY : 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-17 18:06:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : PACKED_STRING_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_VECTOR2_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_VECTOR3_ARRAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PACKED_COLOR_ARRAY : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 13:46:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " Array.Empty<%s>() " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_REF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : TRANSFORM2D :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Transform2D  transform  =  p_val . operator  Transform2D ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( transform  = =  Transform2D ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Transform2D.Identity " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 16:59:24 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Transform2D(new Vector2 "  +  transform . columns [ 0 ] . operator  String ( )  +  " , new Vector2 "  +  transform . columns [ 1 ] . operator  String ( )  +  " , new Vector2 "  +  transform . columns [ 2 ] . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-28 03:36:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : TRANSFORM3D :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 01:08:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Transform3D  transform  =  p_val . operator  Transform3D ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( transform  = =  Transform3D ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-26 23:26:56 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Transform3D.Identity " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Basis  basis  =  transform . basis ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-26 23:26:56 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Transform3D(new Vector3 "  +  basis . get_column ( 0 ) . operator  String ( )  +  " , new Vector3 "  +  basis . get_column ( 1 ) . operator  String ( )  +  " , new Vector3 "  +  basis . get_column ( 2 ) . operator  String ( )  +  " , new Vector3 "  +  transform . origin . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
											
												Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
											 
										 
										
											2022-07-20 01:11:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : PROJECTION :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-04 11:44:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Projection  projection  =  p_val . operator  Projection ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( projection  = =  Projection ( ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
											 
										 
										
											2022-07-20 01:11:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Projection.Identity " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-04 11:44:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Projection(new Vector4 "  +  projection . columns [ 0 ] . operator  String ( )  +  " , new Vector4 "  +  projection . columns [ 1 ] . operator  String ( )  +  " , new Vector4 "  +  projection . columns [ 2 ] . operator  String ( )  +  " , new Vector4 "  +  projection . columns [ 3 ] . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
									
										
										
											
												Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
											 
										 
										
											2022-07-20 01:11:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  Variant : : BASIS :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Basis  basis  =  p_val . operator  Basis ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( basis  = =  Basis ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Basis.Identity " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Basis(new Vector3 "  +  basis . get_column ( 0 ) . operator  String ( )  +  " , new Vector3 "  +  basis . get_column ( 1 ) . operator  String ( )  +  " , new Vector3 "  +  basis . get_column ( 2 ) . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-20 07:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : QUATERNION :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Quaternion  quaternion  =  p_val . operator  Quaternion ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( quaternion  = =  Quaternion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Quaternion.Identity " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-20 07:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Quaternion "  +  quaternion . operator  String ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-24 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : CALLABLE : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-20 11:18:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( r_iarg . type . cname  ! =  name_cache . type_Callable ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' cannot have a default value of type ' "  +  String ( name_cache . type_Callable )  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . is_zero ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' can only have null/zero as the default value. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " default " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  Variant : : SIGNAL : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-20 11:18:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( r_iarg . type . cname  ! =  name_cache . type_Signal ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' cannot have a default value of type ' "  +  String ( name_cache . type_Signal )  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_COND_V_MSG ( ! p_val . is_zero ( ) ,  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Parameter of type ' "  +  String ( r_iarg . type . cname )  +  " ' can only have null/zero as the default value. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_iarg . default_argument  =  " default " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_V_MSG ( false ,  " Unexpected Variant type:  "  +  itos ( p_val . get_type ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( r_iarg . def_param_mode  = =  ArgumentInterface : : CONSTANT  & &  r_iarg . type . cname  = =  name_cache . type_Variant  & &  r_iarg . default_argument  ! =  " default " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r_iarg . def_param_mode  =  ArgumentInterface : : NULLABLE_VAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _populate_builtin_type_interfaces ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									builtin_types . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TypeInterface  itype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define INSERT_STRUCT_TYPE(m_type, m_proxy_name)                                          \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{                                                                                      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface : : create_value_type ( String ( # m_type ) ,  String ( # m_proxy_name ) ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_in_expr  =  " &%0 " ;                                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_in_expr_is_unsafe  =  true ;                                                 \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										builtin_types . insert ( itype . cname ,  itype ) ;                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector2 ,  Vector2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector2i ,  Vector2I ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Rect2 ,  Rect2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Rect2i ,  Rect2I ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Transform2D ,  Transform2D ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector3 ,  Vector3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector3i ,  Vector3I ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Basis ,  Basis ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Quaternion ,  Quaternion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Transform3D ,  Transform3D ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( AABB ,  Aabb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Color ,  Color ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Plane ,  Plane ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector4 ,  Vector4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector4i ,  Vector4I ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Projection ,  Projection ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef INSERT_STRUCT_TYPE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-25 23:44:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// bool
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface : : create_value_type ( String ( " bool " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " %0.ToGodotBool() " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:23:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_out  =  " %5return %0(%1).ToBool(); " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type  =  " godot_bool " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . c_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromBool(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-25 23:44:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Integer types
 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-17 21:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// C interface for 'uint32_t' is the same as that of enums. Remember to apply
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// any of the changes done here to 'TypeInterface::postsetup_enum_type' as well.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define INSERT_INT_TYPE(m_name, m_int_struct_name)                                             \ 
  
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{                                                                                           \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface : : create_value_type ( String ( m_name ) ) ;                               \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( itype . name  ! =  " long "  & &  itype . name  ! =  " ulong " )  {                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_in  =  " %5%0 %1_in = %1; \n " ;                                                  \
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 21:53:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . c_out  =  " %5return (%0)(%1); \n " ;                                               \
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . c_type  =  " long " ;                                                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_arg_in  =  " &%s_in " ;                                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  {                                                                                \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_arg_in  =  " &%s " ;                                                             \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}                                                                                       \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_in  =  itype . name ;                                                           \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_out  =  itype . name ;                                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromInt(%1); \n " ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										builtin_types . insert ( itype . cname ,  itype ) ;                                               \
							 
						 
					
						
							
								
									
										
										
										
											2018-10-17 21:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// The expected type for all integers in ptrcall is 'int64_t', so that's what we use for 'c_type'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " sbyte " ,  " Int8 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " short " ,  " Int16 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " int " ,  " Int32 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " long " ,  " Int64 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " byte " ,  " UInt8 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " ushort " ,  " UInt16 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " uint " ,  " UInt32 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INSERT_INT_TYPE ( " ulong " ,  " UInt64 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# undef INSERT_INT_TYPE 
  
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Floating point types
 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-17 21:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// float
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . name  =  " float " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . proxy_name  =  " float " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The expected type for 'float' in ptrcall is 'double'
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . c_in  =  " %5%0 %1_in = %1; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_out  =  " %5return (%0)%1; \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . c_type  =  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_type_in  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_out  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromFloat(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// double
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . name  =  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . proxy_name  =  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_type  =  " double " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_in  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_out  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromFloat(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 20:24:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-17 21:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// String
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " String " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  " string " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_in  =  " %5using %0 %1_in =  "  C_METHOD_MONOSTR_TO_GODOT  " (%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_out  =  " %5return  "  C_METHOD_MONOSTR_FROM_GODOT  " (%1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  " godot_string " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromString(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// StringName
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " StringName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  " StringName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " (%1)(%0?.NativeValue ?? default) " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Cannot pass null StringName to ptrcall
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_out  =  " %5return %0.CreateTakingOwnershipOfDisposableValue(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type  =  " godot_string_name " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_in_vararg  =  " %5using godot_variant %1_in = VariantUtils.CreateFromStringName(%1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  false ;  // [c_out] takes ownership
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_ret_needs_default_initialization  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// NodePath
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " NodePath " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  " NodePath " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " (%1)(%0?.NativeValue ?? default) " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Cannot pass null NodePath to ptrcall
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_out  =  " %5return %0.CreateTakingOwnershipOfDisposableValue(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type  =  " godot_node_path " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  false ;  // [c_out] takes ownership
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_ret_needs_default_initialization  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// RID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " RID " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  " Rid " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Variant
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Variant " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  " Variant " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_in  =  " %5%0 %1_in = (%0)%1.NativeVar; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_out  =  " %5return Variant.CreateTakingOwnershipOfDisposableValue(%1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  " godot_variant " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  false ;  // [c_out] takes ownership
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_ret_needs_default_initialization  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Callable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface : : create_value_type ( String ( " Callable " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " %0 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_in  =  " %5using %0 %1_in =  "  C_METHOD_MANAGED_TO_CALLABLE  " (in %1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_out  =  " %5return  "  C_METHOD_MANAGED_FROM_CALLABLE  " (in %1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  " godot_callable " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  " in  "  +  itype . cs_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Signal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Signal " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-23 19:28:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  " Signal " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " %0 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_in  =  " %5using %0 %1_in =  "  C_METHOD_MANAGED_TO_SIGNAL  " (in %1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-10 01:42:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_out  =  " %5return  "  C_METHOD_MANAGED_FROM_SIGNAL  " (in %1); \n " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  " godot_signal " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  " in  "  +  itype . cs_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// VarArg (fictitious type to represent variable arguments)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " VarArg " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  " Variant[] " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_type  =  " params Variant[] " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " %0 ?? Array.Empty<Variant>() " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// c_type, c_in and c_arg_in are hard-coded in the generator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// c_out and c_type_out are not applicable to VarArg.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s_in " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 17:41:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  " Variant[] " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define INSERT_ARRAY_FULL(m_name, m_type, m_managed_type, m_proxy_t)                \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{                                                                                \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface ( ) ;                                                     \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . name  =  # m_name ;                                                        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cname  =  itype . name ;                                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . proxy_name  =  # m_proxy_t  " [] " ;                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_type  =  itype . proxy_name ;                                            \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_in  =  " %5using %0 %1_in =  "  C_METHOD_MONOARRAY_TO ( m_type )  " (%1); \n " ;  \
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_out  =  " %5return  "  C_METHOD_MONOARRAY_FROM ( m_type )  " (%1); \n " ;         \
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . c_arg_in  =  " &%s_in " ;                                                   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type  =  # m_managed_type ;                                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_in  =  itype . proxy_name ;                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_out  =  itype . proxy_name ;                                         \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_is_disposable_struct  =  true ;                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										builtin_types . insert ( itype . name ,  itype ) ;                                     \
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define INSERT_ARRAY(m_type, m_managed_type, m_proxy_t) INSERT_ARRAY_FULL(m_type, m_type, m_managed_type, m_proxy_t) 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedInt32Array ,  godot_packed_int32_array ,  int ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedInt64Array ,  godot_packed_int64_array ,  long ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_ARRAY_FULL ( PackedByteArray ,  PackedByteArray ,  godot_packed_byte_array ,  byte ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedFloat32Array ,  godot_packed_float32_array ,  float ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedFloat64Array ,  godot_packed_float64_array ,  double ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedStringArray ,  godot_packed_string_array ,  string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedColorArray ,  godot_packed_color_array ,  Color ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedVector2Array ,  godot_packed_vector2_array ,  Vector2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_ARRAY ( PackedVector3Array ,  godot_packed_vector3_array ,  Vector3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef INSERT_ARRAY 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-18 23:07:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Array
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Array " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . type_parameter_count  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_type  =  BINDINGS_NAMESPACE_COLLECTIONS  " . "  +  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " (%1)(%0 ?? new()).NativeValue " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_out  =  " %5return %0.CreateTakingOwnershipOfDisposableValue(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type  =  " godot_array " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  false ;  // [c_out] takes ownership
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_ret_needs_default_initialization  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Array_@generic
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-07 12:59:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reuse Array's itype
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . name  =  " Array_@generic " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_out  =  " %5return new %2(%0(%1)); " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-01 01:45:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For generic Godot collections, Variant.From<T>/As<T> is slower, so we need this special case
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-23 19:28:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToArray(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-01 01:45:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromArray(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-18 23:07:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Dictionary
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Dictionary " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . proxy_name  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:56:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . type_parameter_count  =  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 20:39:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_type  =  BINDINGS_NAMESPACE_COLLECTIONS  " . "  +  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_in_expr  =  " (%1)(%0 ?? new()).NativeValue " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_out  =  " %5return %0.CreateTakingOwnershipOfDisposableValue(%1); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_arg_in  =  " &%s " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type  =  " godot_dictionary " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . cs_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_is_disposable_struct  =  false ;  // [c_out] takes ownership
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_ret_needs_default_initialization  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Dictionary_@generic
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-07 12:59:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reuse Dictionary's itype
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . name  =  " Dictionary_@generic " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_out  =  " %5return new %2(%0(%1)); " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-01 01:45:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For generic Godot collections, Variant.From<T>/As<T> is slower, so we need this special case
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-23 19:28:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToDictionary(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-01 01:45:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromDictionary(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// void (fictitious type to represent the return type of methods that do not return anything)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " void " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  itype . name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type  =  itype . proxy_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . c_type_in  =  itype . c_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . c_type_out  =  itype . c_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _populate_global_constants ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  global_constants_count  =  CoreConstants : : get_global_constant_count ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( global_constants_count  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashMap < String ,  DocData : : ClassDoc > : : Iterator  match  =  EditorHelp : : get_doc_data ( ) - > class_list . find ( " @GlobalScope " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-09 03:39:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CRASH_COND_MSG ( ! match ,  " Could not find '@GlobalScope' in DocData. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  DocData : : ClassDoc  & global_scope_doc  =  match - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  global_constants_count ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  constant_name  =  CoreConstants : : get_global_constant_name ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  DocData : : ConstantDoc  * const_doc  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-03 00:56:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  ( int  j  =  0 ;  j  <  global_scope_doc . constants . size ( ) ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												const  DocData : : ConstantDoc  & curr_const_doc  =  global_scope_doc . constants [ j ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( curr_const_doc . name  = =  constant_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													const_doc  =  & curr_const_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 12:47:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64_t  constant_value  =  CoreConstants : : get_global_constant_value ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											StringName  enum_name  =  CoreConstants : : get_global_constant_enum ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConstantInterface  iconstant ( constant_name ,  snake_to_pascal_case ( constant_name ,  true ) ,  constant_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											iconstant . const_doc  =  const_doc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( enum_name  ! =  StringName ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EnumInterface  ienum ( enum_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 16:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ienum . is_flags  =  CoreConstants : : is_global_constant_bitfield ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:10:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												List < EnumInterface > : : Element  * enum_match  =  global_enums . find ( ienum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( enum_match )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													enum_match - > get ( ) . constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ienum . constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													global_enums . push_back ( ienum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												global_constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( EnumInterface  & ienum  :  global_enums )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											TypeInterface  enum_itype ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . is_enum  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . name  =  ienum . cname . operator  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . cname  =  ienum . cname ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . proxy_name  =  pascal_to_pascal_case ( enum_itype . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											TypeInterface : : postsetup_enum_type ( enum_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_types . insert ( enum_itype . cname ,  enum_itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  prefix_length  =  _determine_enum_prefix ( ienum ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ienum . cname  = =  name_cache . enum_Error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( prefix_length  >  0 )  {  // Just in case it ever changes
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ERR_PRINT ( " Prefix for enum ' "  _STR ( Error )  " ' is not empty. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												prefix_length  =  1 ;  // 'ERR_'
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 19:41:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_apply_prefix_to_enum_constants ( ienum ,  prefix_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HARDCODED
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									List < StringName >  hardcoded_enums ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector2.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector2I.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector3.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector3I.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  StringName  & enum_cname  :  hardcoded_enums )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// These enums are not generated and must be written manually (e.g.: Vector3.Axis)
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Here, we assume core types do not begin with underscore
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										TypeInterface  enum_itype ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_itype . is_enum  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 18:45:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_itype . name  =  enum_cname . operator  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										enum_itype . cname  =  enum_cname ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 16:11:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_itype . proxy_name  =  pascal_to_pascal_case ( enum_itype . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										TypeInterface : : postsetup_enum_type ( enum_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_types . insert ( enum_itype . cname ,  enum_itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _initialize_blacklisted_methods ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blacklisted_methods [ " Object " ] . push_back ( " to_string " ) ;  // there is already ToString
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blacklisted_methods [ " Object " ] . push_back ( " _to_string " ) ;  // override ToString instead
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blacklisted_methods [ " Object " ] . push_back ( " _init " ) ;  // never called in C# (TODO: implement it)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _initialize_compat_singletons ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// No compat singletons yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  BindingsGenerator : : _log ( const  char  * p_format ,  . . . )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( log_print_enabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										va_list  list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										va_start ( list ,  p_format ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OS : : get_singleton ( ) - > print ( " %s " ,  str_format ( p_format ,  list ) . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										va_end ( list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : _initialize ( )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initialized  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 14:02:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									EditorHelp : : generate_doc ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									enum_types . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_initialize_blacklisted_methods ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-14 20:22:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_initialize_compat_singletons ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  obj_type_ok  =  _populate_object_type_interfaces ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_MSG ( ! obj_type_ok ,  " Failed to generate object type interfaces " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									_populate_builtin_type_interfaces ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_populate_global_constants ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate internal calls (after populating type interfaces and global constants)
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 10:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  KeyValue < StringName ,  TypeInterface >  & E  :  obj_types )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  TypeInterface  & itype  =  E . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error  err  =  _populate_method_icalls_table ( itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_MSG ( err  ! =  OK ,  " Failed to generate icalls table for type:  "  +  itype . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 15:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									initialized  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  generate_all_glue_option  =  " --generate-mono-glue " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  handle_cmdline_options ( String  glue_dir_path )  {  
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BindingsGenerator  bindings_generator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bindings_generator . set_log_print_enabled ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! bindings_generator . is_initialized ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_PRINT ( " Failed to initialize the bindings generator " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CRASH_COND ( glue_dir_path . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-29 19:34:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bindings_generator . generate_cs_api ( glue_dir_path . path_join ( API_SOLUTION_NAME ) )  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_PRINT ( generate_all_glue_option  +  " : Failed to generate the C# API. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  cleanup_and_exit_godot ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Exit once done
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Main : : cleanup ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									: : exit ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  BindingsGenerator : : handle_cmdline_args ( const  List < String >  & p_cmdline_args )  {  
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  glue_dir_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 01:16:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									const  List < String > : : Element  * elem  =  p_cmdline_args . front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( elem )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( elem - > get ( )  = =  generate_all_glue_option )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											const  List < String > : : Element  * path_elem  =  elem - > next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( path_elem )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												glue_dir_path  =  path_elem - > get ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												elem  =  elem - > next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ERR_PRINT ( generate_all_glue_option  +  " : No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue'). " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Exit once done with invalid command line arguments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cleanup_and_exit_godot ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 09:44:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										elem  =  elem - > next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( glue_dir_path . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										handle_cmdline_options ( glue_dir_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Exit once done
 
							 
						 
					
						
							
								
									
										
											 
										
											
												C#: Move marshaling logic and generated glue to C#
We will be progressively moving most code to C#.
The plan is to only use Mono's embedding APIs to set things at launch.
This will make it much easier to later support CoreCLR too which
doesn't have rich embedding APIs.
Additionally the code in C# is more maintainable and makes it easier
to implement new features, e.g.: runtime codegen which we could use to
avoid using reflection for marshaling everytime a field, property or
method is accessed.
SOME NOTES ON INTEROP
We make the same assumptions as GDNative about the size of the Godot
structures we use. We take it a bit further by also assuming the layout
of fields in some cases, which is riskier but let's us squeeze out some
performance by avoiding unnecessary managed to native calls.
Code that deals with native structs is less safe than before as there's
no RAII and copy constructors in C#. It's like using the GDNative C API
directly. One has to take special care to free values they own.
Perhaps we could use roslyn analyzers to check this, but I don't know
any that uses attributes to determine what's owned or borrowed.
As to why we maily use pointers for native structs instead of ref/out:
- AFAIK (and confirmed with a benchmark) ref/out are pinned
  during P/Invoke calls and that has a cost.
- Native struct fields can't be ref/out in the first place.
- A `using` local can't be passed as ref/out, only `in`. Calling a
  method or property on an `in` value makes a silent copy, so we want
  to avoid `in`.
REGARDING THE BUILD SYSTEM
There's no longer a `mono_glue=yes/no` SCons options. We no longer
need to build with `mono_glue=no`, generate the glue and then build
again with `mono_glue=yes`. We build only once and generate the glue
(which is in C# now).
However, SCons no longer builds the C# projects for us. Instead one
must run `build_assemblies.py`, e.g.:
```sh
%godot_src_root%/modules/mono/build_scripts/build_assemblies.py \
        --godot-output-dir=%godot_src_root%/bin \
        --godot-target=release_debug`
```
We could turn this into a custom build target, but I don't know how
to do that with SCons (it's possible with Meson).
OTHER NOTES
Most of the moved code doesn't follow the C# naming convention and
still has the word Mono in the names despite no longer dealing with
Mono's embedding APIs. This is just temporary while transitioning,
to make it easier to understand what was moved where.
											 
										 
										
											2021-05-03 15:21:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cleanup_and_exit_godot ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 15:45:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif