2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  bindings_generator.cpp                                               */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                       This file is part of:                           */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                           GODOT ENGINE                                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                      https://godotengine.org                          */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2022-01-03 21:27:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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" 
  
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/string/ucaps.h" 
  
						 
					
						
							
								
									
										
										
										
											2021-02-22 11:06:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "main/main.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../godotsharp_defs.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../utils/path_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../utils/string_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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" 
  
						 
					
						
							
								
									
										
										
										
											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" 
  
						 
					
						
							
								
									
										
											 
										
											
												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_" 
  
						 
					
						
							
								
									
										
										
										
											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#.
  
						 
					
						
							
								
									
										
										
										
											2022-09-04 10:32:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  Vector < String >  ignored_types  =  {  " PhysicsServer2DExtension " ,  " PhysicsServer3DExtension "  } ;  
						 
					
						
							
								
									
										
										
										
											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 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r_enum_itype . c_out  =  " %5return (%0)%1; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  snake_to_pascal_case ( const  String  & p_identifier ,  bool  p_input_is_upper  =  false )  {  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									String  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < String >  parts  =  p_identifier . split ( " _ " ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  parts . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  part  =  parts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( part . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											part [ 0 ]  =  _find_upper ( part [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p_input_is_upper )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  j  =  1 ;  j  <  part . length ( ) ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													part [ j ]  =  _find_lower ( part [ j ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ret  + =  part ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( i  = =  0  | |  i  = =  ( parts . size ( )  -  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Preserve underscores at the beginning and end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Preserve contiguous underscores
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( parts [ i  -  1 ] . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ret  + =  " __ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ret  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  snake_to_camel_case ( const  String  & p_identifier ,  bool  p_input_is_upper  =  false )  {  
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									String  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < String >  parts  =  p_identifier . split ( " _ " ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  parts . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  part  =  parts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( part . length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												part [ 0 ]  =  _find_upper ( part [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_input_is_upper )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												for  ( int  j  =  i  ! =  0  ?  1  :  0 ;  j  <  part . length ( ) ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													part [ j ]  =  _find_lower ( part [ j ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ret  + =  part ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( i  = =  0  | |  i  = =  ( parts . size ( )  -  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Preserve underscores at the beginning and end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Preserve contiguous underscores
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( parts [ i  -  1 ] . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ret  + =  " __ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ret  + =  " _ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														xml_output . append ( " <para> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( lines [ i ] . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( i  ! =  lines . size ( )  -  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( i  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														xml_output . append ( " <para> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													xml_output . append ( lines [ i ] . xml_escape ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 04:03:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( i  ! =  lines . size ( )  -  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 21:59:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " [ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( code_tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " [ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_pos  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 16:24:35 +01: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  " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We use System.Object for Variant, so there is no Variant type in C#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												xml_output . append ( " <c>Variant</c> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  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 " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// bold is not supported in xml comments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pos  =  brk_end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tag_stack . push_front ( tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tag  = =  " i " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// italics is not supported in xml comments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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> " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// underline is not supported in xml comments
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xml_output . append ( " [ " ) ;  // ignore
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve method reference for non-Godot.Object type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_PRINT ( " Cannot resolve method reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve member reference for non-Godot.Object type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_PRINT ( " Cannot resolve member reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve signal reference for non-Godot.Object type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_PRINT ( " Cannot resolve signal reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_PRINT ( " Cannot resolve enum reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												OS : : get_singleton ( ) - > print ( " Cannot resolve constant reference for non-Godot.Object type in documentation: %s \n " ,  p_link_target . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ERR_PRINT ( " Cannot resolve constant reference in documentation: ' "  +  p_link_target  +  " '. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												_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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector2i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ARRAY_ALL ( Vector3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p_output . append ( 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  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( 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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Some Godot.Object assertions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output . append ( "  :  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output . append ( obj_types [ itype . base_name ] . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											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  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-04 05:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Add the type name and the singleton pointer as static fields
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " private static Godot.Object singleton; \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public static Godot.Object  "  CS_PROPERTY_SINGLETON  " \n "  INDENT1  " { \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT2  " get \n "  INDENT2  " { \n "  INDENT3  " if (singleton == null) \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  INDENT4  " singleton =  "  C_METHOD_ENGINE_GET_SINGLETON  " (typeof( " 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 . proxy_name 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   < <  " ).Name); \n "  INDENT3  " return singleton; \n "  INDENT2  " } \n "  INDENT1  " } \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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " private static readonly StringName  "  BINDINGS_NATIVE_NAME_FIELD  "  =  \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// IMPORTANT: We also generate the static fields for Godot.Object instead of declaring
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// them manually in the `Object.base.cs` partial class declaration, because they're
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 name static field
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( is_derived_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  MEMBER_BEGIN  " private static readonly System.Type CachedType = typeof( "  < <  itype . proxy_name  < <  " ); \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 20:21:15 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( MEMBER_BEGIN  " private static readonly StringName  "  BINDINGS_NATIVE_NAME_FIELD  "  =  \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output . append ( itype . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output . append ( " \" ; \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// TODO: Only generate HasGodotClassMethod and InvokeGodotClassMethod if there's any method
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Generate InvokeGodotClassMethod
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " protected internal  "  < <  ( is_derived_type  ?  " override "  :  " virtual " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  "  bool  "  CS_METHOD_INVOKE_GODOT_CLASS_METHOD  " (in godot_string_name method,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   < <  " NativeVariantPtrArgs args, int argCount, 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 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   < <  " ) && argCount ==  "  < <  itos ( imethod . arguments . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   < <  "  &&  "  < <  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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											output  < <  INDENT2  " return base. "  CS_METHOD_INVOKE_GODOT_CLASS_METHOD  " (method, args, argCount, 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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 " ; 
							 
						 
					
						
							
								
									
										
										
										
											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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public new class PropertyName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .PropertyName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public class PropertyName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  PropertyInterface  & iprop  :  itype . properties )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  INDENT2  " public static readonly StringName  "  < <  iprop . proxy_name  < <  "  =  \" "  < <  iprop . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//MethodName
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public new class MethodName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .MethodName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public class MethodName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  MethodInterface  & imethod  :  itype . methods )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  INDENT2  " public static readonly StringName  "  < <  imethod . proxy_name  < <  "  =  \" "  < <  imethod . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  INDENT1  " } \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//SignalName
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_inherit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public new class SignalName :  "  < <  obj_types [ itype . base_name ] . proxy_name  < <  " .SignalName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  MEMBER_BEGIN  " public class SignalName " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									output  < <  " \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   < <  INDENT1  " { \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  SignalInterface  & isignal  :  itype . signals_ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  < <  INDENT2  " public static readonly StringName  "  < <  isignal . proxy_name  < <  "  =  \" "  < <  isignal . cname  < <  " \" ; \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  TypeInterface  * prop_itype  =  _get_type_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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( INDENT2  " get \n " 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																" #pragma warning disable CS0618 // Disable warning about obsolete method \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " ); \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												CLOSE_BLOCK_L2 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" #pragma warning restore CS0618 \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  ( setter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( INDENT2  " set \n " 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																" #pragma warning disable CS0618 // Disable warning about obsolete method \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-19 01:10:08 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " value); \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												CLOSE_BLOCK_L2 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														// TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														" #pragma warning restore CS0618 \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-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 )  {  
						 
					
						
							
								
									
										
											 
										
											
												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_imethod . return_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_itype . cs_in . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cs_in_statements  < <  sformat ( p_itype . cs_in ,  p_itype . c_type ,  " this " , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													String ( ) ,  String ( ) ,  String ( ) ,  INDENT2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										icall_params  + =  " ,  "  +  sformat ( p_itype . cs_in_expr ,  " this " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Singletons are static classes. They don't derive Godot.Object,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so we need to specify the type to call the static method.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p_output  < <  " Object. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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
 
							 
						 
					
						
							
								
									
										
										
										
											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  + =  " ,  " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 ( " \" )] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  delegate_name  =  p_isignal . proxy_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delegate_name  + =  " EventHandler " ;  // Delegate name is [SignalName]EventHandler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( p_isignal . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " , new Callable(value)); \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-25 23:07:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( p_isignal . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p_output . append ( " , new Callable(value)); \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 + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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_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 " ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 < <  " , total_length, out _); \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 " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  INDENT3  " stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() : \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 < <  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-02-27 21:57:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r_output  < <  INDENT2  " using var variantSpanDisposer = new VariantSpanDisposer(varargs_span); \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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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  * param_itype  =  _get_type_or_null ( param_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_NULL_V ( param_itype ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										TypeInterface  itype  =  TypeInterface : : create_object_type ( type_cname ,  api_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . base_name  =  ClassDB : : get_parent_class ( type_cname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-13 21:46:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . is_singleton  =  Engine : : get_singleton ( ) - > has_singleton ( itype . proxy_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " (%1)VariantUtils.ConvertToGodotObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFromGodotObject(%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( itype . is_singleton )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . cs_in_expr  =  " Object. "  CS_STATIC_METHOD_GETINSTANCE  " ( "  CS_PROPERTY_SINGLETON  " ) " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-28 23:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											itype . cs_in_expr  =  " Object. "  CS_STATIC_METHOD_GETINSTANCE  " (%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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); " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_arg_in  =  " (void*)%s " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type  =  " IntPtr " ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02: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  =  " Object " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												imethod . return_type . cname  =  _get_type_name_from_meta ( return_info . type ,  m  ?  m - > get_argument_meta ( - 1 )  :  GodotTypeInfo : : METADATA_NONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  _get_type_name_from_meta ( arginfo . type ,  m  ?  m - > get_argument_meta ( i )  :  GodotTypeInfo : : METADATA_NONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  PropertyInterface  * accessor_property  =  itype . find_property_by_name ( accessor - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 17:11:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We only deprecate 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_deprecated  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												imethod . deprecation_message  =  imethod . proxy_name  +  "  is deprecated. Use the  "  +  accessor_property - > proxy_name  +  "  property instead. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-01 00:40:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													iarg . type . cname  =  _get_type_name_from_meta ( arginfo . type ,  GodotTypeInfo : : METADATA_NONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											String  enum_proxy_name  =  enum_proxy_cname . operator  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( itype . find_property_by_proxy_name ( enum_proxy_cname ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We have several conflicts between enums and PascalCase properties,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so we append 'Enum' to the enum name in those cases.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . cs_variant_to_managed  =  " (%1)VariantUtils.ConvertToInt32(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . cs_managed_to_variant  =  " VariantUtils.CreateFromInt((int)%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . constants . push_back ( iconstant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj_types . insert ( itype . cname ,  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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " (%s) "  +  r_iarg . default_argument ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 01:13:00 -04: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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 01:13:00 -04: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 :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Projection  transform  =  p_val . operator  Projection ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( transform  = =  Projection ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " Projection.Identity " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_iarg . default_argument  =  " new Projection(new Vector4 "  +  transform . matrix [ 0 ] . operator  String ( )  +  " , new Vector4 "  +  transform . matrix [ 1 ] . operator  String ( )  +  " , new Vector4 "  +  transform . matrix [ 2 ] . operator  String ( )  +  " , new Vector4 "  +  transform . matrix [ 3 ] . operator  String ( )  +  " ) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											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-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define INSERT_STRUCT_TYPE(m_type)                                     \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{                                                                   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype  =  TypeInterface : : create_value_type ( String ( # m_type ) ) ;      \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_in  =  # m_type  " * " ;                                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . c_type_out  =  itype . cs_type ;                               \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_in_expr  =  " &%0 " ;                                       \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_in_expr_is_unsafe  =  true ;                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " VariantUtils.ConvertTo%2(%0) " ;   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFrom%2(%0) " ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										builtin_types . insert ( itype . cname ,  itype ) ;                       \
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector2i ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Rect2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Rect2i ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Transform2D ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector3 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector3i ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Basis ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-20 07:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Quaternion ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 01:08:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Transform3D ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 21:48:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( AABB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Color ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Plane ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												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_STRUCT_TYPE ( Vector4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( Vector4i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INSERT_STRUCT_TYPE ( 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 " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToBool(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromBool(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ;                                                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											itype . c_out  =  " %5return (%0)%1; \n " ;                                                 \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 " ;  \
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " VariantUtils.ConvertTo "  m_int_struct_name  " (%0) " ;        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFromInt(%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " VariantUtils.ConvertToFloat32(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFromFloat(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " VariantUtils.ConvertToFloat64(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFromFloat(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToStringObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromString(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToStringNameObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromStringName(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToNodePathObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromNodePath(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  " RID " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToRID(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromRID(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " Variant.CreateCopyingBorrowed(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " %0.CopyNativeVariant() " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToCallableManaged(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromCallable(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 19:20:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Signal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype  =  TypeInterface ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Signal " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . proxy_name  =  " SignalInfo " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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  "  C_METHOD_MANAGED_FROM_SIGNAL  " (&%1); \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToSignalInfo(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromSignalInfo(%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ;                                    \
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										itype . cs_variant_to_managed  =  " VariantUtils.ConvertAs%2ToSystemArray(%0) " ;   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itype . cs_managed_to_variant  =  " VariantUtils.CreateFrom%2(%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToArrayObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromArray(%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Array_@generic
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Re-use Array's itype
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Array_@generic " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_out  =  " %5return new %2(%0(%1)); " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									itype . cs_variant_to_managed  =  " VariantUtils.ConvertToDictionaryObject(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_managed_to_variant  =  " VariantUtils.CreateFromDictionary(%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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									builtin_types . insert ( itype . cname ,  itype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Dictionary_@generic
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Re-use Dictionary's itype
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . name  =  " Dictionary_@generic " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cname  =  itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									itype . cs_out  =  " %5return new %2(%0(%1)); " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-24 20:25:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// TODO: ienum.is_flags is always false for core constants since they don't seem to support bitfield enums
 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . proxy_name  =  enum_itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											TypeInterface : : postsetup_enum_type ( enum_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											enum_itype . cs_variant_to_managed  =  " (%1)VariantUtils.ConvertToInt32(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											enum_itype . cs_managed_to_variant  =  " VariantUtils.CreateFromInt((int)%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector2i.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardcoded_enums . push_back ( " Vector3.Axis " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-03 04:42:20 -05: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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-28 22:25:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_itype . proxy_name  =  enum_itype . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										TypeInterface : : postsetup_enum_type ( enum_itype ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-27 21:57:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum_itype . cs_variant_to_managed  =  " (%1)VariantUtils.ConvertToInt32(%0) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										enum_itype . cs_managed_to_variant  =  " VariantUtils.CreateFromInt((int)%0) " ; 
							 
						 
					
						
							
								
									
										
										
										
											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)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-02 23:24:00 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									EditorHelp : : generate_doc ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-24 03:17:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									enum_types . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-24 00:40:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_initialize_blacklisted_methods ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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