diff --git a/.gitignore b/.gitignore index aa955b9..eaec275 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -# Typical location for CMake build files and Visual Studio 2017 generated directories -/cmake -/NativeScript.dir -/x64 +# Rider IDE +.idea + +# Unity upgrade logs +Unity/Logs \ No newline at end of file diff --git a/README.md b/README.md index 08c33a6..8b108f6 100644 --- a/README.md +++ b/README.md @@ -2,33 +2,70 @@ A library to allow writing Unity scripts in native code: C, C++, assembly. +## Purpose + +This project aims to give you a viable alternative to C#. Scripting in C++ isn't right for all parts of every project, but now it's an option. + +## Goals + +* Make scripting in C++ as easy as C# +* Low performance overhead +* Easy integration with any Unity project +* Fast compile, build, and code generation times +* Don't lose support from Unity Technologies + # Reasons to Prefer C++ Over C# # -By using C++ directly, you gain complete control over the code the CPU will execute. It's much easier to generate optimal code with a C++ compiler than with a C# compiler, IL2CPP, and finally a C++ compiler. You can even code with compiler intrinsics or assembly to directly write machine code and take advantage of CPU features like [SIMD](http://jacksondunstan.com/articles/3890) and hardware AES encryption for massive performance gains. +## Fast Device Build Times + +Changing one line of C# code requires you to make a new build of the game. Typical Android build times tend to be at least 10 minutes because IL2CPP has to run and then a huge amount of C++ must be compiled. + +By using C++, we can compile the game as a C++ plugin in about 1 second, swap the plugin into the APK, and then immediately install and run the game. That's a huge productivity boost! + +## Fast Compile Times + +C++ [compiles much more quickly](https://github.com/jacksondunstan/cscppcompiletimes) than C#. Incremental builds when just one file changes-- the most common builds-- can be 15x faster than with C#. Faster compilation adds up over time to productivity gains. Quicker iteration times make it easier to stay in the "flow" of programming. + +## No Garbage Collector + +Unity's garbage collector is mandatory and has a lot of problems. It's slow, runs on the main thread, collects all garbage at once, fragments the heap, and never shrinks the heap. So your game will experience "frame hitches" and eventually you'll run out of memory and crash. + +A significant amount of effort is required to work around the GC and the resulting code is difficult to maintain and slow. This includes techniques like [object pools](https://jacksondunstan.com/articles/3829), which essentially make memory management manual. You've also got to avoid boxing value types like `int` to to managed types like `object`, not use `foreach` loops in some situations, and various other [gotchas](https://jacksondunstan.com/articles/3850). + +C++ has no required garbage collector and features optional automatic memory management via "smart pointer" types like [shared_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr). It offers excellent alternatives to Unity's primitive garbage collector. + +While using some .NET APIs will still involve garbage creation, the problem is contained to only those APIs rather than being a pervasive issue for all your code. -C++ is also a much larger language than C# and some developers will prefer having more tools at their disposal. Here are a few differences: +## Total Control + +By using C++ directly, you gain complete control over the code the CPU will execute. It's much easier to generate optimal code with a C++ compiler than with a C# compiler, IL2CPP, and finally a C++ compiler. Cut out the middle-man and you can take advantage of compiler intrinsics or assembly to directly write machine code using powerful CPU features like [SIMD](https://jacksondunstan.com/articles/3890) and hardware AES encryption for massive performance gains. + +## More Features + +C++ is a much larger language than C# and some developers will prefer having more tools at their disposal. Here are a few differences: * Its template system is much more powerful than C# generics * There are macros for extreme flexibility by generating code -* Function pointers instead of just delegates +* Cheap function pointers instead of heavyweight delegates * No-overhead [algorithms](http://en.cppreference.com/w/cpp/algorithm) instead of LINQ * Bit fields for easy memory savings -* Pointers and never-null references instead of just managed referneces +* Pointers and never-null references instead of just managed references * Much more. C++ is huge. -There are also some problems with C# code running under Unity that you'll automatically avoid. For one, Unity's garbage collector is very slow. It runs on the main thread, which blocks rendering and input handling. It collects all objects at once, which causes frame hitches. And it fragments memory, so eventually you may run out and crash. - -A significant amount of effort is required to work around the GC and the resulting code is difficult to maintain and slow. This includes techniques like [object pools](http://jacksondunstan.com/articles/3829), which essentially make memory management manual. You've also got to avoid boxing value types to managed types, `foreach` loops in some situations, and various other [gotchas](http://jacksondunstan.com/articles/3850). +## No IL2CPP Surprises -C++ has no required garbage collector and features optional automatic memory management via "smart pointer" types like [shared_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr). It offers an excellent alternative to Unity's primitive garbage collector. +While IL2CPP transforms C# into C++ already, it generates a lot of overhead. There are many [surprises](https://jacksondunstan.com/articles/3916) if you read through the generated C++. For example, there's overhead for any function using a static variable and an extra two pointers are stored at the beginning of every class. The same goes for all sorts of features such as `sizeof()`, mandatory null checks, and so forth. Instead, you could write C++ directly and not need to work around IL2CPP. -While IL2CPP transforms C# into C++ already, it generates a lot of overhead. There are many [surprises](http://jacksondunstan.com/articles/3916) if you read through the generated C++. For example, there's overhead for any function using a static variable and an extra two pointers are stored at the beginning of every class. The same goes for all sorts of features such as `sizeof()`, mandatory null checks, and so forth. Instead, you could write C++ directly and not need to work around IL2CPP. +## Industry Standard Language -This project aims to give you a viable alternative to C#. Scripting in C++ isn't right for every project, but now it's an option. +C++ is the standard language for video games as well as many other fields. By programming in C++ you can more easily transfer your skills and code to and from non-Unity projects. For example, you can avoid lock-in by using the same language (C++) that you'd use in the [Unreal](https://www.unrealengine.com) or [Lumberyard](https://aws.amazon.com/lumberyard/) engines. -# Features +# UnityNativeScripting Features -* Supports Windows, macOS, iOS, and Android (editor and standalone) +* Code generator exposes any C# API to C++ +* Supports Windows, macOS, Linux, iOS, and Android (editor and standalone) +* Works with Unity 2017.x and 5.x +* Plays nice with other C# scripts- no need to use 100% C++ * Object-oriented API just like in C# > @@ -37,24 +74,68 @@ This project aims to give you a viable alternative to C#. Scripting in C++ isn't Vector3 position(1.0f, 2.0f, 3.0f); transform.SetPosition(position); -* No need to reload the Unity editor when changing C++ -* Code generator exposes any C# API (Unity, .NET, custom DLLs) with a simple JSON config file +* Hot reloading: change C++ without restarting the game * Handle `MonoBehaviour` messages in C++ > void MyScript::Start() { - Debug::Log(String("MyScript has started")); + String message("MyScript has started"); + Debug::Log(message); } -* Platform-dependent compilation via the [usual flags](https://docs.unity3d.com/Manual/PlatformDependentCompilation.html) (e.g. `#if UNITY_EDITOR`) +* Platform-dependent compilation (e.g. `#if TARGET_OS_ANDROID`) * [CMake](https://cmake.org/) build system sets up any IDE project or command-line build +# Code Generator + +The core of this project is a code generator. It generates C# and C++ code called "bindings" that make C# APIs available to C++ game code. It supports a wide range of language features: + +* Types + * `class` + * `struct` + * `enum` + * Arrays (single- and multi-dimensional) + * Delegates (e.g. `Action`) + * `decimal` +* Type Contents + * Constructors + * Methods + * Fields + * Properties (`get` and `set` like `obj.x`) + * Indexers (`get` and `set` like `obj[x]`) + * Events (`add` and `remove` delegates) + * Overloaded operators + * Boxing and unboxing (e.g. casting `int` to `object` and visa versa) +* Function Features + * `out` and `ref` parameters + * Generic types and methods + * Default parameters +* Cross-Language Features + * Exceptions (C# to C++ and C++ to C#) + * Implementing C# interfaces with C++ classes + * Deriving from C# classes with C++ classes + +Note that the code generator does not yet support: + +* `Array`, `string`, and `object` methods (e.g. `GetHashCode`) +* Non-null string default parameters and null non-string default parameters +* Implicit `params` parameter (a.k.a. "var args") passing +* C# pointers +* Nested types +* Down-casting + +To configure the code generator, open `Unity/Assets/NativeScriptTypes.json` and notice the existing examples. Add on to this file to expose more C# APIs from Unity, .NET, or custom DLLs to your C++ code. + +To run the code generator, choose `NativeScript > Generate Bindings` from the Unity editor. + # Performance -[Article](http://jacksondunstan.com/articles/3952). +Almost all projects will see a net performance win by reducing garbage collection, eliminating IL2CPP overhead, and access to compiler intrinsics and assembly. Calls from C++ into C# incur only a minor performance penalty. In the rare case that almost all of your code is calls to .NET APIs then you may experience a net performance loss. -tl;dr - Most projects will not be noticeably impacted by C++ overhead and many projects will benefit from reducing garbage collection and IL2CPP overhead. +[Testing and benchmarks article](https://jacksondunstan.com/articles/3952) + +[Optimizations article](https://jacksondunstan.com/articles/4311) # Project Structure @@ -76,15 +157,12 @@ With C++, the workflow looks like this: 3. Switch to the Unity editor window. Nothing to compile. 4. Run the game -One of the project's goals is to make it just as easy to work with C++ as it is to work with C#, if not easier. - # Getting Started 1. Download or clone this repo 2. Copy everything in `Unity/Assets` directory to your Unity project's `Assets` directory -3. Copy the `Unity/CppSource` directory to your Unity project directory -4. Edit `NativeScriptTypes.json` and specify what parts of the Unity API you want access to from C++. Some examples are provided, but feel free to delete them if you're not using those features. -5. Edit `Unity/CppSource/Game/Game.cpp` to create your game. Some example code is provided, but feel free to delete it. You can add more C++ source (`.cpp`) and header (`.h`) files here as your game grows. +3. Edit `NativeScriptTypes.json` and specify what parts of the Unity, .NET, and custom DLL APIs you want access to from C++. +4. Edit `Unity/Assets/CppSource/Game/Game.cpp` and `Unity/Assets/CppSource/Game/Game.h` to create your game. Some example code is provided, but feel free to delete it. You can add more C++ source (`.cpp`) and header (`.h`) files here as your game grows. # Building the C++ Plugin @@ -114,7 +192,7 @@ One of the project's goals is to make it just as easy to work with C++ as it is 2. Create a directory for build files. Anywhere is fine. 3. Open a Command Prompt by clicking the Start button, typing "Command Prompt", then clicking the app 4. Execute `cd /path/to/your/build/directory` -5. Execute `cmake -G "Visual Studio VERSION YEAR Win64" -DEDITOR=TRUE /path/to/your/project/CppSource`. Replace `VERSION` and `YEAR` with the version of Visual Studio you want to use. To see the options, execute `cmake --help` and look at the list at the bottom. For example, use `"`Visual Studio 15 2017 Win64` for Visual Studio 2017. Any version, including Community, works just fine. Remove `-DEDITOR=TRUE` for standalone builds. +5. Execute `cmake -G "Visual Studio VERSION YEAR Win64" -DEDITOR=TRUE /path/to/your/project/CppSource`. Replace `VERSION` and `YEAR` with the version of Visual Studio you want to use. To see the options, execute `cmake --help` and look at the list at the bottom. For example, use `"Visual Studio 15 2017 Win64"` for Visual Studio 2017. Any version, including Community, works just fine. Remove `-DEDITOR=TRUE` for standalone builds. If you are using Visual Studio 2019, execute `cmake -G "Visual Studio 16" -A "x64" -DEDITOR=TRUE /path/to/your/project/CppSource` instead. 6. The project files are now generated in your build directory 7. Open `NativeScript.sln` and click `Build > Build Solution`. @@ -138,62 +216,17 @@ One of the project's goals is to make it just as easy to work with C++ as it is 6. The build scripts or IDE project files are now generated in your build directory 7. Build as appropriate for your generator. For example, execute `make` if you chose `Unix Makefiles` as your generator. -# The Code Generator - -To run the code generator, choose `NativeScript > Generate Bindings` from the Unity editor. - -To configure the code generator, open `NativeScriptTypes.json` and notice the existing examples. Add on to this file to expose more C# APIs from Unity, .NET, or custom DLLs to your C++ code. - -The code generator supports: - -* Class types (i.e. Classes with methods, etc. Parameters, etc. are fine.) -* Constructors -* Methods -* Fields -* Properties (getters and setters) -* Generic return types -* `MonoBehaviour` classes with "message" functions (except `OnAudioFilterRead`) - -The code generator does not support (yet): - -* Struct types -* Arrays (single- or multi-dimensional) -* Generic functions and types -* `out` and `ref` parameters -* Delegates -* `MonoBehaviour` contents (e.g. fields) except for "message" functions - -The JSON file is laid out as follows: - -* Path - Absolute path to the DLL -* Types - Array of types in the DLL to generate - * Name - Name of the type including namespace (e.g. `UnityEngine.GameObject`) - * Constructors - Array of constructors to generate - * Types - Parameter types of the constructor including namespace - * Methods - Array of methods to generate - * Name - Name of the method - * ParamTypes - Parameter types to the method including namespace - * GenericTypes - Sets of type parameters to generate - * Name - Name of the type parameter (e.g. `T`) - * Type - Type to generate for the type parameter including namespace - * Properties - Array of property names to generate - * Fields - Array of field names to generate -* MonoBehaviours - * Name - Name of the `MonoBehaviour` class to generate - * Namespace - Namespace to put the `MonoBehaviour` class in - * Messages - Array of message names to generate (e.g. `Update`) - # Updating To A New Version To update to a new version of this project, overwrite your Unity project's `Assets/NativeScript` directory with this project's `Unity/Assets/NativeScript` directory and re-run the code generator. # Reference -[Articles](http://jacksondunstan.com/articles/3938) by the author describing the development of this project. +[Articles](https://jacksondunstan.com/articles/3938) by the author describing the development of this project. # Author -[Jackson Dunstan](http://jacksondunstan.com) +[Jackson Dunstan](https://jacksondunstan.com) # Contributing diff --git a/Unity/Assets/CppSource.meta b/Unity/Assets/CppSource.meta new file mode 100644 index 0000000..a8346ff --- /dev/null +++ b/Unity/Assets/CppSource.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ec1b3d1da421646d781f3ccc6960a558 +folderAsset: yes +timeCreated: 1525538114 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/CppSource/CMakeLists.txt b/Unity/Assets/CppSource/CMakeLists.txt similarity index 68% rename from Unity/CppSource/CMakeLists.txt rename to Unity/Assets/CppSource/CMakeLists.txt index 73a28d6..2baa025 100644 --- a/Unity/CppSource/CMakeLists.txt +++ b/Unity/Assets/CppSource/CMakeLists.txt @@ -3,29 +3,29 @@ project(NativeScript CXX) # Set platform-dependent compilation defines matching C# if (EDITOR) - add_definitions(-DUNITY_EDITOR) + add_definitions(-DTARGET_OS_EDITOR) if (WIN32) - add_definitions(-DUNITY_EDITOR_WIN) + add_definitions(-DTARGET_OS_EDITOR_WIN) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_definitions(-DUNITY_EDITOR_OSX) + add_definitions(-DTARGET_OS_EDITOR_OSX) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - add_definitions(-DUNITY_EDITOR_LINUX) + add_definitions(-DTARGET_OS_EDITOR_LINUX) endif() else() - add_definitions(-DUNITY_STANDALONE) + add_definitions(-DTARGET_OS_STANDALONE) if (WIN32) - add_definitions(-DUNITY_STANDALONE_WIN) + add_definitions(-DTARGET_OS_WIN) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_definitions(-DUNITY_STANDALONE_OSX) + add_definitions(-DTARGET_OS_OSX) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - add_definitions(-DUNITY_STANDALONE_LINUX) + add_definitions(-DTARGET_OS_LINUX) endif() endif() if (IOS) - add_definitions(-DUNITY_IOS) + add_definitions(-DTARGET_OS_IPHONE) endif() if (ANDROID_NDK) - add_definitions(-DUNITY_ANDROID) + add_definitions(-DTARGET_OS_ANDROID) endif() # Use NDK on Android @@ -36,22 +36,22 @@ endif() # Set output path if (ANDROID_NDK) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Android) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Android) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Android) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Plugins/Android) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Plugins/Android) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Plugins/Android) elseif (IOS) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Assets/Plugins/iOS) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Assets/Plugins/iOS) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Assets/Plugins/iOS) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Plugins/.iOS) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Plugins/.iOS) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Plugins/.iOS) elseif (WIN32 OR (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) if (EDITOR) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Editor) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Editor) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Assets/Plugins/Editor) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Plugins/Editor) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Plugins/Editor) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Plugins/Editor) else() - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Assets/Plugins) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Assets/Plugins) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Assets/Plugins) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../Plugins) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/../Plugins) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/../Plugins) endif() endif() @@ -75,6 +75,13 @@ set( # Build a library. If on an Apple platform, build it in a bundle. add_library(${PROJECT_NAME} MODULE ${SOURCES}) set_target_properties(${PROJECT_NAME} PROPERTIES BUNDLE TRUE) +if (IOS) + set_xcode_property(${PROJECT_NAME} ENABLE_BITCODE "NO") +endif() + +if(WIN32 AND MINGW) + set_property(TARGET ${PROJECT_NAME} PROPERTY PREFIX "") +endif() # Enable C++11 set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) \ No newline at end of file diff --git a/Unity/Assets/CppSource/CMakeLists.txt.meta b/Unity/Assets/CppSource/CMakeLists.txt.meta new file mode 100644 index 0000000..3ecd08d --- /dev/null +++ b/Unity/Assets/CppSource/CMakeLists.txt.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ff824f6dad1204438ac5993f133fa551 +timeCreated: 1525538114 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/Game.meta b/Unity/Assets/CppSource/Game.meta new file mode 100644 index 0000000..7121431 --- /dev/null +++ b/Unity/Assets/CppSource/Game.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5097e8d235bbf426abeae3e4fc76859f +folderAsset: yes +timeCreated: 1525538114 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/Game/Game.cpp b/Unity/Assets/CppSource/Game/Game.cpp new file mode 100644 index 0000000..a8baeff --- /dev/null +++ b/Unity/Assets/CppSource/Game/Game.cpp @@ -0,0 +1,85 @@ +/// +/// Game-specific code for the native plugin +/// +/// +/// Jackson Dunstan, 2017, http://JacksonDunstan.com +/// +/// +/// MIT +/// + +#include "Bindings.h" +#include "Game.h" + +using namespace System; +using namespace UnityEngine; + +namespace +{ + struct GameState + { + float BallDir; + }; + + GameState* gameState; +} + +namespace MyGame +{ + void BallScript::Update() + { + Transform transform = GetTransform(); + Vector3 pos = transform.GetPosition(); + const float speed = 1.2f; + const float min = -1.5f; + const float max = 1.5f; + float distance = Time::GetDeltaTime() * speed * gameState->BallDir; + Vector3 offset(distance, 0, 0); + Vector3 newPos = pos + offset; + if (newPos.x > max) + { + gameState->BallDir *= -1.0f; + newPos.x = max - (newPos.x - max); + if (newPos.x < min) + { + newPos.x = min; + } + } + else if (newPos.x < min) + { + gameState->BallDir *= -1.0f; + newPos.x = min + (min - newPos.x); + if (newPos.x > max) + { + newPos.x = max; + } + } + transform.SetPosition(newPos); + } +} + +// Called when the plugin is initialized +// This is mostly full of test code. Feel free to remove it all. +void PluginMain( + void* memory, + int32_t memorySize, + bool isFirstBoot) +{ + gameState = (GameState*)memory; + if (isFirstBoot) + { + String message("Game booted up"); + Debug::Log(message); + + // The ball initially goes right + gameState->BallDir = 1.0f; + + // Create the ball game object out of a sphere primitive + GameObject go = GameObject::CreatePrimitive(PrimitiveType::Sphere); + String name("GameObject with a BallScript"); + go.SetName(name); + + // Attach the ball script to make it bounce back and forth + go.AddComponent(); + } +} diff --git a/Unity/Assets/CppSource/Game/Game.cpp.meta b/Unity/Assets/CppSource/Game/Game.cpp.meta new file mode 100644 index 0000000..6bcf89c --- /dev/null +++ b/Unity/Assets/CppSource/Game/Game.cpp.meta @@ -0,0 +1,26 @@ +fileFormatVersion: 2 +guid: cd5ee8d1b4f5748ed98f1f7cd17c386d +timeCreated: 1525538114 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/Game/Game.h b/Unity/Assets/CppSource/Game/Game.h new file mode 100644 index 0000000..79d31ad --- /dev/null +++ b/Unity/Assets/CppSource/Game/Game.h @@ -0,0 +1,23 @@ +/// +/// Declaration of the game types the bindings layer needs to know about +/// +/// +/// Jackson Dunstan, 2018, http://JacksonDunstan.com +/// +/// +/// MIT +/// + +#pragma once + +#include "Bindings.h" + +namespace MyGame +{ + struct BallScript : MyGame::BaseBallScript + { + MY_GAME_BALL_SCRIPT_DEFAULT_CONTENTS + MY_GAME_BALL_SCRIPT_DEFAULT_CONSTRUCTOR + void Update() override; + }; +} diff --git a/Unity/Assets/CppSource/Game/Game.h.meta b/Unity/Assets/CppSource/Game/Game.h.meta new file mode 100644 index 0000000..c81ed01 --- /dev/null +++ b/Unity/Assets/CppSource/Game/Game.h.meta @@ -0,0 +1,26 @@ +fileFormatVersion: 2 +guid: 568849c22711c4c4aaaf09df05a1d812 +timeCreated: 1525538114 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/NativeScript.meta b/Unity/Assets/CppSource/NativeScript.meta new file mode 100644 index 0000000..a82c5d8 --- /dev/null +++ b/Unity/Assets/CppSource/NativeScript.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c48669dd52f8e49b890586dd9a417de5 +folderAsset: yes +timeCreated: 1525538114 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/NativeScript/Bindings.cpp b/Unity/Assets/CppSource/NativeScript/Bindings.cpp new file mode 100644 index 0000000..8cb2e2e --- /dev/null +++ b/Unity/Assets/CppSource/NativeScript/Bindings.cpp @@ -0,0 +1,6349 @@ +/// +/// Internals of the bindings between native and .NET code. +/// Game code shouldn't go here. +/// +/// +/// Jackson Dunstan, 2017, http://JacksonDunstan.com +/// +/// +/// MIT +/// + +// Game type definitions +#include "Game.h" + +// Type definitions +#include "Bindings.h" + +// For assert() +#include + +// For memset(), etc. +#include + +// Macro to put before functions that need to be exposed to C# +#ifdef _WIN32 + #define DLLEXPORT extern "C" __declspec(dllexport) +#else + #define DLLEXPORT extern "C" +#endif + +//////////////////////////////////////////////////////////////// +// C# functions for C++ to call +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + void (*ReleaseObject)(int32_t handle); + int32_t (*StringNew)(const char* chars); + void (*SetException)(int32_t handle); + int32_t (*ArrayGetLength)(int32_t handle); + int32_t (*EnumerableGetEnumerator)(int32_t handle); + + /*BEGIN FUNCTION POINTERS*/ + void (*ReleaseSystemDecimal)(int32_t handle); + int32_t (*SystemDecimalConstructorSystemDouble)(double value); + int32_t (*SystemDecimalConstructorSystemUInt64)(uint64_t value); + int32_t (*BoxDecimal)(int32_t valHandle); + int32_t (*UnboxDecimal)(int32_t valHandle); + UnityEngine::Vector3 (*UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle)(float x, float y, float z); + UnityEngine::Vector3 (*UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3)(UnityEngine::Vector3& a, UnityEngine::Vector3& b); + int32_t (*BoxVector3)(UnityEngine::Vector3& val); + UnityEngine::Vector3 (*UnboxVector3)(int32_t valHandle); + int32_t (*UnityEngineObjectPropertyGetName)(int32_t thisHandle); + void (*UnityEngineObjectPropertySetName)(int32_t thisHandle, int32_t valueHandle); + int32_t (*UnityEngineComponentPropertyGetTransform)(int32_t thisHandle); + UnityEngine::Vector3 (*UnityEngineTransformPropertyGetPosition)(int32_t thisHandle); + void (*UnityEngineTransformPropertySetPosition)(int32_t thisHandle, UnityEngine::Vector3& value); + int32_t (*SystemCollectionsIEnumeratorPropertyGetCurrent)(int32_t thisHandle); + int32_t (*SystemCollectionsIEnumeratorMethodMoveNext)(int32_t thisHandle); + int32_t (*UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript)(int32_t thisHandle); + int32_t (*UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType)(UnityEngine::PrimitiveType type); + void (*UnityEngineDebugMethodLogSystemObject)(int32_t messageHandle); + int32_t (*UnityEngineMonoBehaviourPropertyGetTransform)(int32_t thisHandle); + int32_t (*SystemExceptionConstructorSystemString)(int32_t messageHandle); + int32_t (*BoxPrimitiveType)(UnityEngine::PrimitiveType val); + UnityEngine::PrimitiveType (*UnboxPrimitiveType)(int32_t valHandle); + float (*UnityEngineTimePropertyGetDeltaTime)(); + void (*ReleaseBaseBallScript)(int32_t handle); + void (*BaseBallScriptConstructor)(int32_t cppHandle, int32_t* handle); + int32_t (*BoxBoolean)(uint32_t val); + int32_t (*UnboxBoolean)(int32_t valHandle); + int32_t (*BoxSByte)(int8_t val); + int8_t (*UnboxSByte)(int32_t valHandle); + int32_t (*BoxByte)(uint8_t val); + uint8_t (*UnboxByte)(int32_t valHandle); + int32_t (*BoxInt16)(int16_t val); + int16_t (*UnboxInt16)(int32_t valHandle); + int32_t (*BoxUInt16)(uint16_t val); + uint16_t (*UnboxUInt16)(int32_t valHandle); + int32_t (*BoxInt32)(int32_t val); + int32_t (*UnboxInt32)(int32_t valHandle); + int32_t (*BoxUInt32)(uint32_t val); + uint32_t (*UnboxUInt32)(int32_t valHandle); + int32_t (*BoxInt64)(int64_t val); + int64_t (*UnboxInt64)(int32_t valHandle); + int32_t (*BoxUInt64)(uint64_t val); + uint64_t (*UnboxUInt64)(int32_t valHandle); + int32_t (*BoxChar)(uint16_t val); + int16_t (*UnboxChar)(int32_t valHandle); + int32_t (*BoxSingle)(float val); + float (*UnboxSingle)(int32_t valHandle); + int32_t (*BoxDouble)(double val); + double (*UnboxDouble)(int32_t valHandle); + /*END FUNCTION POINTERS*/ +} + +//////////////////////////////////////////////////////////////// +// Global variables +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + System::String NullString(nullptr); +} + +//////////////////////////////////////////////////////////////// +// Plugin Types +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + ManagedType::ManagedType() + : Handle(0) + { + } + + ManagedType::ManagedType(decltype(nullptr)) + : Handle(0) + { + } + + ManagedType::ManagedType(Plugin::InternalUse iu, int32_t handle) + : Handle(handle) + { + } +} + +//////////////////////////////////////////////////////////////// +// C# Primitive Types +//////////////////////////////////////////////////////////////// + +namespace System +{ + Boolean::Boolean() + : Value(0) + { + } + + Boolean::Boolean(bool value) + : Value((int32_t)value) + { + } + + Boolean::Boolean(int32_t value) + : Value(value) + { + } + + Boolean::Boolean(uint32_t value) + : Value(value) + { + } + + Boolean::operator bool() const + { + return (bool)Value; + } + + Boolean::operator int32_t() const + { + return Value; + } + + Boolean::operator uint32_t() const + { + return Value; + } + + Boolean::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Boolean::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxBoolean(Value)); + } + + Char::Char() + : Value(0) + { + } + + Char::Char(char value) + : Value(value) + { + } + + Char::Char(int16_t value) + : Value(value) + { + } + + Char::operator int16_t() const + { + return Value; + } + + Char::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + Char::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxChar(Value)); + } + + SByte::SByte() + : Value(0) + { + } + + SByte::SByte(int8_t val) + : Value(val) + { + } + + SByte::operator int8_t() const + { + return Value; + } + + SByte::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + SByte::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxSByte(Value)); + } + + Byte::Byte() + : Value(0) + { + } + + Byte::Byte(uint8_t value) + : Value(value) + { + } + + Byte::operator uint8_t() const + { + return Value; + } + + Byte::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Byte::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxByte(Value)); + } + + Int16::Int16() + : Value(0) + { + } + + Int16::Int16(int16_t value) + : Value(value) + { + } + + Int16::operator int16_t() const + { + return Value; + } + + Int16::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + Int16::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxInt16(Value)); + } + + UInt16::UInt16() + : Value(0) + { + } + + UInt16::UInt16(uint16_t value) + : Value(value) + { + } + + UInt16::operator uint16_t() const + { + return Value; + } + + UInt16::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + UInt16::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxUInt16(Value)); + } + + Int32::Int32() + : Value(0) + { + } + + Int32::Int32(int32_t value) + : Value(value) + { + } + + Int32::operator int32_t() const + { + return Value; + } + + Int32::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + Int32::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxInt32(Value)); + } + + UInt32::UInt32() + : Value(0) + { + } + + UInt32::UInt32(uint32_t value) + : Value(value) + { + } + + UInt32::operator uint32_t() const + { + return Value; + } + + UInt32::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + UInt32::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxUInt32(Value)); + } + + Int64::Int64() + : Value(0) + { + } + + Int64::Int64(int64_t value) + : Value(value) + { + } + + Int64::operator int64_t() const + { + return Value; + } + + Int64::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + Int64::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxInt64(Value)); + } + + UInt64::UInt64() + : Value(0) + { + } + + UInt64::UInt64(uint64_t value) + : Value(value) + { + } + + UInt64::operator uint64_t() const + { + return Value; + } + + UInt64::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + UInt64::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxUInt64(Value)); + } + + Single::Single() + : Value(0.0f) + { + } + + Single::Single(float value) + : Value(value) + { + } + + Single::operator float() const + { + return Value; + } + + Single::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Single::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxSingle(Value)); + } + + Double::Double() + : Value(0.0) + { + } + + Double::Double(double value) + : Value(value) + { + } + + Double::operator double() const + { + return Value; + } + + Double::operator Object() const + { + return Object(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator ValueType() const + { + return ValueType(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator IComparable() const + { + return IComparable(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator IFormattable() const + { + return IFormattable(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator IConvertible() const + { + return IConvertible(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator IComparable_1() const + { + return IComparable_1(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } + + Double::operator IEquatable_1() const + { + return IEquatable_1(Plugin::InternalUse::Only, Plugin::BoxDouble(Value)); + } +} + +//////////////////////////////////////////////////////////////// +// Support for using IEnumerable with range for loops +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + // End iterators are dummies full of null + EnumerableIterator::EnumerableIterator(decltype(nullptr)) + : enumerator(nullptr) + , hasMore(false) + { + } + + // Begin iterators keep track of an IEnumerator + EnumerableIterator::EnumerableIterator( + System::Collections::IEnumerable& enumerable) + : enumerator(enumerable.GetEnumerator()) + { + hasMore = enumerator.MoveNext(); + } + + EnumerableIterator& EnumerableIterator::operator++() + { + hasMore = enumerator.MoveNext(); + return *this; + } + + bool EnumerableIterator::operator!=(const EnumerableIterator& other) + { + return hasMore; + } + + System::Object EnumerableIterator::operator*() + { + return enumerator.GetCurrent(); + } +} + +//////////////////////////////////////////////////////////////// +// User-defined literals for creating decimals (System.Decimal) +//////////////////////////////////////////////////////////////// + +System::Decimal operator"" _m(long double x) +{ + return System::Decimal((System::Double)x); +} + +System::Decimal operator"" _m(unsigned long long x) +{ + return System::Decimal((System::UInt64)x); +} + +//////////////////////////////////////////////////////////////// +// Reference counting of managed objects +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + int32_t RefCountsLenClass; + int32_t* RefCountsClass; + + void ReferenceManagedClass(int32_t handle) + { + assert(handle >= 0 && handle < RefCountsLenClass); + if (handle != 0) + { + RefCountsClass[handle]++; + } + } + + void DereferenceManagedClass(int32_t handle) + { + assert(handle >= 0 && handle < RefCountsLenClass); + if (handle != 0) + { + int32_t numRemain = --RefCountsClass[handle]; + if (numRemain == 0) + { + ReleaseObject(handle); + } + } + } + + bool DereferenceManagedClassNoRelease(int32_t handle) + { + assert(handle >= 0 && handle < RefCountsLenClass); + if (handle != 0) + { + int32_t numRemain = --RefCountsClass[handle]; + if (numRemain == 0) + { + return true; + } + } + return false; + } + + /*BEGIN GLOBAL STATE AND FUNCTIONS*/ + int32_t RefCountsLenSystemDecimal; + int32_t* RefCountsSystemDecimal; + + void ReferenceManagedSystemDecimal(int32_t handle) + { + assert(handle >= 0 && handle < RefCountsLenSystemDecimal); + if (handle != 0) + { + RefCountsSystemDecimal[handle]++; + } + } + + void DereferenceManagedSystemDecimal(int32_t handle) + { + assert(handle >= 0 && handle < RefCountsLenSystemDecimal); + if (handle != 0) + { + int32_t numRemain = --RefCountsSystemDecimal[handle]; + if (numRemain == 0) + { + ReleaseSystemDecimal(handle); + } + } + } + + // Free list for MyGame::BaseBallScript pointers + + int32_t BaseBallScriptFreeListSize; + MyGame::BaseBallScript** BaseBallScriptFreeList; + MyGame::BaseBallScript** NextFreeBaseBallScript; + + int32_t StoreBaseBallScript(MyGame::BaseBallScript* del) + { + assert(NextFreeBaseBallScript != nullptr); + MyGame::BaseBallScript** pNext = NextFreeBaseBallScript; + NextFreeBaseBallScript = (MyGame::BaseBallScript**)*pNext; + *pNext = del; + return (int32_t)(pNext - BaseBallScriptFreeList); + } + + MyGame::BaseBallScript* GetBaseBallScript(int32_t handle) + { + assert(handle >= 0 && handle < BaseBallScriptFreeListSize); + return BaseBallScriptFreeList[handle]; + } + + void RemoveBaseBallScript(int32_t handle) + { + MyGame::BaseBallScript** pRelease = BaseBallScriptFreeList + handle; + *pRelease = (MyGame::BaseBallScript*)NextFreeBaseBallScript; + NextFreeBaseBallScript = pRelease; + } + + // Free list for whole MyGame::BaseBallScript objects + + union BaseBallScriptFreeWholeListEntry + { + BaseBallScriptFreeWholeListEntry* Next; + MyGame::BaseBallScript Value; + }; + int32_t BaseBallScriptFreeWholeListSize; + BaseBallScriptFreeWholeListEntry* BaseBallScriptFreeWholeList; + BaseBallScriptFreeWholeListEntry* NextFreeWholeBaseBallScript; + + MyGame::BaseBallScript* StoreWholeBaseBallScript() + { + assert(NextFreeWholeBaseBallScript != nullptr); + BaseBallScriptFreeWholeListEntry* pNext = NextFreeWholeBaseBallScript; + NextFreeWholeBaseBallScript = pNext->Next; + return &pNext->Value; + } + + void RemoveWholeBaseBallScript(MyGame::BaseBallScript* instance) + { + BaseBallScriptFreeWholeListEntry* pRelease = (BaseBallScriptFreeWholeListEntry*)instance; + if (pRelease >= BaseBallScriptFreeWholeList && pRelease < BaseBallScriptFreeWholeList + (BaseBallScriptFreeWholeListSize - 1)) + { + pRelease->Next = NextFreeWholeBaseBallScript; + NextFreeWholeBaseBallScript = pRelease->Next; + } + } + /*END GLOBAL STATE AND FUNCTIONS*/ +} + +namespace Plugin +{ + // An unhandled exception caused by C++ calling into C# + System::Exception* unhandledCsharpException = nullptr; +} + +//////////////////////////////////////////////////////////////// +// Mirrors of C# types. These wrap the C# functions to present +// a similiar API as in C#. +//////////////////////////////////////////////////////////////// + +namespace System +{ + Object::Object() + : Plugin::ManagedType(nullptr) + { + } + + Object::Object(Plugin::InternalUse iu, int32_t handle) + : ManagedType(Plugin::InternalUse::Only, handle) + { + } + + Object::Object(decltype(nullptr)) + : ManagedType(nullptr) + { + } + + Object::~Object() + { + } + + bool Object::operator==(decltype(nullptr)) const + { + return Handle == 0; + } + + bool Object::operator!=(decltype(nullptr)) const + { + return Handle != 0; + } + + void Object::ThrowReferenceToThis() + { + throw *this; + } + + ValueType::ValueType(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + { + } + + ValueType::ValueType(decltype(nullptr)) + : Object(nullptr) + { + } + + Enum::Enum(Plugin::InternalUse iu, int32_t handle) + : ValueType(iu, handle) + { + } + + Enum::Enum(decltype(nullptr)) + : ValueType(nullptr) + { + } + + String::String(decltype(nullptr)) + : Object(Plugin::InternalUse::Only, 0) + { + } + + String::String(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + { + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + String::String(const String& other) + : Object(Plugin::InternalUse::Only, other.Handle) + { + if (Handle) + { + Plugin::ReferenceManagedClass(Handle); + } + } + + String::String(String&& other) + : Object(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + String::~String() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + String& String::operator=(const String& other) + { + if (Handle != other.Handle) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + if (Handle) + { + Plugin::ReferenceManagedClass(Handle); + } + } + return *this; + } + + String& String::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + String& String::operator=(String&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + String::String(const char* chars) + : Object(Plugin::InternalUse::Only, Plugin::StringNew(chars)) + { + Plugin::ReferenceManagedClass(Handle); + } + + ICloneable::ICloneable(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + { + } + + ICloneable::ICloneable(decltype(nullptr)) + : Object(nullptr) + { + } + + namespace Collections + { + IEnumerable::IEnumerable(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + { + } + + IEnumerable::IEnumerable(decltype(nullptr)) + : Object(nullptr) + { + } + + IEnumerator IEnumerable::GetEnumerator() + { + return IEnumerator( + Plugin::InternalUse::Only, + Plugin::EnumerableGetEnumerator(Handle)); + } + + Plugin::EnumerableIterator begin( + System::Collections::IEnumerable& enumerable) + { + return Plugin::EnumerableIterator(enumerable); + } + + Plugin::EnumerableIterator end( + System::Collections::IEnumerable& enumerable) + { + return Plugin::EnumerableIterator(nullptr); + } + + ICollection::ICollection(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + , IEnumerable(nullptr) + { + } + + ICollection::ICollection(decltype(nullptr)) + : Object(nullptr) + , IEnumerable(nullptr) + { + } + + IList::IList(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + , IEnumerable(nullptr) + , ICollection(nullptr) + { + } + + IList::IList(decltype(nullptr)) + : Object(nullptr) + , IEnumerable(nullptr) + , ICollection(nullptr) + { + } + } + + Array::Array(Plugin::InternalUse iu, int32_t handle) + : Object(iu, handle) + , ICloneable(nullptr) + , Collections::IEnumerable(nullptr) + , Collections::ICollection(nullptr) + , Collections::IList(nullptr) + { + } + + Array::Array(decltype(nullptr)) + : Object(nullptr) + , ICloneable(nullptr) + , Collections::IEnumerable(nullptr) + , Collections::ICollection(nullptr) + , Collections::IList(nullptr) + { + } + + int32_t Array::GetLength() + { + return Plugin::ArrayGetLength(Handle); + } + + int32_t Array::GetRank() + { + return 0; + } +} + +/*BEGIN METHOD DEFINITIONS*/ +namespace System +{ + IFormattable::IFormattable(decltype(nullptr)) + { + } + + IFormattable::IFormattable(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IFormattable::IFormattable(const IFormattable& other) + : IFormattable(Plugin::InternalUse::Only, other.Handle) + { + } + + IFormattable::IFormattable(IFormattable&& other) + : IFormattable(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IFormattable::~IFormattable() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IFormattable& IFormattable::operator=(const IFormattable& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IFormattable& IFormattable::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IFormattable& IFormattable::operator=(IFormattable&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IFormattable::operator==(const IFormattable& other) const + { + return Handle == other.Handle; + } + + bool IFormattable::operator!=(const IFormattable& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IConvertible::IConvertible(decltype(nullptr)) + { + } + + IConvertible::IConvertible(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IConvertible::IConvertible(const IConvertible& other) + : IConvertible(Plugin::InternalUse::Only, other.Handle) + { + } + + IConvertible::IConvertible(IConvertible&& other) + : IConvertible(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IConvertible::~IConvertible() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IConvertible& IConvertible::operator=(const IConvertible& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IConvertible& IConvertible::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IConvertible& IConvertible::operator=(IConvertible&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IConvertible::operator==(const IConvertible& other) const + { + return Handle == other.Handle; + } + + bool IConvertible::operator!=(const IConvertible& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable::IComparable(decltype(nullptr)) + { + } + + IComparable::IComparable(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable::IComparable(const IComparable& other) + : IComparable(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable::IComparable(IComparable&& other) + : IComparable(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable::~IComparable() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable& IComparable::operator=(const IComparable& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable& IComparable::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable& IComparable::operator=(IComparable&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable::operator==(const IComparable& other) const + { + return Handle == other.Handle; + } + + bool IComparable::operator!=(const IComparable& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IEquatable_1::IEquatable_1(decltype(nullptr)) + { + } + + IEquatable_1::IEquatable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEquatable_1::IEquatable_1(const IEquatable_1& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IEquatable_1::IEquatable_1(IEquatable_1&& other) + : IEquatable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEquatable_1::~IEquatable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEquatable_1& IEquatable_1::operator=(const IEquatable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEquatable_1& IEquatable_1::operator=(IEquatable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEquatable_1::operator==(const IEquatable_1& other) const + { + return Handle == other.Handle; + } + + bool IEquatable_1::operator!=(const IEquatable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + IComparable_1::IComparable_1(decltype(nullptr)) + { + } + + IComparable_1::IComparable_1(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IComparable_1::IComparable_1(const IComparable_1& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + } + + IComparable_1::IComparable_1(IComparable_1&& other) + : IComparable_1(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IComparable_1::~IComparable_1() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IComparable_1& IComparable_1::operator=(const IComparable_1& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IComparable_1& IComparable_1::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IComparable_1& IComparable_1::operator=(IComparable_1&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IComparable_1::operator==(const IComparable_1& other) const + { + return Handle == other.Handle; + } + + bool IComparable_1::operator!=(const IComparable_1& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + IDeserializationCallback::IDeserializationCallback(decltype(nullptr)) + { + } + + IDeserializationCallback::IDeserializationCallback(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IDeserializationCallback::IDeserializationCallback(const IDeserializationCallback& other) + : IDeserializationCallback(Plugin::InternalUse::Only, other.Handle) + { + } + + IDeserializationCallback::IDeserializationCallback(IDeserializationCallback&& other) + : IDeserializationCallback(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IDeserializationCallback::~IDeserializationCallback() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IDeserializationCallback& IDeserializationCallback::operator=(const IDeserializationCallback& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IDeserializationCallback& IDeserializationCallback::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IDeserializationCallback& IDeserializationCallback::operator=(IDeserializationCallback&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IDeserializationCallback::operator==(const IDeserializationCallback& other) const + { + return Handle == other.Handle; + } + + bool IDeserializationCallback::operator!=(const IDeserializationCallback& other) const + { + return Handle != other.Handle; + } + } + } +} + +namespace System +{ + Decimal::Decimal(decltype(nullptr)) + { + } + + Decimal::Decimal(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedSystemDecimal(Handle); + } + } + + Decimal::Decimal(const Decimal& other) + : Decimal(Plugin::InternalUse::Only, other.Handle) + { + } + + Decimal::Decimal(Decimal&& other) + : Decimal(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Decimal::~Decimal() + { + if (Handle) + { + Plugin::DereferenceManagedSystemDecimal(Handle); + Handle = 0; + } + } + + Decimal& Decimal::operator=(const Decimal& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedSystemDecimal(Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedSystemDecimal(Handle); + } + return *this; + } + + Decimal& Decimal::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedSystemDecimal(Handle); + Handle = 0; + } + return *this; + } + + Decimal& Decimal::operator=(Decimal&& other) + { + if (Handle) + { + Plugin::DereferenceManagedSystemDecimal(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Decimal::operator==(const Decimal& other) const + { + return Handle == other.Handle; + } + + bool Decimal::operator!=(const Decimal& other) const + { + return Handle != other.Handle; + } + + System::Decimal::Decimal(System::Double value) + { + auto returnValue = Plugin::SystemDecimalConstructorSystemDouble(value); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + Handle = returnValue; + if (returnValue) + { + Plugin::ReferenceManagedSystemDecimal(Handle); + } + } + + System::Decimal::Decimal(System::UInt64 value) + { + auto returnValue = Plugin::SystemDecimalConstructorSystemUInt64(value); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + Handle = returnValue; + if (returnValue) + { + Plugin::ReferenceManagedSystemDecimal(Handle); + } + } + + System::Decimal::operator System::ValueType() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::ValueType(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::Object() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::Object(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::IComparable() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IComparable(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::IComparable_1() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IComparable_1(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::IConvertible() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IConvertible(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::IEquatable_1() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IEquatable_1(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::Runtime::Serialization::IDeserializationCallback() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::Runtime::Serialization::IDeserializationCallback(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + System::Decimal::operator System::IFormattable() + { + int32_t handle = Plugin::BoxDecimal(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IFormattable(Plugin::InternalUse::Only, handle); + } + return nullptr; + } +} + +namespace System +{ + System::Object::operator System::Decimal() + { + System::Decimal returnVal(Plugin::InternalUse::Only, Plugin::UnboxDecimal(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace UnityEngine +{ + Vector3::Vector3() + { + } + + UnityEngine::Vector3::Vector3(System::Single x, System::Single y, System::Single z) + { + auto returnValue = Plugin::UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle(x, y, z); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + *this = returnValue; + } + + UnityEngine::Vector3 UnityEngine::Vector3::operator+(UnityEngine::Vector3& a) + { + auto returnValue = Plugin::UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3(*this, a); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnValue; + } + + UnityEngine::Vector3::operator System::ValueType() + { + int32_t handle = Plugin::BoxVector3(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::ValueType(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::Vector3::operator System::Object() + { + int32_t handle = Plugin::BoxVector3(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::Object(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::Vector3::operator System::IEquatable_1() + { + int32_t handle = Plugin::BoxVector3(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IEquatable_1(Plugin::InternalUse::Only, handle); + } + return nullptr; + } +} + +namespace System +{ + System::Object::operator UnityEngine::Vector3() + { + UnityEngine::Vector3 returnVal(Plugin::UnboxVector3(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace UnityEngine +{ + Object::Object(decltype(nullptr)) + { + } + + Object::Object(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Object::Object(const Object& other) + : Object(Plugin::InternalUse::Only, other.Handle) + { + } + + Object::Object(Object&& other) + : Object(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Object::~Object() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Object& Object::operator=(const Object& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Object& Object::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Object& Object::operator=(Object&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Object::operator==(const Object& other) const + { + return Handle == other.Handle; + } + + bool Object::operator!=(const Object& other) const + { + return Handle != other.Handle; + } + + System::String UnityEngine::Object::GetName() + { + auto returnValue = Plugin::UnityEngineObjectPropertyGetName(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return System::String(Plugin::InternalUse::Only, returnValue); + } + + void UnityEngine::Object::SetName(System::String& value) + { + Plugin::UnityEngineObjectPropertySetName(Handle, value.Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } +} + +namespace UnityEngine +{ + Component::Component(decltype(nullptr)) + : UnityEngine::Object(nullptr) + { + } + + Component::Component(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Component::Component(const Component& other) + : Component(Plugin::InternalUse::Only, other.Handle) + { + } + + Component::Component(Component&& other) + : Component(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Component::~Component() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Component& Component::operator=(const Component& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Component& Component::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Component& Component::operator=(Component&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Component::operator==(const Component& other) const + { + return Handle == other.Handle; + } + + bool Component::operator!=(const Component& other) const + { + return Handle != other.Handle; + } + + UnityEngine::Transform UnityEngine::Component::GetTransform() + { + auto returnValue = Plugin::UnityEngineComponentPropertyGetTransform(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return UnityEngine::Transform(Plugin::InternalUse::Only, returnValue); + } +} + +namespace UnityEngine +{ + Transform::Transform(decltype(nullptr)) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , System::Collections::IEnumerable(nullptr) + { + } + + Transform::Transform(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , System::Collections::IEnumerable(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Transform::Transform(const Transform& other) + : Transform(Plugin::InternalUse::Only, other.Handle) + { + } + + Transform::Transform(Transform&& other) + : Transform(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Transform::~Transform() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Transform& Transform::operator=(const Transform& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Transform& Transform::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Transform& Transform::operator=(Transform&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Transform::operator==(const Transform& other) const + { + return Handle == other.Handle; + } + + bool Transform::operator!=(const Transform& other) const + { + return Handle != other.Handle; + } + + UnityEngine::Vector3 UnityEngine::Transform::GetPosition() + { + auto returnValue = Plugin::UnityEngineTransformPropertyGetPosition(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnValue; + } + + void UnityEngine::Transform::SetPosition(UnityEngine::Vector3& value) + { + Plugin::UnityEngineTransformPropertySetPosition(Handle, value); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } +} + +namespace System +{ + namespace Collections + { + IEnumerator::IEnumerator(decltype(nullptr)) + { + } + + IEnumerator::IEnumerator(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + IEnumerator::IEnumerator(const IEnumerator& other) + : IEnumerator(Plugin::InternalUse::Only, other.Handle) + { + } + + IEnumerator::IEnumerator(IEnumerator&& other) + : IEnumerator(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + IEnumerator::~IEnumerator() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + IEnumerator& IEnumerator::operator=(const IEnumerator& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + IEnumerator& IEnumerator::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + IEnumerator& IEnumerator::operator=(IEnumerator&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool IEnumerator::operator==(const IEnumerator& other) const + { + return Handle == other.Handle; + } + + bool IEnumerator::operator!=(const IEnumerator& other) const + { + return Handle != other.Handle; + } + + System::Object System::Collections::IEnumerator::GetCurrent() + { + auto returnValue = Plugin::SystemCollectionsIEnumeratorPropertyGetCurrent(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return System::Object(Plugin::InternalUse::Only, returnValue); + } + + System::Boolean System::Collections::IEnumerator::MoveNext() + { + auto returnValue = Plugin::SystemCollectionsIEnumeratorMethodMoveNext(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnValue; + } + } +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + ISerializable::ISerializable(decltype(nullptr)) + { + } + + ISerializable::ISerializable(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + ISerializable::ISerializable(const ISerializable& other) + : ISerializable(Plugin::InternalUse::Only, other.Handle) + { + } + + ISerializable::ISerializable(ISerializable&& other) + : ISerializable(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + ISerializable::~ISerializable() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + ISerializable& ISerializable::operator=(const ISerializable& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + ISerializable& ISerializable::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + ISerializable& ISerializable::operator=(ISerializable&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool ISerializable::operator==(const ISerializable& other) const + { + return Handle == other.Handle; + } + + bool ISerializable::operator!=(const ISerializable& other) const + { + return Handle != other.Handle; + } + } + } +} + +namespace System +{ + namespace Runtime + { + namespace InteropServices + { + _Exception::_Exception(decltype(nullptr)) + { + } + + _Exception::_Exception(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + _Exception::_Exception(const _Exception& other) + : _Exception(Plugin::InternalUse::Only, other.Handle) + { + } + + _Exception::_Exception(_Exception&& other) + : _Exception(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + _Exception::~_Exception() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + _Exception& _Exception::operator=(const _Exception& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + _Exception& _Exception::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + _Exception& _Exception::operator=(_Exception&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool _Exception::operator==(const _Exception& other) const + { + return Handle == other.Handle; + } + + bool _Exception::operator!=(const _Exception& other) const + { + return Handle != other.Handle; + } + } + } +} + +namespace UnityEngine +{ + GameObject::GameObject(decltype(nullptr)) + : UnityEngine::Object(nullptr) + { + } + + GameObject::GameObject(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + GameObject::GameObject(const GameObject& other) + : GameObject(Plugin::InternalUse::Only, other.Handle) + { + } + + GameObject::GameObject(GameObject&& other) + : GameObject(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + GameObject::~GameObject() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + GameObject& GameObject::operator=(const GameObject& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + GameObject& GameObject::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + GameObject& GameObject::operator=(GameObject&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool GameObject::operator==(const GameObject& other) const + { + return Handle == other.Handle; + } + + bool GameObject::operator!=(const GameObject& other) const + { + return Handle != other.Handle; + } + + template<> MyGame::BaseBallScript UnityEngine::GameObject::AddComponent() + { + auto returnValue = Plugin::UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return MyGame::BaseBallScript(Plugin::InternalUse::Only, returnValue); + } + + UnityEngine::GameObject UnityEngine::GameObject::CreatePrimitive(UnityEngine::PrimitiveType type) + { + auto returnValue = Plugin::UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType(type); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return UnityEngine::GameObject(Plugin::InternalUse::Only, returnValue); + } +} + +namespace UnityEngine +{ + Debug::Debug(decltype(nullptr)) + { + } + + Debug::Debug(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Debug::Debug(const Debug& other) + : Debug(Plugin::InternalUse::Only, other.Handle) + { + } + + Debug::Debug(Debug&& other) + : Debug(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Debug::~Debug() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Debug& Debug::operator=(const Debug& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Debug& Debug::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Debug& Debug::operator=(Debug&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Debug::operator==(const Debug& other) const + { + return Handle == other.Handle; + } + + bool Debug::operator!=(const Debug& other) const + { + return Handle != other.Handle; + } + + void UnityEngine::Debug::Log(System::Object& message) + { + Plugin::UnityEngineDebugMethodLogSystemObject(message.Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } +} + +namespace UnityEngine +{ + Behaviour::Behaviour(decltype(nullptr)) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + { + } + + Behaviour::Behaviour(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Behaviour::Behaviour(const Behaviour& other) + : Behaviour(Plugin::InternalUse::Only, other.Handle) + { + } + + Behaviour::Behaviour(Behaviour&& other) + : Behaviour(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Behaviour::~Behaviour() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Behaviour& Behaviour::operator=(const Behaviour& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Behaviour& Behaviour::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Behaviour& Behaviour::operator=(Behaviour&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Behaviour::operator==(const Behaviour& other) const + { + return Handle == other.Handle; + } + + bool Behaviour::operator!=(const Behaviour& other) const + { + return Handle != other.Handle; + } +} + +namespace UnityEngine +{ + MonoBehaviour::MonoBehaviour(decltype(nullptr)) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + { + } + + MonoBehaviour::MonoBehaviour(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + MonoBehaviour::MonoBehaviour(const MonoBehaviour& other) + : MonoBehaviour(Plugin::InternalUse::Only, other.Handle) + { + } + + MonoBehaviour::MonoBehaviour(MonoBehaviour&& other) + : MonoBehaviour(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + MonoBehaviour::~MonoBehaviour() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + MonoBehaviour& MonoBehaviour::operator=(const MonoBehaviour& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + MonoBehaviour& MonoBehaviour::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + MonoBehaviour& MonoBehaviour::operator=(MonoBehaviour&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool MonoBehaviour::operator==(const MonoBehaviour& other) const + { + return Handle == other.Handle; + } + + bool MonoBehaviour::operator!=(const MonoBehaviour& other) const + { + return Handle != other.Handle; + } + + UnityEngine::Transform UnityEngine::MonoBehaviour::GetTransform() + { + auto returnValue = Plugin::UnityEngineMonoBehaviourPropertyGetTransform(Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return UnityEngine::Transform(Plugin::InternalUse::Only, returnValue); + } +} + +namespace System +{ + Exception::Exception(decltype(nullptr)) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + { + } + + Exception::Exception(Plugin::InternalUse, int32_t handle) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Exception::Exception(const Exception& other) + : Exception(Plugin::InternalUse::Only, other.Handle) + { + } + + Exception::Exception(Exception&& other) + : Exception(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Exception::~Exception() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Exception& Exception::operator=(const Exception& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Exception& Exception::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Exception& Exception::operator=(Exception&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Exception::operator==(const Exception& other) const + { + return Handle == other.Handle; + } + + bool Exception::operator!=(const Exception& other) const + { + return Handle != other.Handle; + } + + System::Exception::Exception(System::String& message) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + { + auto returnValue = Plugin::SystemExceptionConstructorSystemString(message.Handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + Handle = returnValue; + if (returnValue) + { + Plugin::ReferenceManagedClass(returnValue); + } + } +} + +namespace System +{ + SystemException::SystemException(decltype(nullptr)) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + , System::Exception(nullptr) + { + } + + SystemException::SystemException(Plugin::InternalUse, int32_t handle) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + , System::Exception(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + SystemException::SystemException(const SystemException& other) + : SystemException(Plugin::InternalUse::Only, other.Handle) + { + } + + SystemException::SystemException(SystemException&& other) + : SystemException(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + SystemException::~SystemException() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + SystemException& SystemException::operator=(const SystemException& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + SystemException& SystemException::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + SystemException& SystemException::operator=(SystemException&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool SystemException::operator==(const SystemException& other) const + { + return Handle == other.Handle; + } + + bool SystemException::operator!=(const SystemException& other) const + { + return Handle != other.Handle; + } +} + +namespace System +{ + NullReferenceException::NullReferenceException(decltype(nullptr)) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + , System::Exception(nullptr) + , System::SystemException(nullptr) + { + } + + NullReferenceException::NullReferenceException(Plugin::InternalUse, int32_t handle) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + , System::Exception(nullptr) + , System::SystemException(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + NullReferenceException::NullReferenceException(const NullReferenceException& other) + : NullReferenceException(Plugin::InternalUse::Only, other.Handle) + { + } + + NullReferenceException::NullReferenceException(NullReferenceException&& other) + : NullReferenceException(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + NullReferenceException::~NullReferenceException() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + NullReferenceException& NullReferenceException::operator=(const NullReferenceException& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + NullReferenceException& NullReferenceException::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + NullReferenceException& NullReferenceException::operator=(NullReferenceException&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool NullReferenceException::operator==(const NullReferenceException& other) const + { + return Handle == other.Handle; + } + + bool NullReferenceException::operator!=(const NullReferenceException& other) const + { + return Handle != other.Handle; + } +} + +namespace UnityEngine +{ + PrimitiveType::PrimitiveType(int32_t value) + : Value(value) + { + } + + UnityEngine::PrimitiveType::operator int32_t() const + { + return Value; + } + + bool UnityEngine::PrimitiveType::operator==(PrimitiveType other) + { + return Value == other.Value; + } + + bool UnityEngine::PrimitiveType::operator!=(PrimitiveType other) + { + return Value != other.Value; + } + + UnityEngine::PrimitiveType::operator System::Enum() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::Enum(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::PrimitiveType::operator System::ValueType() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::ValueType(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::PrimitiveType::operator System::Object() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::Object(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::PrimitiveType::operator System::IComparable() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IComparable(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::PrimitiveType::operator System::IConvertible() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IConvertible(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + + UnityEngine::PrimitiveType::operator System::IFormattable() + { + int32_t handle = Plugin::BoxPrimitiveType(*this); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (handle) + { + Plugin::ReferenceManagedClass(handle); + return System::IFormattable(Plugin::InternalUse::Only, handle); + } + return nullptr; + } + +} +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Sphere(0); +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Capsule(1); +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Cylinder(2); +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Cube(3); +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Plane(4); +const UnityEngine::PrimitiveType UnityEngine::PrimitiveType::Quad(5); + +namespace System +{ + System::Object::operator UnityEngine::PrimitiveType() + { + UnityEngine::PrimitiveType returnVal(Plugin::UnboxPrimitiveType(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace UnityEngine +{ + Time::Time(decltype(nullptr)) + { + } + + Time::Time(Plugin::InternalUse, int32_t handle) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + Time::Time(const Time& other) + : Time(Plugin::InternalUse::Only, other.Handle) + { + } + + Time::Time(Time&& other) + : Time(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + Time::~Time() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + Time& Time::operator=(const Time& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + Time& Time::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + Time& Time::operator=(Time&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool Time::operator==(const Time& other) const + { + return Handle == other.Handle; + } + + bool Time::operator!=(const Time& other) const + { + return Handle != other.Handle; + } + + System::Single UnityEngine::Time::GetDeltaTime() + { + auto returnValue = Plugin::UnityEngineTimePropertyGetDeltaTime(); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnValue; + } +} + +namespace MyGame +{ + AbstractBaseBallScript::AbstractBaseBallScript(decltype(nullptr)) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + { + } + + AbstractBaseBallScript::AbstractBaseBallScript(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + { + Handle = handle; + if (handle) + { + Plugin::ReferenceManagedClass(handle); + } + } + + AbstractBaseBallScript::AbstractBaseBallScript(const AbstractBaseBallScript& other) + : AbstractBaseBallScript(Plugin::InternalUse::Only, other.Handle) + { + } + + AbstractBaseBallScript::AbstractBaseBallScript(AbstractBaseBallScript&& other) + : AbstractBaseBallScript(Plugin::InternalUse::Only, other.Handle) + { + other.Handle = 0; + } + + AbstractBaseBallScript::~AbstractBaseBallScript() + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + } + + AbstractBaseBallScript& AbstractBaseBallScript::operator=(const AbstractBaseBallScript& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + AbstractBaseBallScript& AbstractBaseBallScript::operator=(decltype(nullptr)) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + Handle = 0; + } + return *this; + } + + AbstractBaseBallScript& AbstractBaseBallScript::operator=(AbstractBaseBallScript&& other) + { + if (Handle) + { + Plugin::DereferenceManagedClass(Handle); + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool AbstractBaseBallScript::operator==(const AbstractBaseBallScript& other) const + { + return Handle == other.Handle; + } + + bool AbstractBaseBallScript::operator!=(const AbstractBaseBallScript& other) const + { + return Handle != other.Handle; + } +} + +namespace MyGame +{ + MyGame::BaseBallScript::BaseBallScript() + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + , MyGame::AbstractBaseBallScript(nullptr) + { + CppHandle = Plugin::StoreBaseBallScript(this); + System::Int32* handle = (System::Int32*)&Handle; + int32_t cppHandle = CppHandle; + Plugin::BaseBallScriptConstructor(cppHandle, &handle->Value); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + if (Handle) + { + Plugin::ReferenceManagedClass(Handle); + } + else + { + Plugin::RemoveBaseBallScript(CppHandle); + CppHandle = 0; + } + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } + + BaseBallScript::BaseBallScript(decltype(nullptr)) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + , MyGame::AbstractBaseBallScript(nullptr) + { + CppHandle = Plugin::StoreBaseBallScript(this); + } + + MyGame::BaseBallScript::BaseBallScript(const MyGame::BaseBallScript& other) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + , MyGame::AbstractBaseBallScript(nullptr) + { + Handle = other.Handle; + CppHandle = Plugin::StoreBaseBallScript(this); + if (Handle) + { + Plugin::ReferenceManagedClass(Handle); + } + } + + MyGame::BaseBallScript::BaseBallScript(MyGame::BaseBallScript&& other) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + , MyGame::AbstractBaseBallScript(nullptr) + { + Handle = other.Handle; + CppHandle = other.CppHandle; + other.Handle = 0; + other.CppHandle = 0; + } + + MyGame::BaseBallScript::BaseBallScript(Plugin::InternalUse, int32_t handle) + : UnityEngine::Object(nullptr) + , UnityEngine::Component(nullptr) + , UnityEngine::Behaviour(nullptr) + , UnityEngine::MonoBehaviour(nullptr) + , MyGame::AbstractBaseBallScript(nullptr) + { + Handle = handle; + CppHandle = Plugin::StoreBaseBallScript(this); + if (Handle) + { + Plugin::ReferenceManagedClass(Handle); + } + } + + MyGame::BaseBallScript::~BaseBallScript() + { + Plugin::RemoveWholeBaseBallScript(this); + Plugin::RemoveBaseBallScript(CppHandle); + CppHandle = 0; + if (Handle) + { + int32_t handle = Handle; + Handle = 0; + if (Plugin::DereferenceManagedClassNoRelease(handle)) + { + Plugin::ReleaseBaseBallScript(handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } + } + } + + MyGame::BaseBallScript& MyGame::BaseBallScript::operator=(const MyGame::BaseBallScript& other) + { + if (this->Handle) + { + Plugin::DereferenceManagedClass(this->Handle); + } + this->Handle = other.Handle; + if (this->Handle) + { + Plugin::ReferenceManagedClass(this->Handle); + } + return *this; + } + + MyGame::BaseBallScript& MyGame::BaseBallScript::operator=(decltype(nullptr)) + { + if (Handle) + { + int32_t handle = Handle; + Handle = 0; + if (Plugin::DereferenceManagedClassNoRelease(handle)) + { + Plugin::ReleaseBaseBallScript(handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } + } + Handle = 0; + return *this; + } + + MyGame::BaseBallScript& MyGame::BaseBallScript::operator=(MyGame::BaseBallScript&& other) + { + Plugin::RemoveBaseBallScript(CppHandle); + CppHandle = 0; + if (Handle) + { + int32_t handle = Handle; + Handle = 0; + if (Plugin::DereferenceManagedClassNoRelease(handle)) + { + Plugin::ReleaseBaseBallScript(handle); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + } + } + Handle = other.Handle; + other.Handle = 0; + return *this; + } + + bool MyGame::BaseBallScript::operator==(const MyGame::BaseBallScript& other) const + { + return Handle == other.Handle; + } + + bool MyGame::BaseBallScript::operator!=(const MyGame::BaseBallScript& other) const + { + return Handle != other.Handle; + } + + DLLEXPORT int32_t NewBaseBallScript(int32_t handle) + { + MyGame::BaseBallScript* memory = Plugin::StoreWholeBaseBallScript(); + MyGame::BallScript* thiz = new (memory) MyGame::BallScript(Plugin::InternalUse::Only, handle); + return thiz->CppHandle; + } + + DLLEXPORT void DestroyBaseBallScript(int32_t cppHandle) + { + MyGame::BaseBallScript* instance = Plugin::GetBaseBallScript(cppHandle); + instance->~BaseBallScript(); + } + + void MyGame::BaseBallScript::Update() + { + } + + DLLEXPORT void MyGameAbstractBaseBallScriptUpdate(int32_t cppHandle) + { + try + { + Plugin::GetBaseBallScript(cppHandle)->Update(); + } + catch (System::Exception ex) + { + Plugin::SetException(ex.Handle); + } + catch (...) + { + System::String msg = "Unhandled exception invoking MyGame::AbstractBaseBallScript"; + System::Exception ex(msg); + Plugin::SetException(ex.Handle); + } + } +} + +namespace System +{ + System::Object::operator System::Boolean() + { + System::Boolean returnVal(Plugin::UnboxBoolean(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::SByte() + { + System::SByte returnVal(Plugin::UnboxSByte(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Byte() + { + System::Byte returnVal(Plugin::UnboxByte(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Int16() + { + System::Int16 returnVal(Plugin::UnboxInt16(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::UInt16() + { + System::UInt16 returnVal(Plugin::UnboxUInt16(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Int32() + { + System::Int32 returnVal(Plugin::UnboxInt32(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::UInt32() + { + System::UInt32 returnVal(Plugin::UnboxUInt32(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Int64() + { + System::Int64 returnVal(Plugin::UnboxInt64(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::UInt64() + { + System::UInt64 returnVal(Plugin::UnboxUInt64(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Char() + { + System::Char returnVal(Plugin::UnboxChar(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Single() + { + System::Single returnVal(Plugin::UnboxSingle(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + System::Object::operator System::Double() + { + System::Double returnVal(Plugin::UnboxDouble(Handle)); + if (Plugin::unhandledCsharpException) + { + System::Exception* ex = Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = nullptr; + ex->ThrowReferenceToThis(); + delete ex; + } + return returnVal; + } +} + +namespace System +{ + struct NullReferenceExceptionThrower : System::NullReferenceException + { + NullReferenceExceptionThrower(int32_t handle) + : System::Runtime::InteropServices::_Exception(nullptr) + , System::Runtime::Serialization::ISerializable(nullptr) + , System::Exception(nullptr) + , System::SystemException(nullptr) + , System::NullReferenceException(Plugin::InternalUse::Only, handle) + { + } + + virtual void ThrowReferenceToThis() + { + throw *this; + } + }; +} + +DLLEXPORT void SetCsharpExceptionSystemNullReferenceException(int32_t handle) +{ + delete Plugin::unhandledCsharpException; + Plugin::unhandledCsharpException = new System::NullReferenceExceptionThrower(handle); +} +/*END METHOD DEFINITIONS*/ + +//////////////////////////////////////////////////////////////// +// App-specific functions for this file to call +//////////////////////////////////////////////////////////////// + +// Called when the plugin is initialized +extern void PluginMain( + void* memory, + int32_t memorySize, + bool isFirstBoot); + +//////////////////////////////////////////////////////////////// +// C++ functions for C# to call +//////////////////////////////////////////////////////////////// + +enum class InitMode : uint8_t +{ + FirstBoot, + Reload +}; + +// Init the plugin +DLLEXPORT void Init( + uint8_t* memory, + int32_t memorySize, + InitMode initMode) +{ + uint8_t* curMemory = memory; + + // Read fixed parameters + Plugin::ReleaseObject = *(void (**)(int32_t handle))curMemory; + curMemory += sizeof(Plugin::ReleaseObject); + Plugin::StringNew = *(int32_t (**)(const char*))curMemory; + curMemory += sizeof(Plugin::StringNew); + Plugin::SetException = *(void (**)(int32_t))curMemory; + curMemory += sizeof(Plugin::SetException); + Plugin::ArrayGetLength = *(int32_t (**)(int32_t))curMemory; + curMemory += sizeof(Plugin::ArrayGetLength); + Plugin::EnumerableGetEnumerator = *(int32_t (**)(int32_t))curMemory; + curMemory += sizeof(Plugin::EnumerableGetEnumerator); + + // Read generated parameters + int32_t maxManagedObjects = *(int32_t*)curMemory; + curMemory += sizeof(int32_t); + /*BEGIN INIT BODY PARAMETER READS*/ + Plugin::ReleaseSystemDecimal = *(void (**)(int32_t handle))curMemory; + curMemory += sizeof(Plugin::ReleaseSystemDecimal); + Plugin::SystemDecimalConstructorSystemDouble = *(int32_t (**)(double value))curMemory; + curMemory += sizeof(Plugin::SystemDecimalConstructorSystemDouble); + Plugin::SystemDecimalConstructorSystemUInt64 = *(int32_t (**)(uint64_t value))curMemory; + curMemory += sizeof(Plugin::SystemDecimalConstructorSystemUInt64); + Plugin::BoxDecimal = *(int32_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::BoxDecimal); + Plugin::UnboxDecimal = *(int32_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxDecimal); + Plugin::UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle = *(UnityEngine::Vector3 (**)(float x, float y, float z))curMemory; + curMemory += sizeof(Plugin::UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle); + Plugin::UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3 = *(UnityEngine::Vector3 (**)(UnityEngine::Vector3& a, UnityEngine::Vector3& b))curMemory; + curMemory += sizeof(Plugin::UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3); + Plugin::BoxVector3 = *(int32_t (**)(UnityEngine::Vector3& val))curMemory; + curMemory += sizeof(Plugin::BoxVector3); + Plugin::UnboxVector3 = *(UnityEngine::Vector3 (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxVector3); + Plugin::UnityEngineObjectPropertyGetName = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineObjectPropertyGetName); + Plugin::UnityEngineObjectPropertySetName = *(void (**)(int32_t thisHandle, int32_t valueHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineObjectPropertySetName); + Plugin::UnityEngineComponentPropertyGetTransform = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineComponentPropertyGetTransform); + Plugin::UnityEngineTransformPropertyGetPosition = *(UnityEngine::Vector3 (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineTransformPropertyGetPosition); + Plugin::UnityEngineTransformPropertySetPosition = *(void (**)(int32_t thisHandle, UnityEngine::Vector3& value))curMemory; + curMemory += sizeof(Plugin::UnityEngineTransformPropertySetPosition); + Plugin::SystemCollectionsIEnumeratorPropertyGetCurrent = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::SystemCollectionsIEnumeratorPropertyGetCurrent); + Plugin::SystemCollectionsIEnumeratorMethodMoveNext = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::SystemCollectionsIEnumeratorMethodMoveNext); + Plugin::UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript); + Plugin::UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType = *(int32_t (**)(UnityEngine::PrimitiveType type))curMemory; + curMemory += sizeof(Plugin::UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType); + Plugin::UnityEngineDebugMethodLogSystemObject = *(void (**)(int32_t messageHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineDebugMethodLogSystemObject); + Plugin::UnityEngineMonoBehaviourPropertyGetTransform = *(int32_t (**)(int32_t thisHandle))curMemory; + curMemory += sizeof(Plugin::UnityEngineMonoBehaviourPropertyGetTransform); + Plugin::SystemExceptionConstructorSystemString = *(int32_t (**)(int32_t messageHandle))curMemory; + curMemory += sizeof(Plugin::SystemExceptionConstructorSystemString); + Plugin::BoxPrimitiveType = *(int32_t (**)(UnityEngine::PrimitiveType val))curMemory; + curMemory += sizeof(Plugin::BoxPrimitiveType); + Plugin::UnboxPrimitiveType = *(UnityEngine::PrimitiveType (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxPrimitiveType); + Plugin::UnityEngineTimePropertyGetDeltaTime = *(float (**)())curMemory; + curMemory += sizeof(Plugin::UnityEngineTimePropertyGetDeltaTime); + Plugin::ReleaseBaseBallScript = *(void (**)(int32_t handle))curMemory; + curMemory += sizeof(Plugin::ReleaseBaseBallScript); + Plugin::BaseBallScriptConstructor = *(void (**)(int32_t cppHandle, int32_t* handle))curMemory; + curMemory += sizeof(Plugin::BaseBallScriptConstructor); + Plugin::BoxBoolean = *(int32_t (**)(uint32_t val))curMemory; + curMemory += sizeof(Plugin::BoxBoolean); + Plugin::UnboxBoolean = *(int32_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxBoolean); + Plugin::BoxSByte = *(int32_t (**)(int8_t val))curMemory; + curMemory += sizeof(Plugin::BoxSByte); + Plugin::UnboxSByte = *(int8_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxSByte); + Plugin::BoxByte = *(int32_t (**)(uint8_t val))curMemory; + curMemory += sizeof(Plugin::BoxByte); + Plugin::UnboxByte = *(uint8_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxByte); + Plugin::BoxInt16 = *(int32_t (**)(int16_t val))curMemory; + curMemory += sizeof(Plugin::BoxInt16); + Plugin::UnboxInt16 = *(int16_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxInt16); + Plugin::BoxUInt16 = *(int32_t (**)(uint16_t val))curMemory; + curMemory += sizeof(Plugin::BoxUInt16); + Plugin::UnboxUInt16 = *(uint16_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxUInt16); + Plugin::BoxInt32 = *(int32_t (**)(int32_t val))curMemory; + curMemory += sizeof(Plugin::BoxInt32); + Plugin::UnboxInt32 = *(int32_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxInt32); + Plugin::BoxUInt32 = *(int32_t (**)(uint32_t val))curMemory; + curMemory += sizeof(Plugin::BoxUInt32); + Plugin::UnboxUInt32 = *(uint32_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxUInt32); + Plugin::BoxInt64 = *(int32_t (**)(int64_t val))curMemory; + curMemory += sizeof(Plugin::BoxInt64); + Plugin::UnboxInt64 = *(int64_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxInt64); + Plugin::BoxUInt64 = *(int32_t (**)(uint64_t val))curMemory; + curMemory += sizeof(Plugin::BoxUInt64); + Plugin::UnboxUInt64 = *(uint64_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxUInt64); + Plugin::BoxChar = *(int32_t (**)(uint16_t val))curMemory; + curMemory += sizeof(Plugin::BoxChar); + Plugin::UnboxChar = *(int16_t (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxChar); + Plugin::BoxSingle = *(int32_t (**)(float val))curMemory; + curMemory += sizeof(Plugin::BoxSingle); + Plugin::UnboxSingle = *(float (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxSingle); + Plugin::BoxDouble = *(int32_t (**)(double val))curMemory; + curMemory += sizeof(Plugin::BoxDouble); + Plugin::UnboxDouble = *(double (**)(int32_t valHandle))curMemory; + curMemory += sizeof(Plugin::UnboxDouble); + /*END INIT BODY PARAMETER READS*/ + + // Init managed object ref counting + Plugin::RefCountsLenClass = maxManagedObjects; + Plugin::RefCountsClass = (int32_t*)curMemory; + curMemory += maxManagedObjects * sizeof(int32_t); + + /*BEGIN INIT BODY ARRAYS*/ + Plugin::RefCountsSystemDecimal = (int32_t*)curMemory; + curMemory += 1000 * sizeof(int32_t); + Plugin::RefCountsLenSystemDecimal = 1000; + + Plugin::BaseBallScriptFreeListSize = 1000; + Plugin::BaseBallScriptFreeList = (MyGame::BaseBallScript**)curMemory; + curMemory += 1000 * sizeof(MyGame::BaseBallScript*); + + Plugin::BaseBallScriptFreeWholeListSize = 1000; + Plugin::BaseBallScriptFreeWholeList = (Plugin::BaseBallScriptFreeWholeListEntry*)curMemory; + curMemory += 1000 * sizeof(Plugin::BaseBallScriptFreeWholeListEntry); + /*END INIT BODY ARRAYS*/ + + // Make sure there was enough memory + int32_t usedMemory = (int32_t)(curMemory - (uint8_t*)memory); + if (usedMemory > memorySize) + { + System::String msg = "Plugin memory size is too low"; + System::Exception ex(msg); + Plugin::SetException(ex.Handle); + return; + } + + if (initMode == InitMode::FirstBoot) + { + // Clear memory + memset(memory, 0, memorySize); + + /*BEGIN INIT BODY FIRST BOOT*/ + for (int32_t i = 0, end = Plugin::BaseBallScriptFreeListSize - 1; i < end; ++i) + { + Plugin::BaseBallScriptFreeList[i] = (MyGame::BaseBallScript*)(Plugin::BaseBallScriptFreeList + i + 1); + } + Plugin::BaseBallScriptFreeList[Plugin::BaseBallScriptFreeListSize - 1] = nullptr; + Plugin::NextFreeBaseBallScript = Plugin::BaseBallScriptFreeList + 1; + + for (int32_t i = 0, end = Plugin::BaseBallScriptFreeWholeListSize - 1; i < end; ++i) + { + Plugin::BaseBallScriptFreeWholeList[i].Next = Plugin::BaseBallScriptFreeWholeList + i + 1; + } + Plugin::BaseBallScriptFreeWholeList[Plugin::BaseBallScriptFreeWholeListSize - 1].Next = nullptr; + Plugin::NextFreeWholeBaseBallScript = Plugin::BaseBallScriptFreeWholeList + 1; + /*END INIT BODY FIRST BOOT*/ + } + + try + { + PluginMain( + curMemory, + (int32_t)(memorySize - usedMemory), + initMode == InitMode::FirstBoot); + } + catch (System::Exception ex) + { + Plugin::SetException(ex.Handle); + } + catch (...) + { + System::String msg = "Unhandled exception in PluginMain"; + System::Exception ex(msg); + Plugin::SetException(ex.Handle); + } +} + +// Receive an unhandled exception from C# +DLLEXPORT void SetCsharpException(int32_t handle) +{ + Plugin::unhandledCsharpException = new System::Exception( + Plugin::InternalUse::Only, + handle); +} + diff --git a/Unity/Assets/CppSource/NativeScript/Bindings.cpp.meta b/Unity/Assets/CppSource/NativeScript/Bindings.cpp.meta new file mode 100644 index 0000000..1b1a472 --- /dev/null +++ b/Unity/Assets/CppSource/NativeScript/Bindings.cpp.meta @@ -0,0 +1,26 @@ +fileFormatVersion: 2 +guid: 6b6c5fe253c434b7db04a6d5165c1001 +timeCreated: 1525538114 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/CppSource/NativeScript/Bindings.h b/Unity/Assets/CppSource/NativeScript/Bindings.h new file mode 100644 index 0000000..4da12a4 --- /dev/null +++ b/Unity/Assets/CppSource/NativeScript/Bindings.h @@ -0,0 +1,1669 @@ +/// +/// Declaration of the various .NET types exposed to C++ +/// +/// +/// Jackson Dunstan, 2017, http://JacksonDunstan.com +/// +/// +/// MIT +/// + +#pragma once + +// For int32_t, etc. +#include + +// For size_t to support placement new and delete +#include + +//////////////////////////////////////////////////////////////// +// Plugin internals. Do not name these in game code as they may +// change without warning. For example: +// // Good. Uses behavior, not names. +// int x = myArray[5]; +// // Bad. Directly uses names. +// ArrayElementProxy1_1 proxy = myArray[5]; +// int x = proxy; +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + enum struct InternalUse + { + Only + }; + + struct ManagedType + { + int32_t Handle; + + ManagedType(); + ManagedType(decltype(nullptr)); + ManagedType(InternalUse, int32_t handle); + }; + + template struct ArrayElementProxy1_1; + + template struct ArrayElementProxy1_2; + template struct ArrayElementProxy2_2; + + template struct ArrayElementProxy1_3; + template struct ArrayElementProxy2_3; + template struct ArrayElementProxy3_3; + + template struct ArrayElementProxy1_4; + template struct ArrayElementProxy2_4; + template struct ArrayElementProxy3_4; + template struct ArrayElementProxy4_4; + + template struct ArrayElementProxy1_5; + template struct ArrayElementProxy2_5; + template struct ArrayElementProxy3_5; + template struct ArrayElementProxy4_5; + template struct ArrayElementProxy5_5; +} + +//////////////////////////////////////////////////////////////// +// C# basic types +//////////////////////////////////////////////////////////////// + +namespace System +{ + struct Object; + struct ValueType; + struct Enum; + struct String; + struct Array; + template struct Array1; + template struct Array2; + template struct Array3; + template struct Array4; + template struct Array5; + struct IComparable; + template struct IComparable_1; + template struct IEquatable_1; + struct IFormattable; + struct IConvertible; + + // .NET booleans are four bytes long + // This struct makes them feel like C++'s bool, int32_t, and uint32_t types + struct Boolean + { + int32_t Value; + + Boolean(); + Boolean(bool value); + Boolean(int32_t value); + Boolean(uint32_t value); + operator bool() const; + operator int32_t() const; + operator uint32_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + // .NET chars are two bytes long + // This struct helps them interoperate with C++'s char and int16_t types + struct Char + { + int16_t Value; + + Char(); + Char(char value); + Char(int16_t value); + operator int16_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct SByte + { + int8_t Value; + + SByte(); + SByte(int8_t value); + operator int8_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Byte + { + uint8_t Value; + + Byte(); + Byte(uint8_t value); + operator uint8_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Int16 + { + int16_t Value; + + Int16(); + Int16(int16_t value); + operator int16_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct UInt16 + { + uint16_t Value; + + UInt16(); + UInt16(uint16_t value); + operator uint16_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Int32 + { + int32_t Value; + + Int32(); + Int32(int32_t value); + operator int32_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct UInt32 + { + uint32_t Value; + + UInt32(); + UInt32(uint32_t value); + operator uint32_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Int64 + { + int64_t Value; + + Int64(); + Int64(int64_t value); + operator int64_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct UInt64 + { + uint64_t Value; + + UInt64(); + UInt64(uint64_t value); + operator uint64_t() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Single + { + float Value; + + Single(); + Single(float value); + operator float() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; + + struct Double + { + double Value; + + Double(); + Double(double value); + operator double() const; + explicit operator Object() const; + explicit operator ValueType() const; + explicit operator IComparable() const; + explicit operator IFormattable() const; + explicit operator IConvertible() const; + explicit operator IComparable_1() const; + explicit operator IEquatable_1() const; + }; +} + +/*BEGIN TEMPLATE DECLARATIONS*/ +namespace System +{ + template struct IEquatable_1; +} + +namespace System +{ + template struct IComparable_1; +} +/*END TEMPLATE DECLARATIONS*/ + +/*BEGIN TYPE DECLARATIONS*/ +namespace System +{ + struct IFormattable; +} + +namespace System +{ + struct IConvertible; +} + +namespace System +{ + struct IComparable; +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + struct IDeserializationCallback; + } + } +} + +namespace System +{ + struct Decimal; +} + +namespace UnityEngine +{ + struct Vector3; +} + +namespace UnityEngine +{ + struct Object; +} + +namespace UnityEngine +{ + struct Component; +} + +namespace UnityEngine +{ + struct Transform; +} + +namespace System +{ + namespace Collections + { + struct IEnumerator; + } +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + struct ISerializable; + } + } +} + +namespace System +{ + namespace Runtime + { + namespace InteropServices + { + struct _Exception; + } + } +} + +namespace UnityEngine +{ + struct GameObject; +} + +namespace UnityEngine +{ + struct Debug; +} + +namespace UnityEngine +{ + struct Behaviour; +} + +namespace UnityEngine +{ + struct MonoBehaviour; +} + +namespace System +{ + struct Exception; +} + +namespace System +{ + struct SystemException; +} + +namespace System +{ + struct NullReferenceException; +} + +namespace UnityEngine +{ + struct PrimitiveType; +} + +namespace UnityEngine +{ + struct Time; +} + +namespace MyGame +{ + struct AbstractBaseBallScript; +} + +namespace MyGame +{ + struct BaseBallScript; +} +/*END TYPE DECLARATIONS*/ + +/*BEGIN TEMPLATE SPECIALIZATION DECLARATIONS*/ +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IEquatable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} + +namespace System +{ + template<> struct IComparable_1; +} +/*END TEMPLATE SPECIALIZATION DECLARATIONS*/ + +//////////////////////////////////////////////////////////////// +// C# type definitions +//////////////////////////////////////////////////////////////// + +namespace System +{ + struct Object : Plugin::ManagedType + { + Object(); + Object(Plugin::InternalUse iu, int32_t handle); + Object(decltype(nullptr)); + virtual ~Object(); + bool operator==(decltype(nullptr)) const; + bool operator!=(decltype(nullptr)) const; + virtual void ThrowReferenceToThis(); + + /*BEGIN UNBOXING METHOD DECLARATIONS*/ + explicit operator System::Decimal(); + explicit operator UnityEngine::Vector3(); + explicit operator UnityEngine::PrimitiveType(); + explicit operator System::Boolean(); + explicit operator System::SByte(); + explicit operator System::Byte(); + explicit operator System::Int16(); + explicit operator System::UInt16(); + explicit operator System::Int32(); + explicit operator System::UInt32(); + explicit operator System::Int64(); + explicit operator System::UInt64(); + explicit operator System::Char(); + explicit operator System::Single(); + explicit operator System::Double(); + /*END UNBOXING METHOD DECLARATIONS*/ + }; + + struct ValueType : virtual Object + { + ValueType(Plugin::InternalUse iu, int32_t handle); + ValueType(decltype(nullptr)); + }; + + struct Enum : virtual ValueType + { + Enum(Plugin::InternalUse iu, int32_t handle); + Enum(decltype(nullptr)); + }; + + struct String : virtual Object + { + String(Plugin::InternalUse iu, int32_t handle); + String(decltype(nullptr)); + String(const String& other); + String(String&& other); + virtual ~String(); + String& operator=(const String& other); + String& operator=(decltype(nullptr)); + String& operator=(String&& other); + String(const char* chars); + }; + + struct ICloneable : virtual Object + { + ICloneable(Plugin::InternalUse iu, int32_t handle); + ICloneable(decltype(nullptr)); + }; + + namespace Collections + { + struct IEnumerable : virtual Object + { + IEnumerable(Plugin::InternalUse iu, int32_t handle); + IEnumerable(decltype(nullptr)); + IEnumerator GetEnumerator(); + }; + + struct ICollection : virtual IEnumerable + { + ICollection(Plugin::InternalUse iu, int32_t handle); + ICollection(decltype(nullptr)); + }; + + struct IList : virtual ICollection, virtual IEnumerable + { + IList(Plugin::InternalUse iu, int32_t handle); + IList(decltype(nullptr)); + }; + } + + struct Array : virtual ICloneable, virtual Collections::IList + { + Array(Plugin::InternalUse iu, int32_t handle); + Array(decltype(nullptr)); + int32_t GetLength(); + int32_t GetRank(); + }; +} + +//////////////////////////////////////////////////////////////// +// Global variables +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + extern System::String NullString; +} + +/*BEGIN TYPE DEFINITIONS*/ +namespace System +{ + struct IFormattable : virtual System::Object + { + IFormattable(decltype(nullptr)); + IFormattable(Plugin::InternalUse, int32_t handle); + IFormattable(const IFormattable& other); + IFormattable(IFormattable&& other); + virtual ~IFormattable(); + IFormattable& operator=(const IFormattable& other); + IFormattable& operator=(decltype(nullptr)); + IFormattable& operator=(IFormattable&& other); + bool operator==(const IFormattable& other) const; + bool operator!=(const IFormattable& other) const; + }; +} + +namespace System +{ + struct IConvertible : virtual System::Object + { + IConvertible(decltype(nullptr)); + IConvertible(Plugin::InternalUse, int32_t handle); + IConvertible(const IConvertible& other); + IConvertible(IConvertible&& other); + virtual ~IConvertible(); + IConvertible& operator=(const IConvertible& other); + IConvertible& operator=(decltype(nullptr)); + IConvertible& operator=(IConvertible&& other); + bool operator==(const IConvertible& other) const; + bool operator!=(const IConvertible& other) const; + }; +} + +namespace System +{ + struct IComparable : virtual System::Object + { + IComparable(decltype(nullptr)); + IComparable(Plugin::InternalUse, int32_t handle); + IComparable(const IComparable& other); + IComparable(IComparable&& other); + virtual ~IComparable(); + IComparable& operator=(const IComparable& other); + IComparable& operator=(decltype(nullptr)); + IComparable& operator=(IComparable&& other); + bool operator==(const IComparable& other) const; + bool operator!=(const IComparable& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IEquatable_1 : virtual System::Object + { + IEquatable_1(decltype(nullptr)); + IEquatable_1(Plugin::InternalUse, int32_t handle); + IEquatable_1(const IEquatable_1& other); + IEquatable_1(IEquatable_1&& other); + virtual ~IEquatable_1(); + IEquatable_1& operator=(const IEquatable_1& other); + IEquatable_1& operator=(decltype(nullptr)); + IEquatable_1& operator=(IEquatable_1&& other); + bool operator==(const IEquatable_1& other) const; + bool operator!=(const IEquatable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + template<> struct IComparable_1 : virtual System::Object + { + IComparable_1(decltype(nullptr)); + IComparable_1(Plugin::InternalUse, int32_t handle); + IComparable_1(const IComparable_1& other); + IComparable_1(IComparable_1&& other); + virtual ~IComparable_1(); + IComparable_1& operator=(const IComparable_1& other); + IComparable_1& operator=(decltype(nullptr)); + IComparable_1& operator=(IComparable_1&& other); + bool operator==(const IComparable_1& other) const; + bool operator!=(const IComparable_1& other) const; + }; +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + struct IDeserializationCallback : virtual System::Object + { + IDeserializationCallback(decltype(nullptr)); + IDeserializationCallback(Plugin::InternalUse, int32_t handle); + IDeserializationCallback(const IDeserializationCallback& other); + IDeserializationCallback(IDeserializationCallback&& other); + virtual ~IDeserializationCallback(); + IDeserializationCallback& operator=(const IDeserializationCallback& other); + IDeserializationCallback& operator=(decltype(nullptr)); + IDeserializationCallback& operator=(IDeserializationCallback&& other); + bool operator==(const IDeserializationCallback& other) const; + bool operator!=(const IDeserializationCallback& other) const; + }; + } + } +} + +namespace System +{ + struct Decimal : Plugin::ManagedType + { + Decimal(decltype(nullptr)); + Decimal(Plugin::InternalUse, int32_t handle); + Decimal(const Decimal& other); + Decimal(Decimal&& other); + virtual ~Decimal(); + Decimal& operator=(const Decimal& other); + Decimal& operator=(decltype(nullptr)); + Decimal& operator=(Decimal&& other); + bool operator==(const Decimal& other) const; + bool operator!=(const Decimal& other) const; + Decimal(System::Double value); + Decimal(System::UInt64 value); + explicit operator System::ValueType(); + explicit operator System::Object(); + explicit operator System::IComparable(); + explicit operator System::IComparable_1(); + explicit operator System::IConvertible(); + explicit operator System::IEquatable_1(); + explicit operator System::Runtime::Serialization::IDeserializationCallback(); + explicit operator System::IFormattable(); + }; +} + +namespace UnityEngine +{ + struct Vector3 + { + Vector3(); + Vector3(System::Single x, System::Single y, System::Single z); + System::Single x; + System::Single y; + System::Single z; + UnityEngine::Vector3 operator+(UnityEngine::Vector3& a); + explicit operator System::ValueType(); + explicit operator System::Object(); + explicit operator System::IEquatable_1(); + }; +} + +namespace UnityEngine +{ + struct Object : virtual System::Object + { + Object(decltype(nullptr)); + Object(Plugin::InternalUse, int32_t handle); + Object(const Object& other); + Object(Object&& other); + virtual ~Object(); + Object& operator=(const Object& other); + Object& operator=(decltype(nullptr)); + Object& operator=(Object&& other); + bool operator==(const Object& other) const; + bool operator!=(const Object& other) const; + System::String GetName(); + void SetName(System::String& value); + }; +} + +namespace UnityEngine +{ + struct Component : virtual UnityEngine::Object + { + Component(decltype(nullptr)); + Component(Plugin::InternalUse, int32_t handle); + Component(const Component& other); + Component(Component&& other); + virtual ~Component(); + Component& operator=(const Component& other); + Component& operator=(decltype(nullptr)); + Component& operator=(Component&& other); + bool operator==(const Component& other) const; + bool operator!=(const Component& other) const; + UnityEngine::Transform GetTransform(); + }; +} + +namespace UnityEngine +{ + struct Transform : virtual UnityEngine::Component, virtual System::Collections::IEnumerable + { + Transform(decltype(nullptr)); + Transform(Plugin::InternalUse, int32_t handle); + Transform(const Transform& other); + Transform(Transform&& other); + virtual ~Transform(); + Transform& operator=(const Transform& other); + Transform& operator=(decltype(nullptr)); + Transform& operator=(Transform&& other); + bool operator==(const Transform& other) const; + bool operator!=(const Transform& other) const; + UnityEngine::Vector3 GetPosition(); + void SetPosition(UnityEngine::Vector3& value); + }; +} + +namespace System +{ + namespace Collections + { + struct IEnumerator : virtual System::Object + { + IEnumerator(decltype(nullptr)); + IEnumerator(Plugin::InternalUse, int32_t handle); + IEnumerator(const IEnumerator& other); + IEnumerator(IEnumerator&& other); + virtual ~IEnumerator(); + IEnumerator& operator=(const IEnumerator& other); + IEnumerator& operator=(decltype(nullptr)); + IEnumerator& operator=(IEnumerator&& other); + bool operator==(const IEnumerator& other) const; + bool operator!=(const IEnumerator& other) const; + System::Object GetCurrent(); + System::Boolean MoveNext(); + }; + } +} + +namespace System +{ + namespace Runtime + { + namespace Serialization + { + struct ISerializable : virtual System::Object + { + ISerializable(decltype(nullptr)); + ISerializable(Plugin::InternalUse, int32_t handle); + ISerializable(const ISerializable& other); + ISerializable(ISerializable&& other); + virtual ~ISerializable(); + ISerializable& operator=(const ISerializable& other); + ISerializable& operator=(decltype(nullptr)); + ISerializable& operator=(ISerializable&& other); + bool operator==(const ISerializable& other) const; + bool operator!=(const ISerializable& other) const; + }; + } + } +} + +namespace System +{ + namespace Runtime + { + namespace InteropServices + { + struct _Exception : virtual System::Object + { + _Exception(decltype(nullptr)); + _Exception(Plugin::InternalUse, int32_t handle); + _Exception(const _Exception& other); + _Exception(_Exception&& other); + virtual ~_Exception(); + _Exception& operator=(const _Exception& other); + _Exception& operator=(decltype(nullptr)); + _Exception& operator=(_Exception&& other); + bool operator==(const _Exception& other) const; + bool operator!=(const _Exception& other) const; + }; + } + } +} + +namespace UnityEngine +{ + struct GameObject : virtual UnityEngine::Object + { + GameObject(decltype(nullptr)); + GameObject(Plugin::InternalUse, int32_t handle); + GameObject(const GameObject& other); + GameObject(GameObject&& other); + virtual ~GameObject(); + GameObject& operator=(const GameObject& other); + GameObject& operator=(decltype(nullptr)); + GameObject& operator=(GameObject&& other); + bool operator==(const GameObject& other) const; + bool operator!=(const GameObject& other) const; + template MT0 AddComponent(); + static UnityEngine::GameObject CreatePrimitive(UnityEngine::PrimitiveType type); + }; +} + +namespace UnityEngine +{ + struct Debug : virtual System::Object + { + Debug(decltype(nullptr)); + Debug(Plugin::InternalUse, int32_t handle); + Debug(const Debug& other); + Debug(Debug&& other); + virtual ~Debug(); + Debug& operator=(const Debug& other); + Debug& operator=(decltype(nullptr)); + Debug& operator=(Debug&& other); + bool operator==(const Debug& other) const; + bool operator!=(const Debug& other) const; + static void Log(System::Object& message); + }; +} + +namespace UnityEngine +{ + struct Behaviour : virtual UnityEngine::Component + { + Behaviour(decltype(nullptr)); + Behaviour(Plugin::InternalUse, int32_t handle); + Behaviour(const Behaviour& other); + Behaviour(Behaviour&& other); + virtual ~Behaviour(); + Behaviour& operator=(const Behaviour& other); + Behaviour& operator=(decltype(nullptr)); + Behaviour& operator=(Behaviour&& other); + bool operator==(const Behaviour& other) const; + bool operator!=(const Behaviour& other) const; + }; +} + +namespace UnityEngine +{ + struct MonoBehaviour : virtual UnityEngine::Behaviour + { + MonoBehaviour(decltype(nullptr)); + MonoBehaviour(Plugin::InternalUse, int32_t handle); + MonoBehaviour(const MonoBehaviour& other); + MonoBehaviour(MonoBehaviour&& other); + virtual ~MonoBehaviour(); + MonoBehaviour& operator=(const MonoBehaviour& other); + MonoBehaviour& operator=(decltype(nullptr)); + MonoBehaviour& operator=(MonoBehaviour&& other); + bool operator==(const MonoBehaviour& other) const; + bool operator!=(const MonoBehaviour& other) const; + UnityEngine::Transform GetTransform(); + }; +} + +namespace System +{ + struct Exception : virtual System::Runtime::InteropServices::_Exception, virtual System::Runtime::Serialization::ISerializable + { + Exception(decltype(nullptr)); + Exception(Plugin::InternalUse, int32_t handle); + Exception(const Exception& other); + Exception(Exception&& other); + virtual ~Exception(); + Exception& operator=(const Exception& other); + Exception& operator=(decltype(nullptr)); + Exception& operator=(Exception&& other); + bool operator==(const Exception& other) const; + bool operator!=(const Exception& other) const; + Exception(System::String& message); + }; +} + +namespace System +{ + struct SystemException : virtual System::Exception, virtual System::Runtime::InteropServices::_Exception, virtual System::Runtime::Serialization::ISerializable + { + SystemException(decltype(nullptr)); + SystemException(Plugin::InternalUse, int32_t handle); + SystemException(const SystemException& other); + SystemException(SystemException&& other); + virtual ~SystemException(); + SystemException& operator=(const SystemException& other); + SystemException& operator=(decltype(nullptr)); + SystemException& operator=(SystemException&& other); + bool operator==(const SystemException& other) const; + bool operator!=(const SystemException& other) const; + }; +} + +namespace System +{ + struct NullReferenceException : virtual System::SystemException, virtual System::Runtime::InteropServices::_Exception, virtual System::Runtime::Serialization::ISerializable + { + NullReferenceException(decltype(nullptr)); + NullReferenceException(Plugin::InternalUse, int32_t handle); + NullReferenceException(const NullReferenceException& other); + NullReferenceException(NullReferenceException&& other); + virtual ~NullReferenceException(); + NullReferenceException& operator=(const NullReferenceException& other); + NullReferenceException& operator=(decltype(nullptr)); + NullReferenceException& operator=(NullReferenceException&& other); + bool operator==(const NullReferenceException& other) const; + bool operator!=(const NullReferenceException& other) const; + }; +} + +namespace UnityEngine +{ + struct PrimitiveType + { + int32_t Value; + static const UnityEngine::PrimitiveType Sphere; + static const UnityEngine::PrimitiveType Capsule; + static const UnityEngine::PrimitiveType Cylinder; + static const UnityEngine::PrimitiveType Cube; + static const UnityEngine::PrimitiveType Plane; + static const UnityEngine::PrimitiveType Quad; + explicit PrimitiveType(int32_t value); + explicit operator int32_t() const; + bool operator==(PrimitiveType other); + bool operator!=(PrimitiveType other); + explicit operator System::Enum(); + explicit operator System::ValueType(); + explicit operator System::Object(); + explicit operator System::IComparable(); + explicit operator System::IConvertible(); + explicit operator System::IFormattable(); + }; +} + +namespace UnityEngine +{ + struct Time : virtual System::Object + { + Time(decltype(nullptr)); + Time(Plugin::InternalUse, int32_t handle); + Time(const Time& other); + Time(Time&& other); + virtual ~Time(); + Time& operator=(const Time& other); + Time& operator=(decltype(nullptr)); + Time& operator=(Time&& other); + bool operator==(const Time& other) const; + bool operator!=(const Time& other) const; + static System::Single GetDeltaTime(); + }; +} + +namespace MyGame +{ + struct AbstractBaseBallScript : virtual UnityEngine::MonoBehaviour + { + AbstractBaseBallScript(decltype(nullptr)); + AbstractBaseBallScript(Plugin::InternalUse, int32_t handle); + AbstractBaseBallScript(const AbstractBaseBallScript& other); + AbstractBaseBallScript(AbstractBaseBallScript&& other); + virtual ~AbstractBaseBallScript(); + AbstractBaseBallScript& operator=(const AbstractBaseBallScript& other); + AbstractBaseBallScript& operator=(decltype(nullptr)); + AbstractBaseBallScript& operator=(AbstractBaseBallScript&& other); + bool operator==(const AbstractBaseBallScript& other) const; + bool operator!=(const AbstractBaseBallScript& other) const; + }; +} + +namespace MyGame +{ + struct BaseBallScript : virtual MyGame::AbstractBaseBallScript + { + BaseBallScript(decltype(nullptr)); + BaseBallScript(Plugin::InternalUse, int32_t handle); + BaseBallScript(const BaseBallScript& other); + BaseBallScript(BaseBallScript&& other); + virtual ~BaseBallScript(); + BaseBallScript& operator=(const BaseBallScript& other); + BaseBallScript& operator=(decltype(nullptr)); + BaseBallScript& operator=(BaseBallScript&& other); + bool operator==(const BaseBallScript& other) const; + bool operator!=(const BaseBallScript& other) const; + int32_t CppHandle; + BaseBallScript(); + virtual void Update(); + }; +} +/*END TYPE DEFINITIONS*/ + +/*BEGIN MACROS*/ +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONSTRUCTOR_DECLARATION \ + BallScript(Plugin::InternalUse iu, int32_t handle); + +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONSTRUCTOR_DEFINITION \ + BallScript::BallScript(Plugin::InternalUse iu, int32_t handle) \ + : UnityEngine::Object(nullptr) \ + , UnityEngine::Component(nullptr) \ + , UnityEngine::Behaviour(nullptr) \ + , UnityEngine::MonoBehaviour(nullptr) \ + , MyGame::AbstractBaseBallScript(nullptr) \ + , MyGame::BaseBallScript(iu, handle) \ + { \ + } + +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONSTRUCTOR \ + BallScript(Plugin::InternalUse iu, int32_t handle) \ + : UnityEngine::Object(nullptr) \ + , UnityEngine::Component(nullptr) \ + , UnityEngine::Behaviour(nullptr) \ + , UnityEngine::MonoBehaviour(nullptr) \ + , MyGame::AbstractBaseBallScript(nullptr) \ + , MyGame::BaseBallScript(iu, handle) \ + { \ + } + +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONTENTS_DECLARATION \ + void* operator new(size_t, void* p) noexcept; \ + void operator delete(void*, size_t) noexcept; \ + +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONTENTS_DEFINITION \ + void* BallScript::operator new(size_t, void* p) noexcept\ + { \ + return p; \ + } \ + void BallScript::operator delete(void*, size_t) noexcept \ + { \ + } + +#define MY_GAME_BALL_SCRIPT_DEFAULT_CONTENTS\ + void* operator new(size_t, void* p) noexcept \ + { \ + return p; \ + } \ + void operator delete(void*, size_t) noexcept \ + { \ + } +/*END MACROS*/ + +//////////////////////////////////////////////////////////////// +// Support for using IEnumerable with range for loops +//////////////////////////////////////////////////////////////// + +namespace Plugin +{ + struct EnumerableIterator + { + System::Collections::IEnumerator enumerator; + bool hasMore; + EnumerableIterator(decltype(nullptr)); + EnumerableIterator(System::Collections::IEnumerable& enumerable); + EnumerableIterator& operator++(); + bool operator!=(const EnumerableIterator& other); + System::Object operator*(); + }; +} + +namespace System +{ + namespace Collections + { + Plugin::EnumerableIterator begin(IEnumerable& enumerable); + Plugin::EnumerableIterator end(IEnumerable& enumerable); + } +} + +//////////////////////////////////////////////////////////////// +// User-defined literals for creating decimals (System.Decimal) +//////////////////////////////////////////////////////////////// + +System::Decimal operator"" _m(long double x); +System::Decimal operator"" _m(unsigned long long x); diff --git a/Unity/Assets/CppSource/NativeScript/Bindings.h.meta b/Unity/Assets/CppSource/NativeScript/Bindings.h.meta new file mode 100644 index 0000000..615fc4b --- /dev/null +++ b/Unity/Assets/CppSource/NativeScript/Bindings.h.meta @@ -0,0 +1,26 @@ +fileFormatVersion: 2 +guid: 2fa6cfa70e93c4d59a7f05e21c18d56b +timeCreated: 1525538114 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/CppSource/iOS.cmake b/Unity/Assets/CppSource/iOS.cmake similarity index 100% rename from Unity/CppSource/iOS.cmake rename to Unity/Assets/CppSource/iOS.cmake diff --git a/Unity/Assets/CppSource/iOS.cmake.meta b/Unity/Assets/CppSource/iOS.cmake.meta new file mode 100644 index 0000000..f706a0b --- /dev/null +++ b/Unity/Assets/CppSource/iOS.cmake.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4d9a55f92979e442396f99d94a5e9ec5 +timeCreated: 1525538114 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/Game.meta b/Unity/Assets/Game.meta new file mode 100644 index 0000000..42f3c6b --- /dev/null +++ b/Unity/Assets/Game.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bb19f2d6c4c0e41c18cdd5ead2b97cec +folderAsset: yes +timeCreated: 1519492407 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/Game/AbstractBaseBallScript.cs b/Unity/Assets/Game/AbstractBaseBallScript.cs new file mode 100644 index 0000000..8694d19 --- /dev/null +++ b/Unity/Assets/Game/AbstractBaseBallScript.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace MyGame +{ + /// + /// Base class of a script used in the example code to make a "ball" bounce + /// back and forth on the screen + /// + /// + /// Jackson Dunstan, 2018, http://JacksonDunstan.com + /// + /// + /// MIT + /// + public abstract class AbstractBaseBallScript : MonoBehaviour + { + public abstract void Update(); + } +} diff --git a/Unity/Assets/NativeScript/ObjectStore.cs.meta b/Unity/Assets/Game/AbstractBaseBallScript.cs.meta similarity index 70% rename from Unity/Assets/NativeScript/ObjectStore.cs.meta rename to Unity/Assets/Game/AbstractBaseBallScript.cs.meta index c203e63..0757588 100644 --- a/Unity/Assets/NativeScript/ObjectStore.cs.meta +++ b/Unity/Assets/Game/AbstractBaseBallScript.cs.meta @@ -1,8 +1,9 @@ fileFormatVersion: 2 -guid: da44db2587e2f46d58d0318a1a71bd03 -timeCreated: 1499537422 +guid: 7c6c722578a90428dbeacfd4a5aaa3ae +timeCreated: 1520705999 licenseType: Free MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Unity/Assets/NativeScript/Bindings.cs b/Unity/Assets/NativeScript/Bindings.cs index b5ee2e5..3ae570d 100644 --- a/Unity/Assets/NativeScript/Bindings.cs +++ b/Unity/Assets/NativeScript/Bindings.cs @@ -1,11 +1,12 @@ using AOT; using System; +using System.Collections; using System.IO; using System.Runtime.InteropServices; +using System.Collections.Generic; using UnityEngine; -using UnityEngine.Assertions; namespace NativeScript { @@ -21,80 +22,331 @@ namespace NativeScript /// public static class Bindings { + // Holds objects and provides handles to them in the form of ints + public static class ObjectStore + { + // Lookup handles by object. + static Dictionary objectHandleCache; + + // Stored objects. The first is never used so 0 can be "null". + static object[] objects; + + // Stack of available handles. + static int[] handles; + + // Index of the next available handle + static int nextHandleIndex; + + // The maximum number of objects to store. Must be positive. + static int maxObjects; + + public static void Init(int maxObjects) + { + ObjectStore.maxObjects = maxObjects; + objectHandleCache = new Dictionary(maxObjects); + + // Initialize the objects as all null plus room for the + // first to always be null. + objects = new object[maxObjects + 1]; + + // Initialize the handles stack as 1, 2, 3, ... + handles = new int[maxObjects]; + for ( + int i = 0, handle = maxObjects; + i < maxObjects; + ++i, --handle) + { + handles[i] = handle; + } + nextHandleIndex = maxObjects - 1; + } + + public static int Store(object obj) + { + // Null is always zero + if (object.ReferenceEquals(obj, null)) + { + return 0; + } + + lock (objects) + { + // Pop a handle off the stack + int handle = handles[nextHandleIndex]; + nextHandleIndex--; + + // Store the object + objects[handle] = obj; + objectHandleCache.Add(obj, handle); + + return handle; + } + } + + public static object Get(int handle) + { + return objects[handle]; + } + + public static int GetHandle(object obj) + { + // Null is always zero + if (object.ReferenceEquals(obj, null)) + { + return 0; + } + + lock (objects) + { + int handle; + + // Get handle from object cache + if (objectHandleCache.TryGetValue(obj, out handle)) + { + return handle; + } + } + + // Object not found + return Store(obj); + } + + public static object Remove(int handle) + { + // Null is never stored, so there's nothing to remove + if (handle == 0) + { + return null; + } + + lock (objects) + { + // Forget the object + object obj = objects[handle]; + objects[handle] = null; + + // Push the handle onto the stack + nextHandleIndex++; + handles[nextHandleIndex] = handle; + + // Remove the object from the cache + objectHandleCache.Remove(obj); + + return obj; + } + } + } + + // Holds structs and provides handles to them in the form of ints + public static class StructStore + where T : struct + { + // Stored structs. The first is never used so 0 can be "null". + static T[] structs; + + // Stack of available handles + static int[] handles; + + // Index of the next available handle + static int nextHandleIndex; + + public static void Init(int maxStructs) + { + // Initialize the objects as all default plus room for the + // first to always be unused. + structs = new T[maxStructs + 1]; + + // Initialize the handles stack as 1, 2, 3, ... + handles = new int[maxStructs]; + for ( + int i = 0, handle = maxStructs; + i < maxStructs; + ++i, --handle) + { + handles[i] = handle; + } + nextHandleIndex = maxStructs - 1; + } + + public static int Store(T structToStore) + { + lock (structs) + { + // Pop a handle off the stack + int handle = handles[nextHandleIndex]; + nextHandleIndex--; + + // Store the struct + structs[handle] = structToStore; + + return handle; + } + } + + public static void Replace(int handle, ref T structToStore) + { + structs[handle] = structToStore; + } + + public static T Get(int handle) + { + return structs[handle]; + } + + public static void Remove(int handle) + { + if (handle != 0) + { + lock (structs) + { + // Forget the struct + structs[handle] = default(T); + + // Push the handle onto the stack + nextHandleIndex++; + handles[nextHandleIndex] = handle; + } + } + } + } + + /// + /// A reusable version of UnityEngine.WaitForSecondsRealtime to avoid + /// GC allocs + /// + class ReusableWaitForSecondsRealtime : CustomYieldInstruction + { + private float waitTime; + + public float WaitTime + { + set + { + waitTime = Time.realtimeSinceStartup + value; + } + } + + public override bool keepWaiting + { + get + { + return Time.realtimeSinceStartup < waitTime; + } + } + + public ReusableWaitForSecondsRealtime(float time) + { + WaitTime = time; + } + } + + public enum DestroyFunction + { + /*BEGIN DESTROY FUNCTION ENUMERATORS*/ + BaseBallScript + /*END DESTROY FUNCTION ENUMERATORS*/ + } + + struct DestroyEntry + { + public DestroyFunction Function; + public int CppHandle; + + public DestroyEntry(DestroyFunction function, int cppHandle) + { + Function = function; + CppHandle = cppHandle; + } + } + + // Name of the plugin when using [DllImport] +#if !UNITY_EDITOR && UNITY_IOS + const string PLUGIN_NAME = "__Internal"; +#else + const string PLUGIN_NAME = "NativeScript"; +#endif + + // Path to load the plugin from when running inside the editor +#if UNITY_EDITOR_OSX + const string PLUGIN_PATH = "/Plugins/Editor/NativeScript.bundle/Contents/MacOS/NativeScript"; +#elif UNITY_EDITOR_LINUX + const string PLUGIN_PATH = "/Plugins/Editor/libNativeScript.so"; +#elif UNITY_EDITOR_WIN + const string PLUGIN_PATH = "/Plugins/Editor/NativeScript.dll"; + const string PLUGIN_TEMP_PATH = "/Plugins/Editor/NativeScript_temp.dll"; +#endif + + enum InitMode : byte + { + FirstBoot, + Reload + } + #if UNITY_EDITOR // Handle to the C++ DLL - public static IntPtr libraryHandle; - - public delegate void InitDelegate( - int maxManagedObjects, - IntPtr releaseObject, - IntPtr stringNew, - /*BEGIN INIT PARAMS*/ - IntPtr stopwatchConstructor, - IntPtr stopwatchPropertyGetElapsedMilliseconds, - IntPtr stopwatchMethodStart, - IntPtr stopwatchMethodReset, - IntPtr objectPropertyGetName, - IntPtr objectPropertySetName, - IntPtr gameObjectConstructor, - IntPtr gameObjectConstructorSystemString, - IntPtr gameObjectPropertyGetTransform, - IntPtr gameObjectMethodFindSystemString, - IntPtr gameObjectMethodAddComponentMyGameMonoBehavioursTestScript, - IntPtr componentPropertyGetTransform, - IntPtr transformPropertyGetPosition, - IntPtr transformPropertySetPosition, - IntPtr debugMethodLogSystemObject, - IntPtr assertFieldGetRaiseExceptions, - IntPtr assertFieldSetRaiseExceptions - /*END INIT PARAMS*/); - - /*BEGIN MONOBEHAVIOUR DELEGATES*/ - public delegate void TestScriptAwakeDelegate(int thisHandle); - public static TestScriptAwakeDelegate TestScriptAwake; - - public delegate void TestScriptOnAnimatorIKDelegate(int thisHandle, int param0); - public static TestScriptOnAnimatorIKDelegate TestScriptOnAnimatorIK; - - public delegate void TestScriptOnCollisionEnterDelegate(int thisHandle, int param0); - public static TestScriptOnCollisionEnterDelegate TestScriptOnCollisionEnter; - - public delegate void TestScriptUpdateDelegate(int thisHandle); - public static TestScriptUpdateDelegate TestScriptUpdate; - /*END MONOBEHAVIOUR DELEGATES*/ + static IntPtr libraryHandle; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void InitDelegate( + IntPtr memory, + int memorySize, + InitMode initMode); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SetCsharpExceptionDelegate(int handle); + + /*BEGIN CPP DELEGATES*/ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int NewBaseBallScriptDelegateType(int param0); + public static NewBaseBallScriptDelegateType NewBaseBallScript; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void DestroyBaseBallScriptDelegateType(int param0); + public static DestroyBaseBallScriptDelegateType DestroyBaseBallScript; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void MyGameAbstractBaseBallScriptUpdateDelegateType(int thisHandle); + public static MyGameAbstractBaseBallScriptUpdateDelegateType MyGameAbstractBaseBallScriptUpdate; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SetCsharpExceptionSystemNullReferenceExceptionDelegateType(int param0); + public static SetCsharpExceptionSystemNullReferenceExceptionDelegateType SetCsharpExceptionSystemNullReferenceException; + /*END CPP DELEGATES*/ #endif #if UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX - [DllImport("__Internal")] - public static extern IntPtr dlopen( + [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr dlopen( string path, int flag); - [DllImport("__Internal")] - public static extern IntPtr dlsym( + [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr dlsym( IntPtr handle, string symbolName); - [DllImport("__Internal")] - public static extern int dlclose( + [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)] + static extern int dlclose( IntPtr handle); - public static IntPtr OpenLibrary(string path) + static IntPtr OpenLibrary( + string path) { - IntPtr handle = dlopen(path, 0); + IntPtr handle = dlopen(path, 1); // 1 = lazy, 2 = now if (handle == IntPtr.Zero) { throw new Exception("Couldn't open native library: " + path); } return handle; } - - public static void CloseLibrary(IntPtr libraryHandle) + + static void CloseLibrary( + IntPtr libraryHandle) { dlclose(libraryHandle); } - - public static T GetDelegate( + + static T GetDelegate( IntPtr libraryHandle, string functionName) where T : class { @@ -108,20 +360,20 @@ public static T GetDelegate( typeof(T)) as T; } #elif UNITY_EDITOR_WIN - [DllImport("kernel32")] - public static extern IntPtr LoadLibrary( + [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] + static extern IntPtr LoadLibrary( string path); - - [DllImport("kernel32")] - public static extern IntPtr GetProcAddress( + + [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] + static extern IntPtr GetProcAddress( IntPtr libraryHandle, string symbolName); - - [DllImport("kernel32")] - public static extern bool FreeLibrary( + + [DllImport("kernel32.dll", SetLastError=true)] + static extern bool FreeLibrary( IntPtr libraryHandle); - - public static IntPtr OpenLibrary(string path) + + static IntPtr OpenLibrary(string path) { IntPtr handle = LoadLibrary(path); if (handle == IntPtr.Zero) @@ -130,13 +382,13 @@ public static IntPtr OpenLibrary(string path) } return handle; } - - public static void CloseLibrary(IntPtr libraryHandle) + + static void CloseLibrary(IntPtr libraryHandle) { FreeLibrary(libraryHandle); } - - public static T GetDelegate( + + static T GetDelegate( IntPtr libraryHandle, string functionName) where T : class { @@ -150,130 +402,553 @@ public static T GetDelegate( typeof(T)) as T; } #else - [DllImport(NativeScriptConstants.PluginName)] + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] static extern void Init( - int maxManagedObjects, - IntPtr releaseObject, - IntPtr stringNew, - /*BEGIN INIT PARAMS*/ - IntPtr stopwatchConstructor, - IntPtr stopwatchPropertyGetElapsedMilliseconds, - IntPtr stopwatchMethodStart, - IntPtr stopwatchMethodReset, - IntPtr objectPropertyGetName, - IntPtr objectPropertySetName, - IntPtr gameObjectConstructor, - IntPtr gameObjectConstructorSystemString, - IntPtr gameObjectPropertyGetTransform, - IntPtr gameObjectMethodFindSystemString, - IntPtr gameObjectMethodAddComponentMyGameMonoBehavioursTestScript, - IntPtr componentPropertyGetTransform, - IntPtr transformPropertyGetPosition, - IntPtr transformPropertySetPosition, - IntPtr debugMethodLogSystemObject, - IntPtr assertFieldGetRaiseExceptions, - IntPtr assertFieldSetRaiseExceptions - /*END INIT PARAMS*/); - - /*BEGIN MONOBEHAVIOUR IMPORTS*/ - [DllImport(NativeScriptConstants.PluginName)] - public static extern void TestScriptAwake(int thisHandle); - - [DllImport(NativeScriptConstants.PluginName)] - public static extern void TestScriptOnAnimatorIK(int thisHandle, int param0); - - [DllImport(NativeScriptConstants.PluginName)] - public static extern void TestScriptOnCollisionEnter(int thisHandle, int param0); - - [DllImport(NativeScriptConstants.PluginName)] - public static extern void TestScriptUpdate(int thisHandle); - /*END MONOBEHAVIOUR IMPORTS*/ + IntPtr memory, + int memorySize, + InitMode initMode); + + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] + static extern void SetCsharpException(int handle); + + /*BEGIN IMPORTS*/ + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] + public static extern int NewBaseBallScript(int thisHandle); + + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] + public static extern void DestroyBaseBallScript(int thisHandle); + + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] + public static extern void MyGameAbstractBaseBallScriptUpdate(int thisHandle); + + [DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)] + public static extern void SetCsharpExceptionSystemNullReferenceException(int thisHandle); + /*END IMPORTS*/ #endif - - delegate void ReleaseObjectDelegate(int handle); - delegate int StringNewDelegate(string chars); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void ReleaseObjectDelegateType(int handle); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int StringNewDelegateType(string chars); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void SetExceptionDelegateType(int handle); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int ArrayGetLengthDelegateType(int handle); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int EnumerableGetEnumeratorDelegateType(int handle); /*BEGIN DELEGATE TYPES*/ - delegate int StopwatchConstructorDelegate(); - delegate long StopwatchPropertyGetElapsedMillisecondsDelegate(int thisHandle); - delegate void StopwatchMethodStartDelegate(int thisHandle); - delegate void StopwatchMethodResetDelegate(int thisHandle); - delegate int ObjectPropertyGetNameDelegate(int thisHandle); - delegate void ObjectPropertySetNameDelegate(int thisHandle, int valueHandle); - delegate int GameObjectConstructorDelegate(); - delegate int GameObjectConstructorSystemStringDelegate(int nameHandle); - delegate int GameObjectPropertyGetTransformDelegate(int thisHandle); - delegate int GameObjectMethodFindSystemStringDelegate(int nameHandle); - delegate int GameObjectMethodAddComponentMyGameMonoBehavioursTestScriptDelegate(int thisHandle); - delegate int ComponentPropertyGetTransformDelegate(int thisHandle); - delegate UnityEngine.Vector3 TransformPropertyGetPositionDelegate(int thisHandle); - delegate void TransformPropertySetPositionDelegate(int thisHandle, UnityEngine.Vector3 value); - delegate void DebugMethodLogSystemObjectDelegate(int messageHandle); - delegate bool AssertFieldGetRaiseExceptionsDelegate(); - delegate void AssertFieldSetRaiseExceptionsDelegate(bool value); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void ReleaseSystemDecimalDelegateType(int handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int SystemDecimalConstructorSystemDoubleDelegateType(double value); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int SystemDecimalConstructorSystemUInt64DelegateType(ulong value); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxDecimalDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnboxDecimalDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate UnityEngine.Vector3 UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegateType(float x, float y, float z); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate UnityEngine.Vector3 UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3DelegateType(ref UnityEngine.Vector3 a, ref UnityEngine.Vector3 b); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxVector3DelegateType(ref UnityEngine.Vector3 val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate UnityEngine.Vector3 UnboxVector3DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnityEngineObjectPropertyGetNameDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void UnityEngineObjectPropertySetNameDelegateType(int thisHandle, int valueHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnityEngineComponentPropertyGetTransformDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate UnityEngine.Vector3 UnityEngineTransformPropertyGetPositionDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void UnityEngineTransformPropertySetPositionDelegateType(int thisHandle, ref UnityEngine.Vector3 value); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int SystemCollectionsIEnumeratorPropertyGetCurrentDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate bool SystemCollectionsIEnumeratorMethodMoveNextDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegateType(UnityEngine.PrimitiveType type); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void UnityEngineDebugMethodLogSystemObjectDelegateType(int messageHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnityEngineMonoBehaviourPropertyGetTransformDelegateType(int thisHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int SystemExceptionConstructorSystemStringDelegateType(int messageHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxPrimitiveTypeDelegateType(UnityEngine.PrimitiveType val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate UnityEngine.PrimitiveType UnboxPrimitiveTypeDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate float UnityEngineTimePropertyGetDeltaTimeDelegateType(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void BaseBallScriptConstructorDelegateType(int cppHandle, ref int handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void ReleaseBaseBallScriptDelegateType(int handle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxBooleanDelegateType(bool val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate bool UnboxBooleanDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxSByteDelegateType(sbyte val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate sbyte UnboxSByteDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxByteDelegateType(byte val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate byte UnboxByteDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxInt16DelegateType(short val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate short UnboxInt16DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxUInt16DelegateType(ushort val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate ushort UnboxUInt16DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxInt32DelegateType(int val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int UnboxInt32DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxUInt32DelegateType(uint val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate uint UnboxUInt32DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxInt64DelegateType(long val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate long UnboxInt64DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxUInt64DelegateType(ulong val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate ulong UnboxUInt64DelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxCharDelegateType(char val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate char UnboxCharDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxSingleDelegateType(float val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate float UnboxSingleDelegateType(int valHandle); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int BoxDoubleDelegateType(double val); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate double UnboxDoubleDelegateType(int valHandle); /*END DELEGATE TYPES*/ - public static void Open() - { +#if UNITY_EDITOR_WIN + private static readonly string pluginTempPath = Application.dataPath + PLUGIN_TEMP_PATH; +#endif + public static Exception UnhandledCppException; #if UNITY_EDITOR + private static readonly string pluginPath = Application.dataPath + PLUGIN_PATH; + public static SetCsharpExceptionDelegate SetCsharpException; +#endif + static IntPtr memory; + static int memorySize; + static DestroyEntry[] destroyQueue; + static int destroyQueueCount; + static int destroyQueueCapacity; + static object destroyQueueLockObj; + + // Fixed delegates + static readonly ReleaseObjectDelegateType ReleaseObjectDelegate = new ReleaseObjectDelegateType(ReleaseObject); + static readonly StringNewDelegateType StringNewDelegate = new StringNewDelegateType(StringNew); + static readonly SetExceptionDelegateType SetExceptionDelegate = new SetExceptionDelegateType(SetException); + static readonly ArrayGetLengthDelegateType ArrayGetLengthDelegate = new ArrayGetLengthDelegateType(ArrayGetLength); + static readonly EnumerableGetEnumeratorDelegateType EnumerableGetEnumeratorDelegate = new EnumerableGetEnumeratorDelegateType(EnumerableGetEnumerator); + + // Generated delegates + /*BEGIN CSHARP DELEGATES*/ + static readonly ReleaseSystemDecimalDelegateType ReleaseSystemDecimalDelegate = new ReleaseSystemDecimalDelegateType(ReleaseSystemDecimal); + static readonly SystemDecimalConstructorSystemDoubleDelegateType SystemDecimalConstructorSystemDoubleDelegate = new SystemDecimalConstructorSystemDoubleDelegateType(SystemDecimalConstructorSystemDouble); + static readonly SystemDecimalConstructorSystemUInt64DelegateType SystemDecimalConstructorSystemUInt64Delegate = new SystemDecimalConstructorSystemUInt64DelegateType(SystemDecimalConstructorSystemUInt64); + static readonly BoxDecimalDelegateType BoxDecimalDelegate = new BoxDecimalDelegateType(BoxDecimal); + static readonly UnboxDecimalDelegateType UnboxDecimalDelegate = new UnboxDecimalDelegateType(UnboxDecimal); + static readonly UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegateType UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegate = new UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegateType(UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle); + static readonly UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3DelegateType UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3Delegate = new UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3DelegateType(UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3); + static readonly BoxVector3DelegateType BoxVector3Delegate = new BoxVector3DelegateType(BoxVector3); + static readonly UnboxVector3DelegateType UnboxVector3Delegate = new UnboxVector3DelegateType(UnboxVector3); + static readonly UnityEngineObjectPropertyGetNameDelegateType UnityEngineObjectPropertyGetNameDelegate = new UnityEngineObjectPropertyGetNameDelegateType(UnityEngineObjectPropertyGetName); + static readonly UnityEngineObjectPropertySetNameDelegateType UnityEngineObjectPropertySetNameDelegate = new UnityEngineObjectPropertySetNameDelegateType(UnityEngineObjectPropertySetName); + static readonly UnityEngineComponentPropertyGetTransformDelegateType UnityEngineComponentPropertyGetTransformDelegate = new UnityEngineComponentPropertyGetTransformDelegateType(UnityEngineComponentPropertyGetTransform); + static readonly UnityEngineTransformPropertyGetPositionDelegateType UnityEngineTransformPropertyGetPositionDelegate = new UnityEngineTransformPropertyGetPositionDelegateType(UnityEngineTransformPropertyGetPosition); + static readonly UnityEngineTransformPropertySetPositionDelegateType UnityEngineTransformPropertySetPositionDelegate = new UnityEngineTransformPropertySetPositionDelegateType(UnityEngineTransformPropertySetPosition); + static readonly SystemCollectionsIEnumeratorPropertyGetCurrentDelegateType SystemCollectionsIEnumeratorPropertyGetCurrentDelegate = new SystemCollectionsIEnumeratorPropertyGetCurrentDelegateType(SystemCollectionsIEnumeratorPropertyGetCurrent); + static readonly SystemCollectionsIEnumeratorMethodMoveNextDelegateType SystemCollectionsIEnumeratorMethodMoveNextDelegate = new SystemCollectionsIEnumeratorMethodMoveNextDelegateType(SystemCollectionsIEnumeratorMethodMoveNext); + static readonly UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegateType UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegate = new UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegateType(UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript); + static readonly UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegateType UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegate = new UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegateType(UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType); + static readonly UnityEngineDebugMethodLogSystemObjectDelegateType UnityEngineDebugMethodLogSystemObjectDelegate = new UnityEngineDebugMethodLogSystemObjectDelegateType(UnityEngineDebugMethodLogSystemObject); + static readonly UnityEngineMonoBehaviourPropertyGetTransformDelegateType UnityEngineMonoBehaviourPropertyGetTransformDelegate = new UnityEngineMonoBehaviourPropertyGetTransformDelegateType(UnityEngineMonoBehaviourPropertyGetTransform); + static readonly SystemExceptionConstructorSystemStringDelegateType SystemExceptionConstructorSystemStringDelegate = new SystemExceptionConstructorSystemStringDelegateType(SystemExceptionConstructorSystemString); + static readonly BoxPrimitiveTypeDelegateType BoxPrimitiveTypeDelegate = new BoxPrimitiveTypeDelegateType(BoxPrimitiveType); + static readonly UnboxPrimitiveTypeDelegateType UnboxPrimitiveTypeDelegate = new UnboxPrimitiveTypeDelegateType(UnboxPrimitiveType); + static readonly UnityEngineTimePropertyGetDeltaTimeDelegateType UnityEngineTimePropertyGetDeltaTimeDelegate = new UnityEngineTimePropertyGetDeltaTimeDelegateType(UnityEngineTimePropertyGetDeltaTime); + static readonly ReleaseBaseBallScriptDelegateType ReleaseBaseBallScriptDelegate = new ReleaseBaseBallScriptDelegateType(ReleaseBaseBallScript); + static readonly BaseBallScriptConstructorDelegateType BaseBallScriptConstructorDelegate = new BaseBallScriptConstructorDelegateType(BaseBallScriptConstructor); + static readonly BoxBooleanDelegateType BoxBooleanDelegate = new BoxBooleanDelegateType(BoxBoolean); + static readonly UnboxBooleanDelegateType UnboxBooleanDelegate = new UnboxBooleanDelegateType(UnboxBoolean); + static readonly BoxSByteDelegateType BoxSByteDelegate = new BoxSByteDelegateType(BoxSByte); + static readonly UnboxSByteDelegateType UnboxSByteDelegate = new UnboxSByteDelegateType(UnboxSByte); + static readonly BoxByteDelegateType BoxByteDelegate = new BoxByteDelegateType(BoxByte); + static readonly UnboxByteDelegateType UnboxByteDelegate = new UnboxByteDelegateType(UnboxByte); + static readonly BoxInt16DelegateType BoxInt16Delegate = new BoxInt16DelegateType(BoxInt16); + static readonly UnboxInt16DelegateType UnboxInt16Delegate = new UnboxInt16DelegateType(UnboxInt16); + static readonly BoxUInt16DelegateType BoxUInt16Delegate = new BoxUInt16DelegateType(BoxUInt16); + static readonly UnboxUInt16DelegateType UnboxUInt16Delegate = new UnboxUInt16DelegateType(UnboxUInt16); + static readonly BoxInt32DelegateType BoxInt32Delegate = new BoxInt32DelegateType(BoxInt32); + static readonly UnboxInt32DelegateType UnboxInt32Delegate = new UnboxInt32DelegateType(UnboxInt32); + static readonly BoxUInt32DelegateType BoxUInt32Delegate = new BoxUInt32DelegateType(BoxUInt32); + static readonly UnboxUInt32DelegateType UnboxUInt32Delegate = new UnboxUInt32DelegateType(UnboxUInt32); + static readonly BoxInt64DelegateType BoxInt64Delegate = new BoxInt64DelegateType(BoxInt64); + static readonly UnboxInt64DelegateType UnboxInt64Delegate = new UnboxInt64DelegateType(UnboxInt64); + static readonly BoxUInt64DelegateType BoxUInt64Delegate = new BoxUInt64DelegateType(BoxUInt64); + static readonly UnboxUInt64DelegateType UnboxUInt64Delegate = new UnboxUInt64DelegateType(UnboxUInt64); + static readonly BoxCharDelegateType BoxCharDelegate = new BoxCharDelegateType(BoxChar); + static readonly UnboxCharDelegateType UnboxCharDelegate = new UnboxCharDelegateType(UnboxChar); + static readonly BoxSingleDelegateType BoxSingleDelegate = new BoxSingleDelegateType(BoxSingle); + static readonly UnboxSingleDelegateType UnboxSingleDelegate = new UnboxSingleDelegateType(UnboxSingle); + static readonly BoxDoubleDelegateType BoxDoubleDelegate = new BoxDoubleDelegateType(BoxDouble); + static readonly UnboxDoubleDelegateType UnboxDoubleDelegate = new UnboxDoubleDelegateType(UnboxDouble); + /*END CSHARP DELEGATES*/ + + /// + /// Open the C++ plugin and call its PluginMain() + /// + /// + /// + /// Number of bytes of memory to make available to the C++ plugin + /// + public static void Open(int memorySize) + { + /*BEGIN STORE INIT CALLS*/ + NativeScript.Bindings.ObjectStore.Init(1000); + NativeScript.Bindings.StructStore.Init(1000); + /*END STORE INIT CALLS*/ + + // Allocate unmanaged memory + Bindings.memorySize = memorySize; + memory = Marshal.AllocHGlobal(memorySize); + + // Allocate destroy queue + destroyQueueCapacity = 128; + destroyQueue = new DestroyEntry[destroyQueueCapacity]; + destroyQueueLockObj = new object(); + OpenPlugin(InitMode.FirstBoot); + } + + // Reloading requires dynamic loading of the C++ plugin, which is only + // available in the editor +#if UNITY_EDITOR + /// + /// Reload the C++ plugin. Its memory is intact and false is passed for + /// the isFirstBoot parameter of PluginMain(). + /// + public static void Reload() + { + DestroyAll(); + ClosePlugin(); + OpenPlugin(InitMode.Reload); + } + + /// + /// Poll the plugin for changes and reload if any are found. + /// + /// + /// + /// Number of seconds between polls. + /// + /// + /// + /// Enumerator for this iterator function. Can be passed to + /// MonoBehaviour.StartCoroutine for easy usage. + /// + public static IEnumerator AutoReload(float pollTime) + { + // Get the original time + long lastWriteTime = File.GetLastWriteTime(pluginPath).Ticks; + + ReusableWaitForSecondsRealtime poll + = new ReusableWaitForSecondsRealtime(pollTime); + do + { + // Poll. Reload if the last write time changed. + long cur = File.GetLastWriteTime(pluginPath).Ticks; + if (cur != lastWriteTime) + { + lastWriteTime = cur; + Reload(); + } + + // Wait to poll again + poll.WaitTime = pollTime; + yield return poll; + } + while (true); + } +#endif + + private static void OpenPlugin(InitMode initMode) + { +#if UNITY_EDITOR + string loadPath; +#if UNITY_EDITOR_WIN + // Copy native library to temporary file + File.Copy(pluginPath, pluginTempPath, true); + loadPath = pluginTempPath; +#else + loadPath = pluginPath; +#endif // Open native library - libraryHandle = OpenLibrary( - Application.dataPath + NativeScriptConstants.PluginPath); + libraryHandle = OpenLibrary(loadPath); InitDelegate Init = GetDelegate( libraryHandle, "Init"); - /*BEGIN MONOBEHAVIOUR GETDELEGATE CALLS*/ - TestScriptAwake = GetDelegate(libraryHandle, "TestScriptAwake"); - TestScriptOnAnimatorIK = GetDelegate(libraryHandle, "TestScriptOnAnimatorIK"); - TestScriptOnCollisionEnter = GetDelegate(libraryHandle, "TestScriptOnCollisionEnter"); - TestScriptUpdate = GetDelegate(libraryHandle, "TestScriptUpdate"); - /*END MONOBEHAVIOUR GETDELEGATE CALLS*/ - + SetCsharpException = GetDelegate( + libraryHandle, + "SetCsharpException"); + /*BEGIN GETDELEGATE CALLS*/ + NewBaseBallScript = GetDelegate(libraryHandle, "NewBaseBallScript"); + DestroyBaseBallScript = GetDelegate(libraryHandle, "DestroyBaseBallScript"); + MyGameAbstractBaseBallScriptUpdate = GetDelegate(libraryHandle, "MyGameAbstractBaseBallScriptUpdate"); + SetCsharpExceptionSystemNullReferenceException = GetDelegate(libraryHandle, "SetCsharpExceptionSystemNullReferenceException"); + /*END GETDELEGATE CALLS*/ #endif - + // Pass parameters through 'memory' + int curMemory = 0; + Marshal.WriteIntPtr( + memory, + curMemory, + Marshal.GetFunctionPointerForDelegate(ReleaseObjectDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr( + memory, + curMemory, + Marshal.GetFunctionPointerForDelegate(StringNewDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr( + memory, + curMemory, + Marshal.GetFunctionPointerForDelegate(SetExceptionDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr( + memory, + curMemory, + Marshal.GetFunctionPointerForDelegate(ArrayGetLengthDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr( + memory, + curMemory, + Marshal.GetFunctionPointerForDelegate(EnumerableGetEnumeratorDelegate)); + curMemory += IntPtr.Size; + + /*BEGIN INIT CALL*/ + Marshal.WriteInt32(memory, curMemory, 1000); // max managed objects + curMemory += sizeof(int); + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(ReleaseSystemDecimalDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(SystemDecimalConstructorSystemDoubleDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(SystemDecimalConstructorSystemUInt64Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxDecimalDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxDecimalDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxVector3Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxVector3Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineObjectPropertyGetNameDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineObjectPropertySetNameDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineComponentPropertyGetTransformDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineTransformPropertyGetPositionDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineTransformPropertySetPositionDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(SystemCollectionsIEnumeratorPropertyGetCurrentDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(SystemCollectionsIEnumeratorMethodMoveNextDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineDebugMethodLogSystemObjectDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineMonoBehaviourPropertyGetTransformDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(SystemExceptionConstructorSystemStringDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxPrimitiveTypeDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxPrimitiveTypeDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnityEngineTimePropertyGetDeltaTimeDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(ReleaseBaseBallScriptDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BaseBallScriptConstructorDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxBooleanDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxBooleanDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxSByteDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxSByteDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxByteDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxByteDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxInt16Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxInt16Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxUInt16Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxUInt16Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxInt32Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxInt32Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxUInt32Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxUInt32Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxInt64Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxInt64Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxUInt64Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxUInt64Delegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxCharDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxCharDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxSingleDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxSingleDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(BoxDoubleDelegate)); + curMemory += IntPtr.Size; + Marshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate(UnboxDoubleDelegate)); + curMemory += IntPtr.Size; + /*END INIT CALL*/ + // Init C++ library - ObjectStore.Init(NativeScriptConstants.MaxManagedObjects); - Init( - NativeScriptConstants.MaxManagedObjects, - Marshal.GetFunctionPointerForDelegate(new ReleaseObjectDelegate(ReleaseObject)), - Marshal.GetFunctionPointerForDelegate(new StringNewDelegate(StringNew)), - /*BEGIN INIT CALL*/ - Marshal.GetFunctionPointerForDelegate(new StopwatchConstructorDelegate(StopwatchConstructor)), - Marshal.GetFunctionPointerForDelegate(new StopwatchPropertyGetElapsedMillisecondsDelegate(StopwatchPropertyGetElapsedMilliseconds)), - Marshal.GetFunctionPointerForDelegate(new StopwatchMethodStartDelegate(StopwatchMethodStart)), - Marshal.GetFunctionPointerForDelegate(new StopwatchMethodResetDelegate(StopwatchMethodReset)), - Marshal.GetFunctionPointerForDelegate(new ObjectPropertyGetNameDelegate(ObjectPropertyGetName)), - Marshal.GetFunctionPointerForDelegate(new ObjectPropertySetNameDelegate(ObjectPropertySetName)), - Marshal.GetFunctionPointerForDelegate(new GameObjectConstructorDelegate(GameObjectConstructor)), - Marshal.GetFunctionPointerForDelegate(new GameObjectConstructorSystemStringDelegate(GameObjectConstructorSystemString)), - Marshal.GetFunctionPointerForDelegate(new GameObjectPropertyGetTransformDelegate(GameObjectPropertyGetTransform)), - Marshal.GetFunctionPointerForDelegate(new GameObjectMethodFindSystemStringDelegate(GameObjectMethodFindSystemString)), - Marshal.GetFunctionPointerForDelegate(new GameObjectMethodAddComponentMyGameMonoBehavioursTestScriptDelegate(GameObjectMethodAddComponentMyGameMonoBehavioursTestScript)), - Marshal.GetFunctionPointerForDelegate(new ComponentPropertyGetTransformDelegate(ComponentPropertyGetTransform)), - Marshal.GetFunctionPointerForDelegate(new TransformPropertyGetPositionDelegate(TransformPropertyGetPosition)), - Marshal.GetFunctionPointerForDelegate(new TransformPropertySetPositionDelegate(TransformPropertySetPosition)), - Marshal.GetFunctionPointerForDelegate(new DebugMethodLogSystemObjectDelegate(DebugMethodLogSystemObject)), - Marshal.GetFunctionPointerForDelegate(new AssertFieldGetRaiseExceptionsDelegate(AssertFieldGetRaiseExceptions)), - Marshal.GetFunctionPointerForDelegate(new AssertFieldSetRaiseExceptionsDelegate(AssertFieldSetRaiseExceptions)) - /*END INIT CALL*/ - ); + Init(memory, memorySize, initMode); + if (UnhandledCppException != null) + { + Exception ex = UnhandledCppException; + UnhandledCppException = null; + throw new Exception("Unhandled C++ exception in Init", ex); + } } + /// + /// Close the C++ plugin + /// public static void Close() { + ClosePlugin(); + Marshal.FreeHGlobal(memory); + memory = IntPtr.Zero; + } + + /// + /// Perform updates over time + /// + public static void Update() + { + DestroyAll(); + } + + private static void ClosePlugin() + { #if UNITY_EDITOR CloseLibrary(libraryHandle); libraryHandle = IntPtr.Zero; #endif +#if UNITY_EDITOR_WIN + File.Delete(pluginTempPath); +#endif + } + + public static void QueueDestroy(DestroyFunction function, int cppHandle) + { + lock (destroyQueueLockObj) + { + // Grow capacity if necessary + int count = destroyQueueCount; + int capacity = destroyQueueCapacity; + DestroyEntry[] queue = destroyQueue; + if (count == capacity) + { + int newCapacity = capacity * 2; + DestroyEntry[] newQueue = new DestroyEntry[newCapacity]; + for (int i = 0; i < capacity; ++i) + { + newQueue[i] = queue[i]; + } + destroyQueueCapacity = newCapacity; + destroyQueue = newQueue; + queue = newQueue; + } + + // Add to the end + queue[count] = new DestroyEntry(function, cppHandle); + destroyQueueCount = count + 1; + } } + static void DestroyAll() + { + lock (destroyQueueLockObj) + { + int count = destroyQueueCount; + DestroyEntry[] queue = destroyQueue; + for (int i = 0; i < count; ++i) + { + DestroyEntry entry = queue[i]; + switch (entry.Function) + { + /*BEGIN DESTROY QUEUE CASES*/ + case DestroyFunction.BaseBallScript: + DestroyBaseBallScript(entry.CppHandle); + break; + /*END DESTROY QUEUE CASES*/ + } + } + destroyQueueCount = 0; + } + } + //////////////////////////////////////////////////////////////// // C# functions for C++ to call //////////////////////////////////////////////////////////////// - [MonoPInvokeCallback(typeof(ReleaseObjectDelegate))] + [MonoPInvokeCallback(typeof(ReleaseObjectDelegateType))] static void ReleaseObject( int handle) { @@ -283,7 +958,7 @@ static void ReleaseObject( } } - [MonoPInvokeCallback(typeof(StringNewDelegate))] + [MonoPInvokeCallback(typeof(StringNewDelegateType))] static int StringNew( string chars) { @@ -291,174 +966,1192 @@ static int StringNew( return handle; } - /*BEGIN FUNCTIONS*/ - [MonoPInvokeCallback(typeof(StopwatchConstructorDelegate))] - static int StopwatchConstructor() - { - var obj = ObjectStore.Store(new System.Diagnostics.Stopwatch()); - return obj; - } - - [MonoPInvokeCallback(typeof(StopwatchPropertyGetElapsedMillisecondsDelegate))] - static long StopwatchPropertyGetElapsedMilliseconds(int thisHandle) + [MonoPInvokeCallback(typeof(SetExceptionDelegateType))] + static void SetException(int handle) { - var thiz = (System.Diagnostics.Stopwatch)ObjectStore.Get(thisHandle); - var obj = thiz.ElapsedMilliseconds; - return obj; + UnhandledCppException = ObjectStore.Get(handle) as Exception; } - [MonoPInvokeCallback(typeof(StopwatchMethodStartDelegate))] - static void StopwatchMethodStart(int thisHandle) + [MonoPInvokeCallback(typeof(ArrayGetLengthDelegateType))] + static int ArrayGetLength(int handle) { - var thiz = (System.Diagnostics.Stopwatch)ObjectStore.Get(thisHandle); - thiz.Start(); + return ((Array)ObjectStore.Get(handle)).Length; } - [MonoPInvokeCallback(typeof(StopwatchMethodResetDelegate))] - static void StopwatchMethodReset(int thisHandle) + [MonoPInvokeCallback(typeof(EnumerableGetEnumeratorDelegateType))] + static int EnumerableGetEnumerator(int handle) { - var thiz = (System.Diagnostics.Stopwatch)ObjectStore.Get(thisHandle); - thiz.Reset(); + return ObjectStore.Store(((IEnumerable)ObjectStore.Get(handle)).GetEnumerator()); } - - [MonoPInvokeCallback(typeof(ObjectPropertyGetNameDelegate))] - static int ObjectPropertyGetName(int thisHandle) + + /*BEGIN FUNCTIONS*/ + [MonoPInvokeCallback(typeof(ReleaseSystemDecimalDelegateType))] + static void ReleaseSystemDecimal(int handle) { - var thiz = (UnityEngine.Object)ObjectStore.Get(thisHandle); - var obj = thiz.name; - int handle = ObjectStore.Store(obj); - return handle; + try + { + if (handle != 0) + { + NativeScript.Bindings.StructStore.Remove(handle); + } + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + } } - [MonoPInvokeCallback(typeof(ObjectPropertySetNameDelegate))] - static void ObjectPropertySetName(int thisHandle, int valueHandle) + [MonoPInvokeCallback(typeof(SystemDecimalConstructorSystemDoubleDelegateType))] + static int SystemDecimalConstructorSystemDouble(double value) { - var thiz = (UnityEngine.Object)ObjectStore.Get(thisHandle); - thiz.name = (string)ObjectStore.Get(valueHandle); + try + { + var returnValue = NativeScript.Bindings.StructStore.Store(new System.Decimal(value)); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(GameObjectConstructorDelegate))] - static int GameObjectConstructor() + [MonoPInvokeCallback(typeof(SystemDecimalConstructorSystemUInt64DelegateType))] + static int SystemDecimalConstructorSystemUInt64(ulong value) { - var obj = ObjectStore.Store(new UnityEngine.GameObject()); - return obj; + try + { + var returnValue = NativeScript.Bindings.StructStore.Store(new System.Decimal(value)); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(GameObjectConstructorSystemStringDelegate))] - static int GameObjectConstructorSystemString(int nameHandle) + [MonoPInvokeCallback(typeof(BoxDecimalDelegateType))] + static int BoxDecimal(int valHandle) { - var obj = ObjectStore.Store(new UnityEngine.GameObject((System.String)ObjectStore.Get(nameHandle))); - return obj; + try + { + var val = (System.Decimal)NativeScript.Bindings.StructStore.Get(valHandle); + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(GameObjectPropertyGetTransformDelegate))] - static int GameObjectPropertyGetTransform(int thisHandle) + [MonoPInvokeCallback(typeof(UnboxDecimalDelegateType))] + static int UnboxDecimal(int valHandle) { - var thiz = (UnityEngine.GameObject)ObjectStore.Get(thisHandle); - var obj = thiz.transform; - int handle = ObjectStore.Store(obj); - return handle; + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = NativeScript.Bindings.StructStore.Store((System.Decimal)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(GameObjectMethodFindSystemStringDelegate))] - static int GameObjectMethodFindSystemString(int nameHandle) + [MonoPInvokeCallback(typeof(UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingleDelegateType))] + static UnityEngine.Vector3 UnityEngineVector3ConstructorSystemSingle_SystemSingle_SystemSingle(float x, float y, float z) { - var obj = UnityEngine.GameObject.Find((System.String)ObjectStore.Get(nameHandle)); - int handle = ObjectStore.Store(obj); - return handle; + try + { + var returnValue = new UnityEngine.Vector3(x, y, z); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } } - [MonoPInvokeCallback(typeof(GameObjectMethodAddComponentMyGameMonoBehavioursTestScriptDelegate))] - static int GameObjectMethodAddComponentMyGameMonoBehavioursTestScript(int thisHandle) + [MonoPInvokeCallback(typeof(UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3DelegateType))] + static UnityEngine.Vector3 UnityEngineVector3Methodop_AdditionUnityEngineVector3_UnityEngineVector3(ref UnityEngine.Vector3 a, ref UnityEngine.Vector3 b) { - var thiz = (UnityEngine.GameObject)ObjectStore.Get(thisHandle); - var obj = thiz.AddComponent(); - int handle = ObjectStore.Store(obj); - return handle; + try + { + var returnValue = a + b; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } } - [MonoPInvokeCallback(typeof(ComponentPropertyGetTransformDelegate))] - static int ComponentPropertyGetTransform(int thisHandle) + [MonoPInvokeCallback(typeof(BoxVector3DelegateType))] + static int BoxVector3(ref UnityEngine.Vector3 val) { - var thiz = (UnityEngine.Component)ObjectStore.Get(thisHandle); - var obj = thiz.transform; - int handle = ObjectStore.Store(obj); - return handle; + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(TransformPropertyGetPositionDelegate))] - static UnityEngine.Vector3 TransformPropertyGetPosition(int thisHandle) + [MonoPInvokeCallback(typeof(UnboxVector3DelegateType))] + static UnityEngine.Vector3 UnboxVector3(int valHandle) { - var thiz = (UnityEngine.Transform)ObjectStore.Get(thisHandle); - var obj = thiz.position; - return obj; + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (UnityEngine.Vector3)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); + } } - [MonoPInvokeCallback(typeof(TransformPropertySetPositionDelegate))] - static void TransformPropertySetPosition(int thisHandle, UnityEngine.Vector3 value) + [MonoPInvokeCallback(typeof(UnityEngineObjectPropertyGetNameDelegateType))] + static int UnityEngineObjectPropertyGetName(int thisHandle) { - var thiz = (UnityEngine.Transform)ObjectStore.Get(thisHandle); - thiz.position = value; + try + { + var thiz = (UnityEngine.Object)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.name; + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(DebugMethodLogSystemObjectDelegate))] - static void DebugMethodLogSystemObject(int messageHandle) + [MonoPInvokeCallback(typeof(UnityEngineObjectPropertySetNameDelegateType))] + static void UnityEngineObjectPropertySetName(int thisHandle, int valueHandle) { - UnityEngine.Debug.Log(ObjectStore.Get(messageHandle)); + try + { + var thiz = (UnityEngine.Object)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var value = (string)NativeScript.Bindings.ObjectStore.Get(valueHandle); + thiz.name = value; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + } } - [MonoPInvokeCallback(typeof(AssertFieldGetRaiseExceptionsDelegate))] - static bool AssertFieldGetRaiseExceptions() + [MonoPInvokeCallback(typeof(UnityEngineComponentPropertyGetTransformDelegateType))] + static int UnityEngineComponentPropertyGetTransform(int thisHandle) { - var obj = UnityEngine.Assertions.Assert.raiseExceptions; - return obj; + try + { + var thiz = (UnityEngine.Component)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.transform; + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } } - [MonoPInvokeCallback(typeof(AssertFieldSetRaiseExceptionsDelegate))] - static void AssertFieldSetRaiseExceptions(bool value) - { - UnityEngine.Assertions.Assert.raiseExceptions = value; - } - /*END FUNCTIONS*/ - } -} - -/*BEGIN MONOBEHAVIOURS*/ -namespace MyGame -{ - namespace MonoBehaviours - { - public class TestScript : UnityEngine.MonoBehaviour + [MonoPInvokeCallback(typeof(UnityEngineTransformPropertyGetPositionDelegateType))] + static UnityEngine.Vector3 UnityEngineTransformPropertyGetPosition(int thisHandle) { - private int thisHandle; - - public TestScript() + try { - thisHandle = NativeScript.ObjectStore.Store(this); + var thiz = (UnityEngine.Transform)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.position; + return returnValue; } - - public void Awake() + catch (System.NullReferenceException ex) { - NativeScript.Bindings.TestScriptAwake(thisHandle); + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); } - - public void OnAnimatorIK(int param0) + catch (System.Exception ex) { - NativeScript.Bindings.TestScriptOnAnimatorIK(thisHandle, param0); + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.Vector3); } - - public void OnCollisionEnter(UnityEngine.Collision param0) + } + + [MonoPInvokeCallback(typeof(UnityEngineTransformPropertySetPositionDelegateType))] + static void UnityEngineTransformPropertySetPosition(int thisHandle, ref UnityEngine.Vector3 value) + { + try { - int param0Handle = NativeScript.ObjectStore.Store(param0); - NativeScript.Bindings.TestScriptOnCollisionEnter(thisHandle, param0Handle); - NativeScript.ObjectStore.Remove(param0Handle); + var thiz = (UnityEngine.Transform)NativeScript.Bindings.ObjectStore.Get(thisHandle); + thiz.position = value; } - - public void Update() + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + } + + [MonoPInvokeCallback(typeof(SystemCollectionsIEnumeratorPropertyGetCurrentDelegateType))] + static int SystemCollectionsIEnumeratorPropertyGetCurrent(int thisHandle) + { + try + { + var thiz = (System.Collections.IEnumerator)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.Current; + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(SystemCollectionsIEnumeratorMethodMoveNextDelegateType))] + static bool SystemCollectionsIEnumeratorMethodMoveNext(int thisHandle) + { + try + { + var thiz = (System.Collections.IEnumerator)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.MoveNext(); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(bool); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(bool); + } + } + + [MonoPInvokeCallback(typeof(UnityEngineGameObjectMethodAddComponentMyGameBaseBallScriptDelegateType))] + static int UnityEngineGameObjectMethodAddComponentMyGameBaseBallScript(int thisHandle) + { + try + { + var thiz = (UnityEngine.GameObject)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.AddComponent(); + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveTypeDelegateType))] + static int UnityEngineGameObjectMethodCreatePrimitiveUnityEnginePrimitiveType(UnityEngine.PrimitiveType type) + { + try + { + var returnValue = UnityEngine.GameObject.CreatePrimitive(type); + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnityEngineDebugMethodLogSystemObjectDelegateType))] + static void UnityEngineDebugMethodLogSystemObject(int messageHandle) + { + try + { + var message = NativeScript.Bindings.ObjectStore.Get(messageHandle); + UnityEngine.Debug.Log(message); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + } + + [MonoPInvokeCallback(typeof(UnityEngineMonoBehaviourPropertyGetTransformDelegateType))] + static int UnityEngineMonoBehaviourPropertyGetTransform(int thisHandle) + { + try + { + var thiz = (UnityEngine.MonoBehaviour)NativeScript.Bindings.ObjectStore.Get(thisHandle); + var returnValue = thiz.transform; + return NativeScript.Bindings.ObjectStore.GetHandle(returnValue); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(SystemExceptionConstructorSystemStringDelegateType))] + static int SystemExceptionConstructorSystemString(int messageHandle) + { + try + { + var message = (string)NativeScript.Bindings.ObjectStore.Get(messageHandle); + var returnValue = NativeScript.Bindings.ObjectStore.Store(new System.Exception(message)); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(BoxPrimitiveTypeDelegateType))] + static int BoxPrimitiveType(UnityEngine.PrimitiveType val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxPrimitiveTypeDelegateType))] + static UnityEngine.PrimitiveType UnboxPrimitiveType(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (UnityEngine.PrimitiveType)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.PrimitiveType); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(UnityEngine.PrimitiveType); + } + } + + [MonoPInvokeCallback(typeof(UnityEngineTimePropertyGetDeltaTimeDelegateType))] + static float UnityEngineTimePropertyGetDeltaTime() + { + try + { + var returnValue = UnityEngine.Time.deltaTime; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(float); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(float); + } + } + + [MonoPInvokeCallback(typeof(BaseBallScriptConstructorDelegateType))] + static void BaseBallScriptConstructor(int cppHandle, ref int handle) + { + try + { + var thiz = new MyGame.BaseBallScript(cppHandle); + handle = NativeScript.Bindings.ObjectStore.Store(thiz); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + handle = default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + handle = default(int); + } + } + + [MonoPInvokeCallback(typeof(ReleaseBaseBallScriptDelegateType))] + static void ReleaseBaseBallScript(int handle) + { + try + { + MyGame.BaseBallScript thiz; + thiz = (MyGame.BaseBallScript)ObjectStore.Get(handle); + int cppHandle = thiz.CppHandle; + thiz.CppHandle = 0; + QueueDestroy(DestroyFunction.BaseBallScript, cppHandle); + ObjectStore.Remove(handle); + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + } + } + + [MonoPInvokeCallback(typeof(BoxBooleanDelegateType))] + static int BoxBoolean(bool val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxBooleanDelegateType))] + static bool UnboxBoolean(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (bool)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(bool); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(bool); + } + } + + [MonoPInvokeCallback(typeof(BoxSByteDelegateType))] + static int BoxSByte(sbyte val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxSByteDelegateType))] + static sbyte UnboxSByte(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (sbyte)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(sbyte); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(sbyte); + } + } + + [MonoPInvokeCallback(typeof(BoxByteDelegateType))] + static int BoxByte(byte val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxByteDelegateType))] + static byte UnboxByte(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (byte)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(byte); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(byte); + } + } + + [MonoPInvokeCallback(typeof(BoxInt16DelegateType))] + static int BoxInt16(short val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxInt16DelegateType))] + static short UnboxInt16(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (short)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(short); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(short); + } + } + + [MonoPInvokeCallback(typeof(BoxUInt16DelegateType))] + static int BoxUInt16(ushort val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxUInt16DelegateType))] + static ushort UnboxUInt16(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (ushort)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(ushort); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(ushort); + } + } + + [MonoPInvokeCallback(typeof(BoxInt32DelegateType))] + static int BoxInt32(int val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxInt32DelegateType))] + static int UnboxInt32(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (int)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(BoxUInt32DelegateType))] + static int BoxUInt32(uint val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxUInt32DelegateType))] + static uint UnboxUInt32(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (uint)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(uint); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(uint); + } + } + + [MonoPInvokeCallback(typeof(BoxInt64DelegateType))] + static int BoxInt64(long val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxInt64DelegateType))] + static long UnboxInt64(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (long)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(long); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(long); + } + } + + [MonoPInvokeCallback(typeof(BoxUInt64DelegateType))] + static int BoxUInt64(ulong val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxUInt64DelegateType))] + static ulong UnboxUInt64(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (ulong)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(ulong); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(ulong); + } + } + + [MonoPInvokeCallback(typeof(BoxCharDelegateType))] + static int BoxChar(char val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxCharDelegateType))] + static char UnboxChar(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (char)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(char); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(char); + } + } + + [MonoPInvokeCallback(typeof(BoxSingleDelegateType))] + static int BoxSingle(float val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxSingleDelegateType))] + static float UnboxSingle(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (float)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(float); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(float); + } + } + + [MonoPInvokeCallback(typeof(BoxDoubleDelegateType))] + static int BoxDouble(double val) + { + try + { + var returnValue = NativeScript.Bindings.ObjectStore.Store((object)val); + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(int); + } + } + + [MonoPInvokeCallback(typeof(UnboxDoubleDelegateType))] + static double UnboxDouble(int valHandle) + { + try + { + var val = NativeScript.Bindings.ObjectStore.Get(valHandle); + var returnValue = (double)val; + return returnValue; + } + catch (System.NullReferenceException ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpExceptionSystemNullReferenceException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(double); + } + catch (System.Exception ex) + { + UnityEngine.Debug.LogException(ex); + NativeScript.Bindings.SetCsharpException(NativeScript.Bindings.ObjectStore.Store(ex)); + return default(double); + } + } + /*END FUNCTIONS*/ + } +} + +/*BEGIN BASE TYPES*/ +namespace MyGame +{ + class BaseBallScript : MyGame.AbstractBaseBallScript + { + public int CppHandle; + + public BaseBallScript() + { + int handle = NativeScript.Bindings.ObjectStore.Store(this); + CppHandle = NativeScript.Bindings.NewBaseBallScript(handle); + } + + ~BaseBallScript() + { + if (CppHandle != 0) + { + NativeScript.Bindings.QueueDestroy(NativeScript.Bindings.DestroyFunction.BaseBallScript, CppHandle); + CppHandle = 0; + } + } + + public BaseBallScript(int cppHandle) + : base() + { + CppHandle = cppHandle; + } + + public override void Update() + { + if (CppHandle != 0) { - NativeScript.Bindings.TestScriptUpdate(thisHandle); + int thisHandle = CppHandle; + NativeScript.Bindings.MyGameAbstractBaseBallScriptUpdate(thisHandle); + if (NativeScript.Bindings.UnhandledCppException != null) + { + Exception ex = NativeScript.Bindings.UnhandledCppException; + NativeScript.Bindings.UnhandledCppException = null; + throw ex; + } } } + } } -/*END MONOBEHAVIOURS*/ \ No newline at end of file +/*END BASE TYPES*/ \ No newline at end of file diff --git a/Unity/Assets/NativeScript/BootScene.unity b/Unity/Assets/NativeScript/BootScene.unity index 5491c69..8a205bf 100644 Binary files a/Unity/Assets/NativeScript/BootScene.unity and b/Unity/Assets/NativeScript/BootScene.unity differ diff --git a/Unity/Assets/NativeScript/BootScript.cs b/Unity/Assets/NativeScript/BootScript.cs index bf3b0eb..74c8268 100644 --- a/Unity/Assets/NativeScript/BootScript.cs +++ b/Unity/Assets/NativeScript/BootScript.cs @@ -1,3 +1,5 @@ +using System; +using UnityEditor; using UnityEngine; namespace NativeScript @@ -5,23 +7,89 @@ namespace NativeScript /// /// Script to run at app startup that initializes and runs the native plugin /// + /// /// /// Jackson Dunstan, 2017, http://JacksonDunstan.com /// + /// /// /// MIT /// - class BootScript : MonoBehaviour + public class BootScript : MonoBehaviour { - void Awake() + public int MemorySize = 1024 * 1024 * 16; + + // Reloading requires dynamic loading of the C++ plugin, which is only + // available in the editor +#if UNITY_EDITOR + public bool AutoReload; + + public float AutoReloadPollTime = 1.0f; + private float lastAutoReloadPollTime; + private Coroutine autoReloadCoroutine; + private Action onPlayModeStateChange; +#endif + + void Start() { +#if UNITY_EDITOR + lastAutoReloadPollTime = AutoReloadPollTime; +#endif DontDestroyOnLoad(gameObject); - Bindings.Open(); + Bindings.Open(MemorySize); +#if UNITY_EDITOR + onPlayModeStateChange = OnEditorStateChanged; + EditorApplication.playModeStateChanged += onPlayModeStateChange; +#endif } - void OnApplicationQuit() +#if UNITY_EDITOR + void Update() + { + Bindings.Update(); + + if (AutoReload) + { + if (AutoReloadPollTime > 0) + { + // Not started yet. Start. + if (autoReloadCoroutine == null) + { + lastAutoReloadPollTime = AutoReloadPollTime; + autoReloadCoroutine = StartCoroutine( + Bindings.AutoReload( + AutoReloadPollTime)); + } + // Poll time changed. Restart. + else if (AutoReloadPollTime != lastAutoReloadPollTime) + { + StopCoroutine(autoReloadCoroutine); + lastAutoReloadPollTime = AutoReloadPollTime; + autoReloadCoroutine = StartCoroutine( + Bindings.AutoReload( + AutoReloadPollTime)); + } + } + } + else + { + // Not stopped yet. Stop. + if (autoReloadCoroutine != null) + { + StopCoroutine(autoReloadCoroutine); + autoReloadCoroutine = null; + } + } + } + + private void OnEditorStateChanged(PlayModeStateChange state) { - Bindings.Close(); + if (state == PlayModeStateChange.EnteredEditMode) + { + EditorApplication.playModeStateChanged -= onPlayModeStateChange; + Bindings.Close(); + } } +#endif } } \ No newline at end of file diff --git a/Unity/Assets/NativeScript/Editor/EditorMenus.cs b/Unity/Assets/NativeScript/Editor/EditorMenus.cs new file mode 100644 index 0000000..a444732 --- /dev/null +++ b/Unity/Assets/NativeScript/Editor/EditorMenus.cs @@ -0,0 +1,30 @@ +using UnityEditor; + +namespace NativeScript.Editor +{ + /// + /// Menus for the Unity Editor + /// + /// + /// + /// Jackson Dunstan, 2018, http://JacksonDunstan.com + /// + /// + /// + /// MIT + /// + public static class EditorMenus + { + [MenuItem("NativeScript/Generate Bindings #%g")] + public static void Generate() + { + GenerateBindings.Generate(); + } + + [MenuItem("NativeScript/Reload Plugin #%r")] + public static void Reload() + { + Bindings.Reload(); + } + } +} diff --git a/Unity/Assets/NativeScript/Editor/EditorMenus.cs.meta b/Unity/Assets/NativeScript/Editor/EditorMenus.cs.meta new file mode 100644 index 0000000..ae3469a --- /dev/null +++ b/Unity/Assets/NativeScript/Editor/EditorMenus.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 5aad51de55c544325a293e98c996a550 +timeCreated: 1515806821 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/NativeScript/Editor/GenerateBindings.cs b/Unity/Assets/NativeScript/Editor/GenerateBindings.cs index 3e0c0f4..be815bc 100644 --- a/Unity/Assets/NativeScript/Editor/GenerateBindings.cs +++ b/Unity/Assets/NativeScript/Editor/GenerateBindings.cs @@ -1,4 +1,6 @@ -using System; +using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; @@ -6,29 +8,11 @@ using UnityEditor; using UnityEngine; -namespace NativeScript +namespace NativeScript.Editor { /// /// Code generator that reads a JSON file and outputs C# and C++ code - /// bindings so C++ can call managed functions. - /// - /// Supports: - /// * Constructors - /// * Properties (get and set) - /// * Fields - /// * Methods - /// * Class types (static and regular) - /// - /// Does Not Support: - /// * Arrays (single- or multi-dimensional) - /// * out or ref parameters - /// * Struct types - /// * Generic functions - /// * Generic types - /// * Delegates - /// - /// TODO: - /// * Prefix binding function names with namespaces + /// bindings so the languages can call each other. /// /// /// Jackson Dunstan, 2017, http://JacksonDunstan.com @@ -40,183 +24,282 @@ public static class GenerateBindings { // Disable unused field types. JsonUtility actually uses them, but it // does so with reflection. - #pragma warning disable CS0649 + #pragma warning disable 649 [Serializable] - private class JsonConstructor + class JsonConstructor + { + public string[] ParamTypes; + public string[] Exceptions; + } + + [Serializable] + class JsonGenericParams { public string[] Types; + public int MaxSimultaneous; } [Serializable] - private class JsonGenericType + class JsonMethod { public string Name; - public string Type; + public string[] ParamTypes; + public JsonGenericParams[] GenericParams; + public bool IsReadOnly; + public string[] Exceptions; } [Serializable] - private class JsonMethod + class JsonPropertyGet { - public string Name; - public string ReturnType; + public bool IsReadOnly = true; public string[] ParamTypes; - public JsonGenericType[] GenericTypes; + public string[] Exceptions; + } + + [Serializable] + class JsonPropertySet + { + public bool IsReadOnly; + public string[] ParamTypes; + public string[] Exceptions; + } + + [Serializable] + class JsonProperty + { + public string Name; + public JsonPropertyGet Get; + public JsonPropertySet Set; + } + + [Serializable] + class JsonEvent + { + public string Name; } [Serializable] - private class JsonType + class JsonType { public string Name; public JsonConstructor[] Constructors; public JsonMethod[] Methods; - public string[] Properties; + public JsonProperty[] Properties; public string[] Fields; + public JsonEvent[] Events; + public JsonGenericParams[] GenericParams; + public int MaxSimultaneous; + public JsonBaseType[] BaseTypes; } [Serializable] - private class JsonAssembly + class JsonBaseType { - public string Path; - public JsonType[] Types; + public string BaseName; + public string DerivedName; + public string[] GenericTypes; + public int MaxSimultaneous; + public JsonConstructor[] Constructors; + public JsonMethod[] OverrideMethods; + public JsonProperty[] OverrideProperties; + public JsonEvent[] OverrideEvents; } [Serializable] - private class JsonMonoBehaviour + class JsonArray { - public string Name; - public string Namespace; - public string[] Messages; + public string Type; + public int[] Ranks; + } + + [Serializable] + class JsonDelegate + { + public string Type; + public JsonGenericParams[] GenericParams; + public int MaxSimultaneous; } [Serializable] - private class JsonDocument + class JsonDocument { - public JsonAssembly[] Assemblies; - public JsonMonoBehaviour[] MonoBehaviours; + public int MaxSimultaneousObjects; + public int DefaultMaxSimultaneous; + public string[] Assemblies; + public JsonType[] Types; + public JsonArray[] Arrays; + public JsonDelegate[] Delegates; } - private class StringBuilders + const int InitialStringBuilderCapacity = 1024 * 100; + + class StringBuilders { - public StringBuilder CsharpInitParams = new StringBuilder(); - public StringBuilder CsharpDelegateTypes = new StringBuilder(); - public StringBuilder CsharpInitCall = new StringBuilder(); - public StringBuilder CsharpFunctions = new StringBuilder(); - public StringBuilder CsharpMonoBehaviours = new StringBuilder(); - public StringBuilder CsharpMonoBehaviourDelegates = new StringBuilder(); - public StringBuilder CsharpMonoBehaviourImports = new StringBuilder(); - public StringBuilder CsharpMonoBehaviourGetDelegateCalls = new StringBuilder(); - public StringBuilder CppFunctionPointers = new StringBuilder(); - public StringBuilder CppTypeDeclarations = new StringBuilder(); - public StringBuilder CppTypeDefinitions = new StringBuilder(); - public StringBuilder CppMethodDefinitions = new StringBuilder(); - public StringBuilder CppInitParams = new StringBuilder(); - public StringBuilder CppInitBody = new StringBuilder(); - public StringBuilder CppMonoBehaviourMessages = new StringBuilder(); - public StringBuilder TempStrBuilder = new StringBuilder(); + public readonly StringBuilder CsharpDelegateTypes = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpStoreInitCalls = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpInitCall = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpBaseTypes = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpFunctions = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpCppDelegates = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpCsharpDelegates = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpImports = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpGetDelegateCalls = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpDestroyFunctionEnumerators = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CsharpDestroyQueueCases = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppFunctionPointers = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppTypeDeclarations = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppTemplateDeclarations = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppTemplateSpecializationDeclarations = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppTypeDefinitions = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppMethodDefinitions = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppInitBodyParameterReads = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppInitBodyArrays = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppInitBodyFirstBoot = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppGlobalStateAndFunctions = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppUnboxingMethodDeclarations = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppStringDefaultParams = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder CppMacros = + new StringBuilder(InitialStringBuilderCapacity); + public readonly StringBuilder TempStrBuilder = + new StringBuilder(InitialStringBuilderCapacity); } - private class ParameterInfo + class ParameterInfo { public string Name; public Type ParameterType; + public Type DereferencedParameterType; + public bool IsOut; + public bool IsRef; + public TypeKind Kind; + public bool IsVirtual; + public bool HasDefault; + public object DefaultValue; + public bool IsVarArg; + } + + enum TypeKind + { + // No type (e.g. a global function) + None, + + // An instance of any class + Class, + + // A struct that must be managed. This includes types like + // RaycastHit which have class fields (Transform) and types with no + // C++ equivalent like decimal. + ManagedStruct, + + // A struct that can be copied between C#/C++. These are types like + // Vector3 with only non-class fields and a C++ equivalent can be + // generated. + FullStruct, + + // Any enum + Enum, + + // Any primitive (e.g. int) except pointers + Primitive, + + // A pointer to any type, either X*, IntPtr, or UIntPtr + Pointer } - private class MessageInfo + // Compares by field declaration order + // This uses MetadataToken, which isn't guaranteed to match field + // declaration order. It just happens to on Mono and .NET. + class FieldOrderComparer : IComparer + { + int IComparer.Compare(object x, object y) + { + FieldInfo xField = (FieldInfo)x; + FieldInfo yField = (FieldInfo)y; + return xField == null + ? yField == null + ? 0 + : -1 + : yField == null + ? 1 + : xField.MetadataToken < yField.MetadataToken + ? -1 + : xField.MetadataToken > yField.MetadataToken + ? 1 + : 0; + } + } + + struct TypeName { public string Name; - public Type[] ParameterTypes; - public bool Selected; - - public MessageInfo( - string name, - params Type[] parameterTypes) - { - Name = name; - ParameterTypes = parameterTypes; - } - } - - private static readonly MessageInfo[] messageInfos = new[] { - new MessageInfo("Awake"), - new MessageInfo("FixedUpdate"), - new MessageInfo("LateUpdate"), - new MessageInfo("OnAnimatorIK",typeof(int)), - new MessageInfo("OnAnimatorMove"), - new MessageInfo("OnApplicationFocus",typeof(bool)), - new MessageInfo("OnApplicationPause",typeof(bool)), - new MessageInfo("OnApplicationQuit"), - // TODO re-enable when arrays are supported - // new MessageInfo("OnAudioFilterRead", typeof(float[]), typeof(int)), - new MessageInfo("OnBecameInvisible"), - new MessageInfo("OnBecameVisible"), - new MessageInfo("OnCollisionEnter", typeof(Collision)), - new MessageInfo("OnCollisionEnter2D", typeof(Collision2D)), - new MessageInfo("OnCollisionExit", typeof(Collision)), - new MessageInfo("OnCollisionExit2D", typeof(Collision2D)), - new MessageInfo("OnCollisionStay", typeof(Collision)), - new MessageInfo("OnCollisionStay2D", typeof(Collision2D)), - new MessageInfo("OnConnectedToServer"), - new MessageInfo("OnControllerColliderHit", typeof(ControllerColliderHit)), - new MessageInfo("OnDestroy"), - new MessageInfo("OnDisable"), - new MessageInfo("OnDisconnectedFromServer", typeof(NetworkDisconnection)), - new MessageInfo("OnDrawGizmos"), - new MessageInfo("OnDrawGizmosSelected"), - new MessageInfo("OnEnable"), - new MessageInfo("OnFailedToConnect", typeof(NetworkConnectionError)), - new MessageInfo("OnFailedToConnectToMasterServer", typeof(NetworkConnectionError)), - new MessageInfo("OnGUI"), - new MessageInfo("OnJointBreak", typeof(float)), - new MessageInfo("OnJointBreak2D", typeof(Joint2D)), - new MessageInfo("OnMasterServerEvent", typeof(MasterServerEvent)), - new MessageInfo("OnMouseDown"), - new MessageInfo("OnMouseDrag"), - new MessageInfo("OnMouseEnter"), - new MessageInfo("OnMouseExit"), - new MessageInfo("OnMouseOver"), - new MessageInfo("OnMouseUp"), - new MessageInfo("OnMouseUpAsButton"), - new MessageInfo("OnNetworkInstantiate", typeof(NetworkMessageInfo)), - new MessageInfo("OnParticleCollision", typeof(GameObject)), - new MessageInfo("OnParticleTrigger"), - new MessageInfo("OnPlayerConnected", typeof(NetworkPlayer)), - new MessageInfo("OnPlayerDisconnected", typeof(NetworkPlayer)), - new MessageInfo("OnPostRender"), - new MessageInfo("OnPreCull"), - new MessageInfo("OnPreRender"), - new MessageInfo("OnRenderImage", typeof(RenderTexture), typeof(RenderTexture)), - new MessageInfo("OnRenderObject"), - new MessageInfo("OnSerializeNetworkView", typeof(BitStream), typeof(NetworkMessageInfo)), - new MessageInfo("OnServerInitialized"), - new MessageInfo("OnTransformChildrenChanged"), - new MessageInfo("OnTransformParentChanged"), - new MessageInfo("OnTriggerEnter", typeof(Collider)), - new MessageInfo("OnTriggerEnter2D", typeof(Collider2D)), - new MessageInfo("OnTriggerExit", typeof(Collider)), - new MessageInfo("OnTriggerExit2D", typeof(Collider2D)), - new MessageInfo("OnTriggerStay", typeof(Collider)), - new MessageInfo("OnTriggerStay2D", typeof(Collider2D)), - new MessageInfo("OnValidate"), - new MessageInfo("OnWillRenderObject"), - new MessageInfo("Reset"), - new MessageInfo("Start"), - new MessageInfo("Update"), + public string Namespace; + public int NumTypeParams; + } + + const int BaseMaxSimultaneous = 1000; + + static readonly Type[] PrimitiveTypes = { + typeof(bool), + typeof(sbyte), + typeof(byte), + typeof(short), + typeof(ushort), + typeof(int), + typeof(uint), + typeof(long), + typeof(ulong), + typeof(char), + typeof(float), + typeof(double) }; const string PostCompileWorkPref = "NativeScriptGenerateBindingsPostCompileWork"; - const string DryRunPref = "NativeScriptGenerateBindingsDryRun"; + static readonly string DotNetDllsDirPath = new FileInfo( + new Uri(typeof(string).Assembly.CodeBase).LocalPath + ).DirectoryName; + static readonly string UnityDllsDirPath = new FileInfo( + new Uri(typeof(GameObject).Assembly.CodeBase).LocalPath + ).DirectoryName; + static readonly string AssetsDirPath = Application.dataPath; + private static readonly DirectoryInfo ProjectDir = + new DirectoryInfo(AssetsDirPath).Parent; + static readonly string ProjectDirPath = ProjectDir.FullName; static readonly string CppDirPath = Path.Combine( Path.Combine( - new DirectoryInfo(Application.dataPath) - .Parent - .FullName, + Path.Combine( + ProjectDirPath, + "Assets"), "CppSource"), "NativeScript"); static readonly string CsharpPath = Path.Combine( - Application.dataPath, + AssetsDirPath, Path.Combine( "NativeScript", "Bindings.cs")); @@ -227,75 +310,180 @@ public MessageInfo( CppDirPath, "Bindings.cpp"); + static readonly FieldOrderComparer DefaultFieldOrderComparer + = new FieldOrderComparer(); + // Restore unused field types - #pragma warning restore CS0649 + #pragma warning restore 649 - [MenuItem("NativeScript/Generate Bindings #%g")] public static void Generate() - { - Generate(false); - } - - [MenuItem("NativeScript/Generate Bindings (dry run) #%&g")] - public static void GenerateDryRun() - { - Generate(true); - } - - static void Generate(bool dryRun) { EditorPrefs.DeleteKey(PostCompileWorkPref); - EditorPrefs.SetBool(DryRunPref, dryRun); - if (dryRun) + JsonDocument doc = LoadJson(); + Assembly[] assemblies = GetAssemblies(doc.Assemblies); + + // Determine whether we need to generate stubs + // We can skip this step if we've already generated all the + // required base types + bool needStubs = false; + if (doc.Types != null) { - DoPostCompileWork(); + foreach (JsonType jsonType in doc.Types) + { + if (jsonType.BaseTypes != null) + { + foreach (JsonBaseType jsonBaseType in jsonType.BaseTypes) + { + // Check if the type is already generated + Type type = TryGetType( + jsonBaseType.BaseName, + assemblies); + if (type == null) + { + needStubs = true; + goto determinedNeedStubs; + } + } + } + } } - else + determinedNeedStubs: + + if (needStubs) { - JsonDocument doc = LoadJson(); - - // Generate stub classes extending MonoBehaviour // We'll need to be able to get these via reflection later - StringBuilder output = new StringBuilder(1024*5); + StringBuilders builders = new StringBuilders(); string timestamp = DateTime.Now.ToLongTimeString(); - foreach (JsonMonoBehaviour monoBehaviour in doc.MonoBehaviours) - { - int csharpIndent = AppendNamespaceBeginning( - monoBehaviour.Namespace, - output); - AppendIndent(csharpIndent, output); - output.Append("public class "); - output.Append(monoBehaviour.Name); - output.Append(" : UnityEngine.MonoBehaviour\n"); - AppendIndent(csharpIndent, output); - output.Append("{\n"); - AppendIndent(csharpIndent + 1, output); - output.Append("// Stub version. GenerateBindings is still in progress. "); - output.Append(timestamp); - output.Append('\n'); - AppendIndent(csharpIndent, output); - output.Append("}\n"); - AppendNamespaceEnding(csharpIndent, output); - } - - // Inject - File.WriteAllText( - CsharpPath, - InjectIntoString( - File.ReadAllText(CsharpPath), - "/*BEGIN MONOBEHAVIOURS*/\n", - "\n/*END MONOBEHAVIOURS*/", - output.ToString())); + AppendStubs( + doc.Types, + assemblies, + timestamp, + builders); + InjectBuilders(builders); // Compile and continue after scripts are refreshed Debug.Log("Waiting for compile..."); - AssetDatabase.Refresh(); EditorPrefs.SetBool(PostCompileWorkPref, true); + AssetDatabase.Refresh(); + } + else + { + DoPostCompileWork(true); + } + } + + static void AppendStubs( + JsonType[] jsonTypes, + Assembly[] assemblies, + string timestamp, + StringBuilders builders) + { + // Base types + foreach (JsonType jsonType in jsonTypes) + { + if (jsonType.BaseTypes != null) + { + foreach (JsonBaseType jsonBaseType in jsonType.BaseTypes) + { + string typeFullName = jsonType.Name; + TypeName typeName = SplitJsonTypeName(typeFullName); + + string baseTypeFullName = jsonBaseType.BaseName; + TypeName baseTypeName = SplitJsonTypeName(baseTypeFullName); + + Type type = GetType(typeFullName, assemblies); + + Type[] typeParams = GetTypes( + jsonBaseType.GenericTypes, + assemblies); + + AppendStubBaseType( + typeName, + baseTypeName, + typeParams, + type, + timestamp, + builders.CsharpBaseTypes); + } + } + } + } + + static void AppendStubBaseType( + TypeName typeName, + TypeName baseTypeName, + Type[] typeParams, + Type type, + string timestamp, + StringBuilder output) + { + int indent = AppendNamespaceBeginning( + baseTypeName.Namespace, + output); + AppendIndent(indent, output); + if (type.IsClass) + { + output.Append("abstract public class "); + } + else + { + output.Append("public interface "); + } + output.Append(baseTypeName.Name); + output.Append(" : "); + AppendCsharpTypeFullName( + typeName, + output); + AppendCSharpTypeParameters( + typeParams, + output); + output.AppendLine(); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.Append("// Stub version. GenerateBindings is still in progress. "); + output.Append(timestamp); + output.AppendLine(); + if (type.IsClass) + { + output.AppendLine(); + ConstructorInfo[] constructors = type.GetConstructors(); + if (constructors.Length > 0) + { + foreach (ConstructorInfo ctor in constructors) + { + if (ctor.IsPublic + && ctor.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length == 0) + { + ParameterInfo[] ctorParams = ConvertParameters( + ctor.GetParameters()); + output.Append("\t\t"); + output.Append(baseTypeName.Name); + output.Append('('); + AppendCsharpParams( + ctorParams, + output); + output.AppendLine(")"); + output.Append("\t\t\t: base("); + AppendCsharpFunctionCallParameters( + ctorParams, + output); + output.AppendLine(")"); + output.AppendLine("\t\t{"); + output.AppendLine("\t\t}"); + output.AppendLine("\t\t"); + break; + } + } + } } + AppendIndent(indent, output); + output.AppendLine("}"); + AppendNamespaceEnding(indent, output); } [UnityEditor.Callbacks.DidReloadScripts] - private static void OnScriptsReloaded() + static void OnScriptsReloaded() { // Scripts get reloaded for many reasons, not just our work // Check if this reload is due to us refreshing the asset DB @@ -303,1466 +491,10802 @@ private static void OnScriptsReloaded() EditorPrefs.DeleteKey(PostCompileWorkPref); if (doWork) { - DoPostCompileWork(); + DoPostCompileWork(false); } } - static void DoPostCompileWork() + static void DoPostCompileWork(bool canRefreshAssetDb) { - bool dryRun = EditorPrefs.GetBool(DryRunPref); - EditorPrefs.DeleteKey(DryRunPref); + DateTime beforeTime = DateTime.Now; JsonDocument doc = LoadJson(); - - // Build binding strings + Assembly[] assemblies = GetAssemblies(doc.Assemblies); StringBuilders builders = new StringBuilders(); - StringBuilder csharpInitParams = builders.CsharpInitParams; - StringBuilder csharpDelegateTypes = builders.CsharpDelegateTypes; - StringBuilder csharpInitCall = builders.CsharpInitCall; - StringBuilder csharpFunctions = builders.CsharpFunctions; - StringBuilder csharpMonoBehaviours = builders.CsharpMonoBehaviours; - StringBuilder csharpMonoBehaviourDelegates = builders.CsharpMonoBehaviourDelegates; - StringBuilder csharpMonoBehaviourImports = builders.CsharpMonoBehaviourImports; - StringBuilder csharpMonoBehaviourGetDelegateCalls = builders.CsharpMonoBehaviourGetDelegateCalls; - StringBuilder cppFunctionPointers = builders.CppFunctionPointers; - StringBuilder cppTypeDeclarations = builders.CppTypeDeclarations; - StringBuilder cppTypeDefinitions = builders.CppTypeDefinitions; - StringBuilder cppMethodDefinitions = builders.CppMethodDefinitions; - StringBuilder cppInitParams = builders.CppInitParams; - StringBuilder cppInitBody = builders.CppInitBody; - StringBuilder cppMonoBehaviourMessages = builders.CppMonoBehaviourMessages; - StringBuilder tempStrBuilder = builders.TempStrBuilder; - foreach (JsonAssembly jsonAssembly in doc.Assemblies) - { - Assembly assembly = Assembly.LoadFrom(jsonAssembly.Path); - foreach (JsonType jsonType in jsonAssembly.Types) - { - Type type = assembly.GetType(jsonType.Name); - string typeNameLower = char.ToLower(type.Name[0]) - + type.Name.Substring(1); - bool isStatic = type.IsAbstract && type.IsSealed; - - // C++ type declaration - int indent = AppendCppTypeDeclaration( - type.Namespace, - type.Name, - isStatic, - cppTypeDeclarations); - - // C++ type definition (beginning) - AppendCppTypeDefinitionBegin( - type.Namespace, - type.Name, - type.BaseType.Namespace, - type.BaseType.Name, - isStatic, - indent, - cppTypeDefinitions); - - // C++ method definition - int cppMethodDefinitionsIndent = AppendCppMethodDefinitionBegin( - type.Namespace, - type.Name, - type.BaseType.Namespace, - type.BaseType.Name, - isStatic, - indent, - cppMethodDefinitions); - - // Constructors - foreach (JsonConstructor jsonCtor in jsonType.Constructors) - { - Type[] paramTypes = GetTypes(jsonCtor.Types, assembly); - ConstructorInfo ctor = type.GetConstructor(paramTypes); - ParameterInfo[] parameters = ConvertParameters( - ctor.GetParameters()); - - // Build uppercase function name - tempStrBuilder.Length = 0; - tempStrBuilder.Append(type.Name); - tempStrBuilder.Append("Constructor"); - AppendTypeNames(paramTypes, tempStrBuilder); - string funcName = tempStrBuilder.ToString(); - - // Build lowercase function name - tempStrBuilder.Length = 0; - tempStrBuilder.Append(typeNameLower); - tempStrBuilder.Append("Constructor"); - AppendTypeNames(paramTypes, tempStrBuilder); - string funcNameLower = tempStrBuilder.ToString(); - - // C# init param declaration - AppendCsharpInitParam(funcNameLower, csharpInitParams); - - // C# delegate type - AppendCsharpDelegateType( - funcName, - true, - typeof(int), - parameters, - csharpDelegateTypes); - - // C# init call param - AppendCsharpInitCallArg(funcName, csharpInitCall); - - // C# function - AppendCsharpFunctionBeginning( - type, - funcName, - true, - typeof(int), - null, - parameters, - csharpFunctions); - csharpFunctions.Append("ObjectStore.Store("); - csharpFunctions.Append("new "); - AppendCsharpTypeName( - type, - csharpFunctions); - AppendCsharpFunctionCallParameters( - true, - parameters, - csharpFunctions); - csharpFunctions.Append(");"); - AppendCsharpFunctionReturn( - typeof(int), - csharpFunctions); - - // C++ function pointer - AppendCppFunctionPointerDefinition( - funcName, - true, - parameters, - type, - cppFunctionPointers); - - // C++ type declaration - AppendIndent( - indent + 1, - cppTypeDefinitions); - AppendCppMethodDeclaration( - type.Name, - false, - null, - null, - parameters, - cppTypeDefinitions); - - // C++ method definition - AppendCppMethodDefinition( - type, - null, - type.Name, - null, - parameters, - indent, - cppMethodDefinitions); - AppendIndent(indent + 1, cppMethodDefinitions); - cppMethodDefinitions.Append(": "); - cppMethodDefinitions.Append(type.Name); - cppMethodDefinitions.Append('('); - cppMethodDefinitions.Append(type.Name); - cppMethodDefinitions.Append('('); - AppendCppPluginFunctionCall( - true, - type, - funcName, - parameters, - cppMethodDefinitions); - cppMethodDefinitions.Append(")\n"); - AppendIndent(indent, cppMethodDefinitions); - cppMethodDefinitions.Append("{\n"); - AppendIndent(indent, cppMethodDefinitions); - cppMethodDefinitions.Append("}\n"); - AppendIndent(indent, cppMethodDefinitions); - cppMethodDefinitions.Append("\n"); - - // C++ init params - AppendCppInitParam( - funcNameLower, - true, - parameters, - type, - cppInitParams); - - // C++ init body - AppendCppInitBody(funcName, funcNameLower, cppInitBody); - } + + // Get the default number of maximum simultaneous objects in case + // it's not specified for a specific type + int defaultMaxSimultaneous = doc.DefaultMaxSimultaneous != 0 + ? doc.DefaultMaxSimultaneous + : BaseMaxSimultaneous; + + // Init param for max managed Objects + builders.CsharpInitCall.Append("\t\t\tMarshal.WriteInt32(memory, curMemory, "); + builders.CsharpInitCall.Append(defaultMaxSimultaneous); + builders.CsharpInitCall.AppendLine("); // max managed objects"); + builders.CsharpInitCall.AppendLine("\t\t\tcurMemory += sizeof(int);"); + builders.CsharpInitCall.Append(' '); + + // C# ObjectStore Init call + builders.CsharpStoreInitCalls.Append( + "\t\t\tNativeScript.Bindings.ObjectStore.Init("); + builders.CsharpStoreInitCalls.Append(defaultMaxSimultaneous); + builders.CsharpStoreInitCalls.AppendLine(");"); + + // Generate types + if (doc.Types != null) + { + foreach (JsonType jsonType in doc.Types) + { + Type type = GetType(jsonType.Name, assemblies); + TypeKind typeKind = GetTypeKind(type); + AppendType( + jsonType, + type, + typeKind, + assemblies, + defaultMaxSimultaneous, + builders); - // Properties - foreach (string jsonPropertyName in jsonType.Properties) + if (jsonType.BaseTypes != null) { - PropertyInfo property = type.GetProperty( - jsonPropertyName); - MethodInfo getMethod = property.GetGetMethod(); - if (getMethod != null && getMethod.IsPublic) - { - AppendGetter( - property.Name, - typeNameLower, - "Property", - ConvertParameters(getMethod.GetParameters()), - getMethod.IsStatic, - type, - property.PropertyType, - indent, - builders); - } - MethodInfo setMethod = property.GetSetMethod(); - if (setMethod != null && setMethod.IsPublic) + Type[] genericArgTypes = type.GetGenericArguments(); + foreach (JsonBaseType jsonBaseType in jsonType.BaseTypes) { - AppendSetter( - property.Name, - "Property", - typeNameLower, - ConvertParameters(setMethod.GetParameters()), - setMethod.IsStatic, + TypeName baseTypeTypeName = GetBaseTypeBaseNameAndNamespace( + jsonBaseType, type, - property.PropertyType, - indent, - builders); - } - } - - // Fields - foreach (string jsonFieldName in jsonType.Fields) - { - FieldInfo field = type.GetField(jsonFieldName); - AppendGetter( - field.Name, - typeNameLower, - "Field", - new ParameterInfo[0], - field.IsStatic, - type, - field.FieldType, - indent, - builders); - ParameterInfo setParam = new ParameterInfo(); - setParam.Name = "value"; - setParam.ParameterType = field.FieldType; - ParameterInfo[] parameters = new []{ setParam }; - AppendSetter( - field.Name, - "Field", - typeNameLower, - parameters, - field.IsStatic, - type, - field.FieldType, - indent, - builders); - } - - // Methods - foreach (JsonMethod jsonMethod in jsonType.Methods) - { - MethodInfo method = GetMethod( - type, - jsonMethod.Name, - jsonMethod.ReturnType, - jsonMethod.ParamTypes); - ParameterInfo[] parameters = ConvertParameters( - method.GetParameters()); - Type[] paramTypes = GetTypes( - jsonMethod.ParamTypes, - assembly); - - if (jsonMethod.GenericTypes != null) - { - foreach (JsonGenericType genericType in jsonMethod.GenericTypes) - { - Type returnType; - if (genericType.Name == method.ReturnType.Name) - { - returnType = GetType(genericType.Type, assembly); - } - else - { - returnType = method.ReturnType; - } - Type[] typeParams = new[] { returnType }; - - AppendMethod( - type, - typeNameLower, - method.Name, - method.IsStatic, - returnType, - typeParams, - parameters, - paramTypes, - indent, - builders); - } - } - else - { - AppendMethod( + genericArgTypes, + builders.TempStrBuilder); + AppendBaseType( type, - typeNameLower, - method.Name, - method.IsStatic, - method.ReturnType, - null, - parameters, - paramTypes, - indent, + baseTypeTypeName, + jsonBaseType, + assemblies, + defaultMaxSimultaneous, builders); } } - - // C++ type definition (ending) - AppendCppTypeDefinitionEnd( - isStatic, - indent, - cppTypeDefinitions); - - // C++ method definition (ending) - AppendCppMethodDefinitionEnd( - cppMethodDefinitionsIndent, - cppMethodDefinitions); } } - foreach (JsonMonoBehaviour monoBehaviour in doc.MonoBehaviours) + + // Generate boxing and unboxing for primitive types + foreach (Type type in PrimitiveTypes) + { + string dummyString; + ParameterInfo[] dummyParams; + AppendBoxingBindings( + type, + TypeKind.Primitive, + null, + builders, + out dummyString, + out dummyParams); + AppendUnboxing( + type, + TypeKind.Primitive, + null, + builders); + } + + // Generate arrays + if (doc.Arrays != null) { - // C++ Type Declaration - int cppIndent = AppendCppTypeDeclaration( - monoBehaviour.Namespace, - monoBehaviour.Name, - false, - cppTypeDeclarations); - - // C++ Type Definition (begin) - AppendCppTypeDefinitionBegin( - monoBehaviour.Namespace, - monoBehaviour.Name, - "UnityEngine", - "MonoBehaviour", - false, - cppIndent, - cppTypeDefinitions - ); + foreach (JsonArray array in doc.Arrays) + { + AppendArray( + array, + assemblies, + builders); + } + } + + // Generate delegates + if (doc.Delegates != null) + { + foreach (JsonDelegate del in doc.Delegates) + { + AppendDelegate( + del, + assemblies, + defaultMaxSimultaneous, + builders); + } + } + + // Generate exception setters + AppendExceptions( + doc, + assemblies, + builders); + + // Output source files + RemoveTrailingChars(builders); + InjectBuilders(builders); + + // Inform the user of the result + if (canRefreshAssetDb) + { + AssetDatabase.Refresh(); + DateTime afterTime = DateTime.Now; + TimeSpan duration = afterTime - beforeTime; + Debug.LogFormat( + "Done generating bindings in {0} seconds.", + duration.TotalSeconds); + } + else + { + Debug.LogWarning( + "Can't auto-refresh due to a bug in Unity. " + + "Please manually refresh assets with " + + "Assets -> Refresh to finish generating bindings"); + } + } + + static JsonDocument LoadJson() + { + string jsonPath = Path.Combine( + Application.dataPath, + NativeScriptConstants.JSON_CONFIG_PATH); + string json = File.ReadAllText(jsonPath); + return JsonUtility.FromJson(json); + } + + static Assembly[] GetAssemblies(string[] assemblyNames) + { + const int numDefaultAssemblies = +#if UNITY_2017_2_OR_NEWER + 43; +#else + 7; +#endif + + int numAssemblies; + Assembly[] assemblies; + if (assemblyNames == null) + { + numAssemblies = numDefaultAssemblies; + assemblies = new Assembly[numAssemblies]; + } + else + { + numAssemblies = numDefaultAssemblies + assemblyNames.Length; + assemblies = new Assembly[numAssemblies]; - // C++ method definition - int cppMethodDefinitionsIndent = AppendCppMethodDefinitionBegin( - monoBehaviour.Namespace, - monoBehaviour.Name, - "UnityEngine", - "MonoBehaviour", - false, - cppIndent, - cppMethodDefinitions); - AppendCppMethodDefinitionEnd( - cppMethodDefinitionsIndent, - cppMethodDefinitions); - - // C# Class extending MonoBehaviour - int csharpIndent = AppendNamespaceBeginning( - monoBehaviour.Namespace, - csharpMonoBehaviours); - AppendIndent(csharpIndent, csharpMonoBehaviours); - csharpMonoBehaviours.Append("public class "); - csharpMonoBehaviours.Append(monoBehaviour.Name); - csharpMonoBehaviours.Append(" : UnityEngine.MonoBehaviour\n"); - AppendIndent(csharpIndent, csharpMonoBehaviours); - csharpMonoBehaviours.Append("{\n"); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("private int thisHandle;\n"); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append('\n'); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("public "); - csharpMonoBehaviours.Append(monoBehaviour.Name); - csharpMonoBehaviours.Append("()\n"); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("{\n"); - AppendIndent(csharpIndent + 2, csharpMonoBehaviours); - csharpMonoBehaviours.Append("thisHandle = NativeScript.ObjectStore.Store(this);\n"); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("}\n"); - if (monoBehaviour.Messages.Length > 0) - { - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append('\n'); - } - for (int messageIndex = 0; messageIndex < monoBehaviour.Messages.Length; ++messageIndex) - { - string message = monoBehaviour.Messages[messageIndex]; - MessageInfo messageInfo = null; - foreach (MessageInfo mi in messageInfos) - { - if (mi.Name == message) - { - messageInfo = mi; - break; - } - } - Type[] paramTypes = messageInfo.ParameterTypes; - int numParams = paramTypes.Length; - ParameterInfo[] parameters = ConvertParameters( - paramTypes); - - // C++ Method Declaration - AppendIndent( - cppIndent + 1, - cppTypeDefinitions); - AppendCppMethodDeclaration( - messageInfo.Name, - false, - typeof(void), - null, - parameters, - cppTypeDefinitions); - - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("public "); - AppendCsharpTypeName( - typeof(void), - csharpMonoBehaviours); - csharpMonoBehaviours.Append(' '); - csharpMonoBehaviours.Append(messageInfo.Name); - csharpMonoBehaviours.Append('('); - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - AppendCsharpTypeName( - paramType, - csharpMonoBehaviours); - csharpMonoBehaviours.Append(' '); - csharpMonoBehaviours.Append("param"); - csharpMonoBehaviours.Append(i); - if (i != numParams - 1) - { - csharpMonoBehaviours.Append(", "); - } - } - csharpMonoBehaviours.Append(")\n"); - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("{\n"); - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (!paramType.IsValueType) - { - AppendIndent(csharpIndent + 2, csharpMonoBehaviours); - csharpMonoBehaviours.Append("int param"); - csharpMonoBehaviours.Append(i); - csharpMonoBehaviours.Append("Handle = NativeScript.ObjectStore.Store("); - csharpMonoBehaviours.Append("param"); - csharpMonoBehaviours.Append(i); - csharpMonoBehaviours.Append(");\n"); - } - } - AppendIndent(csharpIndent + 2, csharpMonoBehaviours); - csharpMonoBehaviours.Append("NativeScript.Bindings."); - csharpMonoBehaviours.Append(monoBehaviour.Name); - csharpMonoBehaviours.Append(messageInfo.Name); - csharpMonoBehaviours.Append("(thisHandle"); - if (numParams > 0) - { - csharpMonoBehaviours.Append(", "); - } - for (int i = 0; i < numParams; ++i) - { - csharpMonoBehaviours.Append("param"); - csharpMonoBehaviours.Append(i); - Type paramType = paramTypes[i]; - if (!paramType.IsValueType) - { - csharpMonoBehaviours.Append("Handle"); - } - if (i != numParams - 1) - { - csharpMonoBehaviours.Append(", "); - } - } - csharpMonoBehaviours.Append(");\n"); - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (!paramType.IsValueType) - { - AppendIndent(csharpIndent + 2, csharpMonoBehaviours); - csharpMonoBehaviours.Append("NativeScript.ObjectStore.Remove(param"); - csharpMonoBehaviours.Append(i); - if (!paramType.IsValueType) - { - csharpMonoBehaviours.Append("Handle"); - } - csharpMonoBehaviours.Append(");\n"); - } - } - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append("}\n"); - if (messageIndex != monoBehaviour.Messages.Length - 1) - { - AppendIndent(csharpIndent + 1, csharpMonoBehaviours); - csharpMonoBehaviours.Append('\n'); - } - - // C# Delegate - csharpMonoBehaviourDelegates.Append("\t\tpublic delegate void "); - csharpMonoBehaviourDelegates.Append(monoBehaviour.Name); - csharpMonoBehaviourDelegates.Append(messageInfo.Name); - csharpMonoBehaviourDelegates.Append("Delegate(int thisHandle"); - if (numParams > 0) - { - csharpMonoBehaviourDelegates.Append(", "); - } - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (paramType.IsValueType) - { - AppendCsharpTypeName( - paramType, - csharpMonoBehaviourDelegates); - csharpMonoBehaviourDelegates.Append(" param"); - csharpMonoBehaviourDelegates.Append(i); - } - else - { - csharpMonoBehaviourDelegates.Append("int param"); - csharpMonoBehaviourDelegates.Append(i); - } - if (i != numParams-1) - { - csharpMonoBehaviourDelegates.Append(", "); - } - } - csharpMonoBehaviourDelegates.Append(");\n"); - csharpMonoBehaviourDelegates.Append("\t\tpublic static "); - csharpMonoBehaviourDelegates.Append(monoBehaviour.Name); - csharpMonoBehaviourDelegates.Append(messageInfo.Name); - csharpMonoBehaviourDelegates.Append("Delegate "); - csharpMonoBehaviourDelegates.Append(monoBehaviour.Name); - csharpMonoBehaviourDelegates.Append(messageInfo.Name); - csharpMonoBehaviourDelegates.Append(";\n\t\t\n"); - - // C# Import - csharpMonoBehaviourImports.Append("\t\t[DllImport(Constants.PluginName)]\n"); - csharpMonoBehaviourImports.Append("\t\tpublic static extern void "); - csharpMonoBehaviourImports.Append(monoBehaviour.Name); - csharpMonoBehaviourImports.Append(messageInfo.Name); - csharpMonoBehaviourImports.Append("(int thisHandle"); - if (numParams > 0) - { - csharpMonoBehaviourImports.Append(", "); - } - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (paramType.IsValueType) - { - AppendCsharpTypeName( - paramType, - csharpMonoBehaviourImports); - csharpMonoBehaviourImports.Append(" param"); - csharpMonoBehaviourImports.Append(i); - } - else - { - csharpMonoBehaviourImports.Append("int param"); - csharpMonoBehaviourImports.Append(i); - } - if (i != numParams-1) - { - csharpMonoBehaviourImports.Append(", "); - } - } - csharpMonoBehaviourImports.Append(");\n\t\t\n"); - - // C# GetDelegate Call - csharpMonoBehaviourGetDelegateCalls.Append("\t\t\t"); - csharpMonoBehaviourGetDelegateCalls.Append(monoBehaviour.Name); - csharpMonoBehaviourGetDelegateCalls.Append(messageInfo.Name); - csharpMonoBehaviourGetDelegateCalls.Append(" = GetDelegate<"); - csharpMonoBehaviourGetDelegateCalls.Append(monoBehaviour.Name); - csharpMonoBehaviourGetDelegateCalls.Append(messageInfo.Name); - csharpMonoBehaviourGetDelegateCalls.Append("Delegate>(libraryHandle, \""); - csharpMonoBehaviourGetDelegateCalls.Append(monoBehaviour.Name); - csharpMonoBehaviourGetDelegateCalls.Append(messageInfo.Name); - csharpMonoBehaviourGetDelegateCalls.Append("\");\n"); - - // C++ Message - cppMonoBehaviourMessages.Append("DLLEXPORT void "); - cppMonoBehaviourMessages.Append(monoBehaviour.Name); - cppMonoBehaviourMessages.Append(messageInfo.Name); - cppMonoBehaviourMessages.Append("(int32_t thisHandle"); - if (numParams > 0) - { - cppMonoBehaviourMessages.Append(", "); - } - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (paramType.IsValueType) - { - AppendCppTypeName( - paramType, - cppMonoBehaviourMessages); - cppMonoBehaviourMessages.Append(" param"); - cppMonoBehaviourMessages.Append(i); - } - else - { - cppMonoBehaviourMessages.Append("int32_t param"); - cppMonoBehaviourMessages.Append(i); - cppMonoBehaviourMessages.Append("Handle"); - } - if (i != numParams-1) - { - cppMonoBehaviourMessages.Append(", "); - } - } - cppMonoBehaviourMessages.Append(")\n{\n\t"); - AppendCppTypeName( - monoBehaviour.Namespace, - monoBehaviour.Name, - cppMonoBehaviourMessages); - cppMonoBehaviourMessages.Append(" thiz(thisHandle);\n"); - for (int i = 0; i < numParams; ++i) - { - Type paramType = paramTypes[i]; - if (!paramType.IsValueType) - { - cppMonoBehaviourMessages.Append('\t'); - AppendCppTypeName( - paramType, - cppMonoBehaviourMessages); - cppMonoBehaviourMessages.Append(" param"); - cppMonoBehaviourMessages.Append(i); - cppMonoBehaviourMessages.Append("(param"); - cppMonoBehaviourMessages.Append(i); - cppMonoBehaviourMessages.Append("Handle);\n"); - } - } - cppMonoBehaviourMessages.Append("\tthiz."); - cppMonoBehaviourMessages.Append(messageInfo.Name); - cppMonoBehaviourMessages.Append("("); - for (int i = 0; i < numParams; ++i) - { - cppMonoBehaviourMessages.Append("param"); - cppMonoBehaviourMessages.Append(i); - if (i != numParams-1) - { - cppMonoBehaviourMessages.Append(", "); - } - } - cppMonoBehaviourMessages.Append(");\n}\n\n"); + for (int i = 0; i < assemblyNames.Length; ++i) + { + string path = assemblyNames[i] + .Replace("UNITY_PROJECT", ProjectDirPath) + .Replace("UNITY_ASSETS", AssetsDirPath) + .Replace("DOTNET_DLLS", DotNetDllsDirPath) + .Replace("UNITY_DLLS", UnityDllsDirPath); + Assembly assembly = Assembly.LoadFrom(path); + assemblies[numDefaultAssemblies + i] = assembly; } - - // C# Class extending MonoBehaviour (end) - AppendIndent(csharpIndent, csharpMonoBehaviours); - csharpMonoBehaviours.Append("}\n"); - AppendNamespaceEnding(csharpIndent, csharpMonoBehaviours); - - // C++ Type Definition (end) - AppendCppTypeDefinitionEnd( - false, - cppIndent, - cppTypeDefinitions); - } - - // Remove trailing chars (e.g. commas) for last elements - RemoveTrailingChars(csharpInitParams); - RemoveTrailingChars(csharpDelegateTypes); - RemoveTrailingChars(csharpInitCall); - RemoveTrailingChars(csharpFunctions); - RemoveTrailingChars(csharpMonoBehaviours); - RemoveTrailingChars(csharpMonoBehaviourDelegates); - RemoveTrailingChars(csharpMonoBehaviourImports); - RemoveTrailingChars(csharpMonoBehaviourGetDelegateCalls); - RemoveTrailingChars(cppFunctionPointers); - RemoveTrailingChars(cppTypeDeclarations); - RemoveTrailingChars(cppMethodDefinitions); - RemoveTrailingChars(cppTypeDefinitions); - RemoveTrailingChars(cppInitParams); - RemoveTrailingChars(cppInitBody); - RemoveTrailingChars(cppMonoBehaviourMessages); - - if (dryRun) - { - LogStringBuilder("C# init params", csharpInitParams); - LogStringBuilder("C# delegates", csharpDelegateTypes); - LogStringBuilder("C# init call", csharpInitCall); - LogStringBuilder("C# functions", csharpFunctions); - LogStringBuilder("C# MonoBehaviours", csharpMonoBehaviours); - LogStringBuilder("C# MonoBehaviour Delegates", csharpMonoBehaviourDelegates); - LogStringBuilder("C# MonoBehaviour Imports", csharpMonoBehaviourImports); - LogStringBuilder("C# MonoBehaviour GetDelegate Calls", csharpMonoBehaviourGetDelegateCalls); - LogStringBuilder("C++ function pointers", cppFunctionPointers); - LogStringBuilder("C++ type declarations", cppTypeDeclarations); - LogStringBuilder("C++ type definitions", cppTypeDefinitions); - LogStringBuilder("C++ method definitions", cppMethodDefinitions); - LogStringBuilder("C++ init params", cppInitParams); - LogStringBuilder("C++ init body", cppInitBody); - LogStringBuilder("C++ MonoBehaviour messages", cppMonoBehaviourMessages); - } - else - { - // Inject into source files - string csharpContents = File.ReadAllText(CsharpPath); - string cppHeaderContents = File.ReadAllText(CppHeaderPath); - string cppSourceContents = File.ReadAllText(CppSourcePath); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN INIT PARAMS*/\n", - "\n\t\t\t/*END INIT PARAMS*/", - csharpInitParams.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN DELEGATE TYPES*/\n", - "\n\t\t/*END DELEGATE TYPES*/", - csharpDelegateTypes.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN INIT CALL*/\n", - "\n\t\t\t\t/*END INIT CALL*/", - csharpInitCall.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN FUNCTIONS*/\n", - "\n\t\t/*END FUNCTIONS*/", - csharpFunctions.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN MONOBEHAVIOURS*/\n", - "\n/*END MONOBEHAVIOURS*/", - csharpMonoBehaviours.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN MONOBEHAVIOUR DELEGATES*/\n", - "\n\t\t/*END MONOBEHAVIOUR DELEGATES*/", - csharpMonoBehaviourDelegates.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN MONOBEHAVIOUR IMPORTS*/\n", - "\n\t\t/*END MONOBEHAVIOUR IMPORTS*/", - csharpMonoBehaviourImports.ToString()); - csharpContents = InjectIntoString( - csharpContents, - "/*BEGIN MONOBEHAVIOUR GETDELEGATE CALLS*/\n", - "\n\t\t\t/*END MONOBEHAVIOUR GETDELEGATE CALLS*/", - csharpMonoBehaviourGetDelegateCalls.ToString()); - cppSourceContents = InjectIntoString( - cppSourceContents, - "/*BEGIN FUNCTION POINTERS*/\n", - "\n\t/*END FUNCTION POINTERS*/", - cppFunctionPointers.ToString()); - cppHeaderContents = InjectIntoString( - cppHeaderContents, - "/*BEGIN TYPE DECLARATIONS*/\n", - "\n/*END TYPE DECLARATIONS*/", - cppTypeDeclarations.ToString()); - cppHeaderContents = InjectIntoString( - cppHeaderContents, - "/*BEGIN TYPE DEFINITIONS*/\n", - "\n/*END TYPE DEFINITIONS*/", - cppTypeDefinitions.ToString()); - cppSourceContents = InjectIntoString( - cppSourceContents, - "/*BEGIN METHOD DEFINITIONS*/\n", - "\n/*END METHOD DEFINITIONS*/", - cppMethodDefinitions.ToString()); - cppSourceContents = InjectIntoString( - cppSourceContents, - "/*BEGIN INIT PARAMS*/\n", - "\n\t/*END INIT PARAMS*/", - cppInitParams.ToString()); - cppSourceContents = InjectIntoString( - cppSourceContents, - "/*BEGIN INIT BODY*/\n", - "\n\t/*END INIT BODY*/", - cppInitBody.ToString()); - cppSourceContents = InjectIntoString( - cppSourceContents, - "/*BEGIN MONOBEHAVIOUR MESSAGES*/\n", - "\n/*END MONOBEHAVIOUR MESSAGES*/", - cppMonoBehaviourMessages.ToString()); - - File.WriteAllText(CsharpPath, csharpContents); - File.WriteAllText(CppHeaderPath, cppHeaderContents); - File.WriteAllText(CppSourcePath, cppSourceContents); - Debug.Log( - "Can't auto-refresh due to a bug in Unity. " + - "Please manually refresh assets with Assets -> Refresh."); } - } - - static JsonDocument LoadJson() - { - string jsonPath = Path.Combine( - Application.dataPath, - NativeScriptConstants.ExposedTypesJsonPath); - string json = File.ReadAllText(jsonPath); - return JsonUtility.FromJson(json); + assemblies[0] = typeof(string).Assembly; // .NET: mscorlib + assemblies[1] = typeof(Uri).Assembly; // .NET: System + assemblies[2] = typeof(Action).Assembly; // .NET: System.Core + assemblies[3] = typeof(Vector3).Assembly; // UnityEngine (core module for 2017.2+) + assemblies[4] = typeof(Bindings).Assembly; // Runtime scripts + assemblies[5] = typeof(GenerateBindings).Assembly; // Editor scripts + assemblies[6] = typeof(EditorPrefs).Assembly; // UnityEditor +#if UNITY_2017_2_OR_NEWER + assemblies[7] = typeof(UnityEngine.Accessibility.VisionUtility).Assembly; // Unity accessibility module + assemblies[8] = typeof(UnityEngine.AI.NavMesh).Assembly; // Unity AI module + assemblies[9] = typeof(UnityEngine.Animations.AnimationClipPlayable).Assembly; // Unity animation module +#if !UNITY_2020_1_OR_NEWER //This class migrate to package + assemblies[10] = typeof(UnityEngine.XR.ARRenderMode).Assembly; // Unity AR module +#else + assemblies[10] = typeof(UnityEngine.XR.InputDevices).Assembly; // Unity AR module without package +#endif + + assemblies[11] = typeof(AudioSettings).Assembly; // Unity audio module + assemblies[12] = typeof(Cloth).Assembly; // Unity cloth module + assemblies[13] = typeof(ClusterInput).Assembly; // Unity cluster input module + assemblies[14] = typeof(ClusterNetwork).Assembly; // Unity custer renderer module + assemblies[15] = typeof(UnityEngine.CrashReportHandler.CrashReportHandler).Assembly; // Unity crash reporting module + assemblies[16] = typeof(UnityEngine.Playables.PlayableDirector).Assembly; // Unity director module + assemblies[17] = typeof(UnityEngine.SocialPlatforms.IAchievement).Assembly; // Unity game center module + assemblies[18] = typeof(ImageConversion).Assembly; // Unity image conversion module + assemblies[19] = typeof(GUI).Assembly; // Unity IMGUI module + assemblies[20] = typeof(JsonUtility).Assembly; // Unity JSON serialize module + assemblies[21] = typeof(ParticleSystem).Assembly; // Unity particle system module + assemblies[22] = typeof(UnityEngine.Analytics.PerformanceReporting).Assembly; // Unity performance reporting module + assemblies[23] = typeof(Physics2D).Assembly; // Unity physics 2D module + assemblies[24] = typeof(Physics).Assembly; // Unity physics module + assemblies[25] = typeof(ScreenCapture).Assembly; // Unity screen capture module + assemblies[26] = typeof(Terrain).Assembly; // Unity terrain module + assemblies[27] = typeof(TerrainCollider).Assembly; // Unity terrain physics module + assemblies[28] = typeof(Font).Assembly; // Unity text rendering module + assemblies[29] = typeof(UnityEngine.Tilemaps.Tile).Assembly; // Unity tilemap module +#if UNITY_2019_1_OR_NEWER + assemblies[30] = typeof(UnityEngine.UIElements.Button).Assembly; // Unity UI elements module +#else + assemblies[30] = typeof(UnityEngine.Experimental.UIElements.Button).Assembly; // Unity UI elements module +#endif + assemblies[31] = typeof(Canvas).Assembly; // Unity UI module +#if UNITY_2020_1_OR_NEWER + assemblies[32] = typeof(UnityEngine.Networking.Utility).Assembly; // Unity network module +#else + assemblies[32] = typeof(UnityEngine.Networking.NetworkTransport).Assembly; // Unity network module +#endif + assemblies[33] = typeof(UnityEngine.Analytics.Analytics).Assembly; // Unity analytics module + assemblies[34] = typeof(RemoteSettings).Assembly; // Unity Unity connect module + assemblies[35] = typeof(UnityEngine.Networking.DownloadHandlerAudioClip).Assembly; // Unity web request audio module + assemblies[36] = typeof(WWWForm).Assembly; // Unity web request module + assemblies[37] = typeof(UnityEngine.Networking.DownloadHandlerTexture).Assembly; // Unity web request texture module +#if !UNITY_2020_1_OR_NEWER + assemblies[38] = typeof(WWW).Assembly; // Unity web request WWW module +#else + assemblies[38] = typeof(UnityEngine.Networking.UnityWebRequest).Assembly; +#endif + assemblies[39] = typeof(WheelCollider).Assembly; // Unity vehicles module + assemblies[40] = typeof(UnityEngine.Video.VideoClip).Assembly; // Unity video module + assemblies[41] = typeof(UnityEngine.XR.InputTracking).Assembly; // Unity VR module + assemblies[42] = typeof(WindZone).Assembly; // Unity wind module +#endif + return assemblies; } static Type[] GetTypes( string[] typeNames, - Assembly assembly) + Assembly[] assemblies) { - Assembly systemAssembly = typeof(string).Assembly; + if (typeNames == null) + { + return new Type[0]; + } Type[] types = new Type[typeNames.Length]; for (int i = 0; i < typeNames.Length; ++i) { - types[i] = GetType(typeNames[i], assembly); + types[i] = GetType(typeNames[i], assemblies); } return types; } static Type GetType( string typeName, - Assembly assembly) + Assembly[] assemblies) + { + Type type = TryGetType( + typeName, + assemblies); + if (type != null) + { + return type; + } + + // Not finding a type is a fatal error + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Couldn't find type \""); + errorBuilder.Append(typeName); + errorBuilder.Append('"'); + throw new Exception(errorBuilder.ToString()); + } + + static Type TryGetType( + string typeName, + Assembly[] assemblies) { - return assembly.GetType(typeName) - ?? typeof(string).Assembly.GetType(typeName) - ?? typeof(Bindings).Assembly.GetType(typeName); + // Search all assemblies for the type + foreach (Assembly assembly in assemblies) + { + Type type = assembly.GetType(typeName); + if (type != null) + { + return type; + } + } + return null; + } + + static TypeKind GetTypeKind(Type type) + { + if (type == typeof(void)) + { + return TypeKind.None; + } + + if (type.IsPointer) + { + return TypeKind.Pointer; + } + + if (type.IsEnum) + { + return TypeKind.Enum; + } + + if (type.IsPrimitive) + { + return TypeKind.Primitive; + } + + if (!type.IsValueType) + { + return TypeKind.Class; + } + + // Decimal (currently) can't be represented on the C++ side, so + // don't count it as a full struct + if (type != typeof(decimal) && IsFullValueType(type)) + { + return TypeKind.FullStruct; + } + + return TypeKind.ManagedStruct; + } + + static ParameterInfo[] GetConstructorParameters( + Type type, + bool allowDefault, + string[] paramTypeNames) + { + foreach (ConstructorInfo ctor in type.GetConstructors()) + { + System.Reflection.ParameterInfo[] reflectionParams + = ctor.GetParameters(); + if (CheckParametersMatch( + paramTypeNames, + reflectionParams)) + { + return ConvertParameters(reflectionParams); + } + } + + if (allowDefault) + { + return new ParameterInfo[0]; + } + + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Constructor \""); + AppendCsharpTypeFullName(type, errorBuilder); + errorBuilder.Append('('); + for (int i = 0; i < paramTypeNames.Length; ++i) + { + errorBuilder.Append(paramTypeNames[i]); + if (i != paramTypeNames.Length - 1) + { + errorBuilder.Append(", "); + } + } + errorBuilder.Append(")\" not found"); + throw new Exception(errorBuilder.ToString()); } static MethodInfo GetMethod( Type type, + MethodInfo[] methods, string methodName, - string returnTypeName, - string[] paramTypeNames) + string[] paramTypeNames, + string[] genericTypeNames) + { + foreach (MethodInfo method in methods) + { + // Name must match + if (method.Name != methodName) + { + continue; + } + + // All parameters must match + if (!CheckParametersMatch( + paramTypeNames, + method.GetParameters())) + { + continue; + } + + // Generic arg count must match + Type[] methodGenericArgs = method.GetGenericArguments(); + int numGenericTypeNames = genericTypeNames == null ? 0 : genericTypeNames.Length; + if (methodGenericArgs.Length == numGenericTypeNames) + { + return method; + } + } + + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Method \""); + AppendCsharpTypeFullName(type, errorBuilder); + errorBuilder.Append('.'); + errorBuilder.Append(methodName); + errorBuilder.Append('('); + for (int i = 0; i < paramTypeNames.Length; ++i) + { + errorBuilder.Append(paramTypeNames[i]); + if (i != paramTypeNames.Length - 1) + { + errorBuilder.Append(", "); + } + } + errorBuilder.Append(")\" not found"); + throw new Exception(errorBuilder.ToString()); + } + + static Type[] GetDirectInterfaces(Type type) { - foreach (MethodInfo method in type.GetMethods()) + Type[] allInterfaces = type.GetInterfaces(); + List minimalInterfaces = new List(); + foreach(Type iType in allInterfaces) { - if (method.Name == methodName) + bool contains = false; + foreach (Type t in allInterfaces) { - if (returnTypeName != null) + if (Array.IndexOf(t.GetInterfaces(), iType) >= 0) { - if (string.IsNullOrEmpty(method.ReturnType.Namespace)) - { - if (method.ReturnType.Name != returnTypeName) - { - continue; - } - } - else + contains = true; + break; + } + } + if (!contains) + { + minimalInterfaces.Add(iType); + } + } + minimalInterfaces.Sort( + (x, y) => string.Compare( + x.Name, + y.Name, + StringComparison.InvariantCulture)); + return minimalInterfaces.ToArray(); + } + + static void AddCppCtorInitType(Type type, List types) + { + if (type.BaseType != null + && type.BaseType != typeof(object) + && type.BaseType != typeof(ValueType)) + { + AddCppCtorInitType(type.BaseType, types); + } + foreach (Type interfaceType in GetDirectInterfaces(type)) + { + AddCppCtorInitType(interfaceType, types); + } + if (!types.Contains(type)) + { + types.Add(type); + } + } + + static Type[] GetCppCtorInitTypes(Type type, bool includeSelf) + { + List types = new List(); + AddCppCtorInitType(type, types); + if (!includeSelf) + { + types.RemoveAll(t => t == type); + } + return types.ToArray(); + } + + static void AppendCppConstructorInitializerList( + Type[] interfaceTypes, + int indent, + StringBuilder output, + string newline = null) + { + if (string.IsNullOrWhiteSpace(newline)) + { + newline = Environment.NewLine; + } + + string separator = ": "; + foreach (Type interfaceType in interfaceTypes) + { + AppendIndent(indent, output); + output.Append(separator); + AppendCppTypeFullName( interfaceType, output); + output.Append("(nullptr)"); + output.Append(newline); + separator = ", "; + } + } + + static void AppendUppercaseWithUnderscores( + string str, + StringBuilder output) + { + if (string.IsNullOrEmpty(str)) + { + return; + } + char prev = str[0]; + output.Append(char.ToUpper(prev)); + for (int i = 1; i < str.Length; ++i) + { + char cur = str[i]; + if (char.IsUpper(cur) && char.IsLower(prev)) + { + output.Append('_'); + } + output.Append(char.ToUpper(cur)); + prev = cur; + } + } + + static bool CheckParametersMatch( + string[] paramTypeNames, + System.Reflection.ParameterInfo[] reflectionParams) + { + // Length must match + if (reflectionParams.Length != paramTypeNames.Length) + { + return false; + } + + // All params must match + for (int i = 0; i < reflectionParams.Length; ++i) + { + Type type = DereferenceParameterType( + reflectionParams[i]); + string typeName = paramTypeNames[i]; + if (!CheckTypeNameMatches(typeName, type)) + { + return false; + } + } + + return true; + } + + static bool CheckTypeNameMatches( + string typeName, + Type type) + { + // No namespace. Only name must match. + if (string.IsNullOrEmpty(type.Namespace)) + { + if (type.Name != typeName) + { + return false; + } + } + // Must be: Namespace.Name + else + { + // Length must be the same as (namespace + '.' + name) + if ( + typeName.Length != + type.Namespace.Length + + 1 + + type.Name.Length) + { + return false; + } + + // Must start with namespace + if (!typeName.StartsWith(type.Namespace)) + { + return false; + } + + // Namespace must be followed by '.' + if (typeName[type.Namespace.Length] != '.') + { + return false; + } + + // Must end with name + if (!typeName.EndsWith(type.Name)) + { + return false; + } + } + + return true; + } + + static void AppendParameterTypeNames( + ParameterInfo[] parameters, + StringBuilder output) + { + for (int i = 0, len = parameters.Length; i < len; ++i) + { + Type type = parameters[i].DereferencedParameterType; + AppendNamespace(type.Namespace, string.Empty, output); + AppendTypeNameWithoutSuffixes( + type.Name, + output); + if (type.IsArray) + { + output.Append("Array"); + output.Append(type.GetArrayRank()); + } + if (i != len - 1) + { + output.Append('_'); + } + } + } + + static void AppendTypeNames( + Type[] typeNames, + StringBuilder output) + { + if (typeNames != null) + { + for (int i = 0, len = typeNames.Length; i < len; ++i) + { + Type curType = typeNames[i]; + AppendNamespace( + curType.Namespace, + string.Empty, + output); + AppendTypeNameWithoutSuffixes( + curType.Name, + output); + if (i != len - 1) + { + output.Append('_'); + } + } + } + } + + static TypeName GetBaseTypeBaseNameAndNamespace( + JsonBaseType jsonBaseType, + Type type, + Type[] typeParams, + StringBuilder tempStringBuilder) + { + // Get specified (optional) base type name + TypeName baseTypeTypeName = SplitJsonTypeName(jsonBaseType.BaseName); + + // If base type name isn't provided, make one + if (string.IsNullOrEmpty(baseTypeTypeName.Name)) + { + tempStringBuilder.Length = 0; + AppendNamespace( + type.Namespace, + string.Empty, + tempStringBuilder); + tempStringBuilder.Append("Base"); + AppendTypeNameWithoutSuffixes( + type.Name, + tempStringBuilder); + AppendTypeNames( + typeParams, + tempStringBuilder); + baseTypeTypeName.Name = tempStringBuilder.ToString(); + } + + baseTypeTypeName.NumTypeParams = typeParams.Length; + return baseTypeTypeName; + } + + static void AppendNamespace( + string namespaceName, + string separator, + StringBuilder output) + { + int startIndex = 0; + if (!string.IsNullOrEmpty(namespaceName)) + { + do + { + int separatorIndex = namespaceName.IndexOf( + '.', + startIndex); + if (separatorIndex < 0) + { + separatorIndex = namespaceName.IndexOf( + '+', + startIndex); + if (separatorIndex < 0) + { + break; + } + } + output.Append( + namespaceName, + startIndex, + separatorIndex - startIndex); + output.Append(separator); + startIndex = separatorIndex + 1; + } + while (true); + output.Append( + namespaceName, + startIndex, + namespaceName.Length - startIndex); + } + } + + static TypeName SplitJsonTypeName(string fullName) + { + string typeName; + string typeNamespace; + + // No full name + if (string.IsNullOrEmpty(fullName)) + { + typeName = string.Empty; + typeNamespace = string.Empty; + } + else + { + // Has a namespace + int index = fullName.LastIndexOf('.'); + if (index >= 0) + { + typeNamespace = fullName.Substring(0, index); + typeName = fullName.Substring(index + 1); + } + // No namespace. Just name. + else + { + typeName = fullName; + typeNamespace = string.Empty; + } + } + + return GetTypeName(typeName, typeNamespace); + } + + static ParameterInfo[] ConvertParameters( + System.Reflection.ParameterInfo[] reflectionParameters, + int start = 0) + { + int num = reflectionParameters.Length - start; + ParameterInfo[] parameters = new ParameterInfo[num]; + for (int i = start; i < num; ++i) + { + System.Reflection.ParameterInfo reflectionInfo = + reflectionParameters[i]; + ParameterInfo info = new ParameterInfo(); + info.Name = reflectionInfo.Name; + info.ParameterType = reflectionInfo.ParameterType; + info.IsOut = reflectionInfo.IsOut; + info.IsRef = !info.IsOut && info.ParameterType.IsByRef; + info.DereferencedParameterType = DereferenceParameterType( + reflectionInfo); + info.Kind = GetTypeKind( + info.DereferencedParameterType); + info.HasDefault = (reflectionInfo.Attributes & + ParameterAttributes.HasDefault) == + ParameterAttributes.HasDefault; + info.DefaultValue = reflectionInfo.DefaultValue; + info.IsVarArg = reflectionInfo.IsDefined( + typeof(ParamArrayAttribute), + false); + parameters[i - start] = info; + } + return parameters; + } + + static Type DereferenceParameterType( + System.Reflection.ParameterInfo info) + { + Type paramType = info.ParameterType; + return info.IsOut + ? paramType.GetElementType() + : paramType.IsByRef + ? paramType.GetElementType() + : paramType; + } + + static ParameterInfo[] ConvertParameters( + Type[] paramTypes) + { + int num = paramTypes.Length; + ParameterInfo[] parameters = new ParameterInfo[num]; + for (int i = 0; i < num; ++i) + { + Type paramType = paramTypes[i]; + ParameterInfo info = new ParameterInfo(); + info.Name = "param" + i; + info.ParameterType = paramType; + info.IsOut = false; + info.IsRef = false; + info.DereferencedParameterType = paramType; + info.Kind = GetTypeKind( + info.DereferencedParameterType); + parameters[i] = info; + } + return parameters; + } + + static TypeName GetTypeName(Type type) + { + TypeName typeName; + typeName.Name = type.Name; + typeName.Namespace = type.Namespace; + typeName.NumTypeParams = type.GetGenericArguments().Length; + return typeName; + } + + static TypeName GetTypeName( + string name, + string namespaceName) + { + TypeName typeName; + typeName.Name = name; + typeName.Namespace = namespaceName; + typeName.NumTypeParams = 0; + return typeName; + } + + static TypeName GetTypeName( + string name, + string namespaceName, + int numTypeParams) + { + TypeName typeName; + typeName.Name = name; + typeName.Namespace = namespaceName; + typeName.NumTypeParams = numTypeParams; + return typeName; + } + + static bool IsStatic(Type type) + { + return type.IsAbstract && type.IsSealed; + } + + static bool IsDelegate(Type type) + { + return typeof(Delegate).IsAssignableFrom(type); + } + + static bool IsNonDelegateClass(Type type) + { + return type.IsClass && !IsDelegate(type); + } + + static bool IsManagedValueType(Type type) + { + return type.IsValueType && !IsFullValueType(type); + } + + static bool IsFullValueType(Type type) + { + if (!type.IsValueType) + { + return false; + } + if (type.IsPrimitive || type.IsEnum || type == typeof(void)) + { + return true; + } + const BindingFlags bindingFlags = + BindingFlags.Instance + | BindingFlags.NonPublic + | BindingFlags.Public; + foreach (FieldInfo field in type.GetFields(bindingFlags)) + { + if (!field.IsPublic + || (!field.IsStatic + && !IsFullValueType(field.FieldType))) + { + return false; + } + } + return true; + } + + static int ArrayIndexOf(T[] array, T value) + { + return array != null ? + Array.IndexOf(array, value) : + -1; + } + + static void AppendTypeNameWithoutGenericSuffix( + string typeName, + StringBuilder output) + { + // Names are like "List`1" + // Remove the ` and everything after it + int backtickIndex = typeName.IndexOf('`'); + if (backtickIndex < 0) + { + output.Append(typeName); + } + else + { + // Append up to (but not including) the ` + output.Append( + typeName, + 0, + backtickIndex); + + // Find the first non-number after the ` + int endIndex = backtickIndex + 1; + while ( + endIndex < typeName.Length + && char.IsNumber(typeName[endIndex])) + { + endIndex++; + } + + // Append everything after the numbers + if (endIndex < typeName.Length) + { + output.Append( + typeName, + endIndex, + typeName.Length - endIndex); + } + } + } + + static void AppendTypeNameWithoutSuffixes( + string typeName, + StringBuilder output) + { + // Names are like "List`1" or "int[]" or "List`1[]" + // Remove the first of ` or [ and everything after it + int backtickIndex = typeName.IndexOf('`'); + if (backtickIndex < 0) + { + int bracketIndex = typeName.IndexOf('['); + if (bracketIndex < 0) + { + output.Append(typeName); + } + else + { + output.Append(typeName, 0, bracketIndex); + } + } + else + { + output.Append(typeName, 0, backtickIndex); + } + } + + static void AppendType( + JsonType jsonType, + Type type, + TypeKind typeKind, + Assembly[] assemblies, + int defaultMaxSimultaneous, + StringBuilders builders) + { + if (typeKind == TypeKind.Enum) + { + AppendEnum( + type, + builders); + AppendUnboxing( + type, + typeKind, + null, + builders); + } + else + { + Type[] genericArgTypes = type.GetGenericArguments(); + if (jsonType.GenericParams != null) + { + if (!IsStatic(type)) + { + AppendCppTemplateDeclaration( + GetTypeName(type), + builders.CppTemplateDeclarations); + } + + foreach (JsonGenericParams jsonGenericParams + in jsonType.GenericParams) + { + Type[] typeParams = GetTypes( + jsonGenericParams.Types, + assemblies); + Type genericType = type.MakeGenericType(typeParams); + int maxSimultaneous = jsonGenericParams.MaxSimultaneous != 0 + ? jsonGenericParams.MaxSimultaneous + : jsonType.MaxSimultaneous != 0 + ? jsonType.MaxSimultaneous + : defaultMaxSimultaneous; + AppendType( + jsonType, + genericArgTypes, + genericType, + typeKind, + typeParams, + maxSimultaneous, + assemblies, + builders); + if (typeKind != TypeKind.Class) + { + AppendUnboxing( + genericType, + typeKind, + typeParams, + builders); + } + } + } + else + { + int maxSimultaneous = jsonType.MaxSimultaneous != 0 + ? jsonType.MaxSimultaneous + : defaultMaxSimultaneous; + AppendType( + jsonType, + genericArgTypes, + type, + typeKind, + null, + maxSimultaneous, + assemblies, + builders); + if (typeKind != TypeKind.Class) + { + AppendUnboxing( + type, + typeKind, + null, + builders); + } + } + } + } + + static void AppendType( + JsonType jsonType, + Type[] genericArgTypes, + Type type, + TypeKind typeKind, + Type[] typeParams, + int maxSimultaneous, + Assembly[] assemblies, + StringBuilders builders) + { + bool isStatic = IsStatic(type); + if (!isStatic && typeKind == TypeKind.ManagedStruct) + { + // C# StructStore Init call + builders.CsharpStoreInitCalls.Append( + "\t\t\tNativeScript.Bindings.StructStore<"); + AppendCsharpTypeFullName( + type, + builders.CsharpStoreInitCalls); + builders.CsharpStoreInitCalls.Append(">.Init("); + builders.CsharpStoreInitCalls.Append(maxSimultaneous); + builders.CsharpStoreInitCalls.AppendLine(");"); + + // Build function name suffix + builders.TempStrBuilder.Length = 0; + AppendReleaseFunctionNameSuffix( + GetTypeName(type), + typeParams, + builders.TempStrBuilder); + string funcNameSuffix = builders.TempStrBuilder.ToString(); + + // Build function name + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Release"); + AppendReleaseFunctionNameSuffix( + GetTypeName(type), + typeParams, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + // Build ReleaseX parameters + ParameterInfo paramInfo = new ParameterInfo(); + paramInfo.Name = "handle"; + paramInfo.ParameterType = typeof(int); + paramInfo.IsOut = false; + paramInfo.IsRef = false; + paramInfo.DereferencedParameterType = typeof(int); + paramInfo.Kind = TypeKind.Primitive; + ParameterInfo[] parameters = { paramInfo }; + + // ReleaseX C# delegate type + AppendCsharpDelegateType( + funcName, + true, + type, + typeKind, + typeof(void), + parameters, + builders.CsharpDelegateTypes); + + // ReleaseX C# function + AppendCsharpFunctionBeginning( + type, + funcName, + true, + typeKind, + typeof(void), + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.AppendLine("if (handle != 0)"); + builders.CsharpFunctions.AppendLine("\t\t\t{"); + builders.CsharpFunctions.Append( + "\t\t\t\tNativeScript.Bindings.StructStore<"); + AppendCsharpTypeFullName( + type, + builders.CsharpFunctions); + builders.CsharpFunctions.AppendLine(">.Remove(handle);"); + builders.CsharpFunctions.Append("\t\t\t}"); + AppendCsharpFunctionEnd( + typeof(void), + new Type[0], + parameters, + builders.CsharpFunctions); + + // C++ function pointer definition + AppendCppFunctionPointerDefinition( + funcName, + true, + default(TypeName), + TypeKind.None, + parameters, + typeof(void), + builders.CppFunctionPointers); + + // C++ init body for ReleaseX + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + true, + default(TypeName), + TypeKind.None, + parameters, + typeof(void), + builders.CppInitBodyParameterReads); + + // C# init call arg for ReleaseX + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C++ init body for handle array length + builders.CppInitBodyArrays.Append("\tPlugin::RefCounts"); + builders.CppInitBodyArrays.Append(funcNameSuffix); + builders.CppInitBodyArrays.AppendLine(" = (int32_t*)curMemory;"); + builders.CppInitBodyArrays.Append("\tcurMemory += "); + builders.CppInitBodyArrays.Append(maxSimultaneous); + builders.CppInitBodyArrays.AppendLine(" * sizeof(int32_t);"); + builders.CppInitBodyArrays.Append("\tPlugin::RefCountsLen"); + builders.CppInitBodyArrays.Append(funcNameSuffix); + builders.CppInitBodyArrays.Append(" = "); + builders.CppInitBodyArrays.Append(maxSimultaneous); + builders.CppInitBodyArrays.AppendLine(";"); + builders.CppInitBodyArrays.AppendLine("\t"); + + // C++ ref count state and functions + builders.CppGlobalStateAndFunctions.Append("\tint32_t RefCountsLen"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine(";"); + builders.CppGlobalStateAndFunctions.Append("\tint32_t* RefCounts"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine(";"); + builders.CppGlobalStateAndFunctions.AppendLine("\t"); + builders.CppGlobalStateAndFunctions.Append("\tvoid ReferenceManaged"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine("(int32_t handle)"); + builders.CppGlobalStateAndFunctions.AppendLine("\t{"); + builders.CppGlobalStateAndFunctions.Append("\t\tassert(handle >= 0 && handle < RefCountsLen"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine(");"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\tif (handle != 0)"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t{"); + builders.CppGlobalStateAndFunctions.Append("\t\t\tRefCounts"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine("[handle]++;"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t}"); + builders.CppGlobalStateAndFunctions.AppendLine("\t}"); + builders.CppGlobalStateAndFunctions.AppendLine("\t"); + builders.CppGlobalStateAndFunctions.Append("\tvoid DereferenceManaged"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine("(int32_t handle)"); + builders.CppGlobalStateAndFunctions.AppendLine("\t{"); + builders.CppGlobalStateAndFunctions.Append("\t\tassert(handle >= 0 && handle < RefCountsLen"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine(");"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\tif (handle != 0)"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t{"); + builders.CppGlobalStateAndFunctions.Append("\t\t\tint32_t numRemain = --RefCounts"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine("[handle];"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t\tif (numRemain == 0)"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t\t{"); + builders.CppGlobalStateAndFunctions.Append("\t\t\t\tRelease"); + builders.CppGlobalStateAndFunctions.Append(funcNameSuffix); + builders.CppGlobalStateAndFunctions.AppendLine("(handle);"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t\t}"); + builders.CppGlobalStateAndFunctions.AppendLine("\t\t}"); + builders.CppGlobalStateAndFunctions.AppendLine("\t}"); + builders.CppGlobalStateAndFunctions.AppendLine("\t"); + } + + // C++ type declaration + int indent = AppendCppTypeDeclaration( + GetTypeName(type), + isStatic, + typeParams, + typeParams != null ? + builders.CppTemplateSpecializationDeclarations : + builders.CppTypeDeclarations); + + // C++ type definition (beginning) + Type[] interfaceTypes = GetDirectInterfaces(type); + string baseTypeName; + string baseTypeNamespace; + Type[] baseTypeTypeParams; + switch (typeKind) + { + case TypeKind.FullStruct: + baseTypeName = null; + baseTypeNamespace = null; + baseTypeTypeParams = null; + break; + case TypeKind.ManagedStruct: + if (interfaceTypes.Length == 0) + { + baseTypeName = "ManagedType"; + baseTypeNamespace = "Plugin"; + baseTypeTypeParams = null; + } + else + { + baseTypeName = null; + baseTypeNamespace = null; + baseTypeTypeParams = null; + } + break; + default: + Type baseType = type.BaseType ?? typeof(object); + baseTypeName = baseType.Name; + baseTypeNamespace = baseType.Namespace; + baseTypeTypeParams = baseType.GetGenericArguments(); + break; + } + + AppendCppTypeDefinitionBegin( + GetTypeName(type), + typeKind, + typeParams, + GetTypeName(baseTypeName, baseTypeNamespace), + baseTypeTypeParams, + interfaceTypes, + isStatic, + indent, + builders.CppTypeDefinitions); + + // C++ method definition + Type[] cppCtorInterfaceTypes = GetCppCtorInitTypes( + type, + false); + int cppMethodDefinitionsIndent = AppendCppMethodDefinitionsBegin( + GetTypeName(type), + typeKind, + typeParams, + cppCtorInterfaceTypes, + isStatic, + (extraIndent, subject) => {}, + (extraIndent, subject) => {}, + indent, + builders.CppMethodDefinitions); + + // Constructors + if (typeKind == TypeKind.FullStruct) + { + AppendFullValueTypeDefaultConstructor( + type, + indent, + builders); + } + if (jsonType.Constructors != null) + { + foreach (JsonConstructor jsonCtor in jsonType.Constructors) + { + AppendConstructor( + jsonCtor.ParamTypes, + jsonCtor.Exceptions, + type, + isStatic, + typeKind, + assemblies, + typeParams, + genericArgTypes, + cppCtorInterfaceTypes, + indent, + builders); + } + } + + // Properties + if (jsonType.Properties != null) + { + foreach (JsonProperty jsonProperty in jsonType.Properties) + { + AppendProperty( + jsonProperty, + type, + isStatic, + typeKind, + typeParams, + genericArgTypes, + indent, + assemblies, + builders); + } + } + + // Fields + if (typeKind == TypeKind.FullStruct) + { + AppendFullValueTypeFields( + type, + indent + 1, + builders); + } + else + { + if (jsonType.Fields != null) + { + foreach (string jsonFieldName in jsonType.Fields) + { + AppendField( + jsonFieldName, + type, + isStatic, + typeKind, + typeParams, + genericArgTypes, + indent, + builders + ); + } + } + } + + // Events + if (jsonType.Events != null) + { + foreach (JsonEvent jsonEvent in jsonType.Events) + { + AppendEvent( + jsonEvent, + type, + isStatic, + typeKind, + typeParams, + indent, + builders + ); + } + } + + // Methods + if (jsonType.Methods != null) + { + MethodInfo[] methods = type.GetMethods(); + foreach (JsonMethod jsonMethod in jsonType.Methods) + { + AppendMethod( + jsonMethod, + assemblies, + type, + isStatic, + typeKind, + methods, + typeParams, + genericArgTypes, + indent, + builders); + } + } + + // Boxing + if (typeKind != TypeKind.Class) + { + AppendBoxing( + type, + typeKind, + typeParams, + indent, + builders); + } + + // C++ type definition (ending) + AppendCppTypeDefinitionEnd( + isStatic, + indent, + builders.CppTypeDefinitions); + + // C++ method definition (ending) + AppendCppMethodDefinitionsEnd( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + // Generate iterator if this type implements IEnumerable + Type[] allInterfaces = type.GetInterfaces(); + foreach (Type interfaceType in allInterfaces) + { + if (interfaceType.IsGenericType + && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + builders.TempStrBuilder.Length = 0; + AppendNamespace( + type.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + type.Name, + builders.TempStrBuilder); + AppendTypeNames( + typeParams, + builders.TempStrBuilder); + string bindingEnumerableTypeName = builders.TempStrBuilder.ToString(); + + Type elementType = interfaceType.GetGenericArguments()[0]; + AppendGenericEnumerableIterator( + type, + typeof(IEnumerator<>).MakeGenericType(elementType), + elementType, + bindingEnumerableTypeName, + builders.CppTypeDefinitions, + builders.CppMethodDefinitions); + break; + } + } + } + + static void AppendBaseType( + Type type, + TypeName cppBaseTypeTypeName, + JsonBaseType jsonBaseType, + Assembly[] assemblies, + int defaultMaxSimultaneous, + StringBuilders builders) + { + int maxSimultaneous = jsonBaseType.MaxSimultaneous != 0 + ? jsonBaseType.MaxSimultaneous + : defaultMaxSimultaneous; + if (jsonBaseType.GenericTypes != null) + { + Type[] typeParams = GetTypes( + jsonBaseType.GenericTypes, + assemblies); + Type genericType = type.MakeGenericType(typeParams); + AppendBaseType( + genericType, + jsonBaseType, + cppBaseTypeTypeName, + typeParams, + maxSimultaneous, + assemblies, + builders); + } + else + { + AppendBaseType( + type, + jsonBaseType, + cppBaseTypeTypeName, + null, + maxSimultaneous, + assemblies, + builders); + } + } + + static void AppendReleaseFunctionNameSuffix( + TypeName typeTypeName, + Type[] typeParams, + StringBuilder output) + { + AppendNamespace( + typeTypeName.Namespace, + string.Empty, + output); + AppendTypeNameWithoutSuffixes( + typeTypeName.Name, + output); + if (typeParams != null) + { + for (int i = 0, len = typeParams.Length; i < len; ++i) + { + Type typeParam = typeParams[i]; + AppendNamespace( + typeParam.Namespace, + string.Empty, + output); + AppendTypeNameWithoutSuffixes( + typeParam.Name, + output); + if (i != len - 1) + { + output.Append('_'); + } + } + } + } + + static void AppendEnum( + Type type, + StringBuilders builders) + { + // C++ type declaration + int indent = AppendCppTypeDeclaration( + GetTypeName(type), + false, + null, + builders.CppTypeDeclarations); + + // C++ type definition (begin) + AppendCppTypeDefinitionBegin( + GetTypeName(type), + TypeKind.FullStruct, + null, + default(TypeName), + null, + null, + false, + indent, + builders.CppTypeDefinitions); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + + // Primitive type field + Type underlyingType = Enum.GetUnderlyingType(type); + AppendCppPrimitiveTypeName( + underlyingType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine(" Value;"); + + // Enumerator fields + FieldInfo[] fields = type.GetFields( + BindingFlags.Static + | BindingFlags.Public); + foreach (FieldInfo field in fields) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("static const "); + AppendCppTypeFullName( + type, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append(' '); + builders.CppTypeDefinitions.Append(field.Name); + builders.CppTypeDefinitions.AppendLine(";"); + } + + // Constructor from primitive type + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("explicit "); + builders.CppTypeDefinitions.Append(type.Name); + builders.CppTypeDefinitions.Append('('); + AppendCppPrimitiveTypeName( + underlyingType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine(" value);"); + + // Conversion operator to primitive type + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("explicit operator "); + AppendCppPrimitiveTypeName( + underlyingType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("() const;"); + + // Equality operator + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("bool operator==("); + builders.CppTypeDefinitions.Append(type.Name); + builders.CppTypeDefinitions.AppendLine(" other);"); + + // Inequality operator + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("bool operator!=("); + builders.CppTypeDefinitions.Append(type.Name); + builders.CppTypeDefinitions.AppendLine(" other);"); + + AppendNamespaceBeginning( + type.Namespace, + builders.CppMethodDefinitions); + + // Constructor from primitive type + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(type.Name); + builders.CppMethodDefinitions.Append("::"); + builders.CppMethodDefinitions.Append(type.Name); + builders.CppMethodDefinitions.Append('('); + AppendCppPrimitiveTypeName( + underlyingType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(" value)"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(": Value(value)"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(); + + // Conversion operator to primitive type + AppendIndent( + indent, + builders.CppMethodDefinitions); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("::operator "); + AppendCppPrimitiveTypeName( + underlyingType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("() const"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return Value;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // Equality operator + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("bool "); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("::operator==("); + builders.CppMethodDefinitions.Append(type.Name); + builders.CppMethodDefinitions.AppendLine(" other)"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return Value == other.Value;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // Inequality operator + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("bool "); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("::operator!=("); + builders.CppMethodDefinitions.Append(type.Name); + builders.CppMethodDefinitions.AppendLine(" other)"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return Value != other.Value;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + AppendBoxing( + type, + TypeKind.Enum, + null, + indent, + builders); + + AppendNamespaceEnding( + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("};"); + AppendNamespaceEnding( + indent, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine();; + + // Static initialization + foreach (FieldInfo field in fields) + { + builders.CppMethodDefinitions.Append("const "); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(' '); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("::"); + builders.CppMethodDefinitions.Append(field.Name); + builders.CppMethodDefinitions.Append('('); + builders.CppMethodDefinitions.Append( + field.GetRawConstantValue()); + builders.CppMethodDefinitions.AppendLine(");"); + } + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendBoxing( + Type type, + TypeKind typeKind, + Type[] typeParams, + int indent, + StringBuilders builders) + { + string boxFuncName; + ParameterInfo[] boxCppParams; + AppendBoxingBindings( + type, + typeKind, + typeParams, + builders, + out boxFuncName, + out boxCppParams); + + for (Type baseType = type.BaseType; + baseType != null; + baseType = baseType.BaseType) + { + string boxMethodDefinitionName; + string boxMethodDeclarationName; + AppendCppBoxingMethodNames( + baseType, + builders.TempStrBuilder, + out boxMethodDefinitionName, + out boxMethodDeclarationName); + AppendCppBoxingMethodDeclaration( + boxMethodDeclarationName, + boxCppParams, + indent + 1, + builders.CppTypeDefinitions); + AppendCppBoxingMethodDefinition( + type, + typeParams, + baseType, + typeKind, + boxMethodDefinitionName, + boxFuncName, + boxCppParams, + indent, + builders.CppMethodDefinitions); + } + foreach (Type interfaceType in type.GetInterfaces()) + { + string boxMethodDefinitionName; + string boxMethodDeclarationName; + AppendCppBoxingMethodNames( + interfaceType, + builders.TempStrBuilder, + out boxMethodDefinitionName, + out boxMethodDeclarationName); + AppendCppBoxingMethodDeclaration( + boxMethodDeclarationName, + boxCppParams, + indent + 1, + builders.CppTypeDefinitions); + AppendCppBoxingMethodDefinition( + type, + typeParams, + interfaceType, + typeKind, + boxMethodDefinitionName, + boxFuncName, + boxCppParams, + indent, + builders.CppMethodDefinitions); + } + } + + static void AppendBoxingBindings( + Type type, + TypeKind typeKind, + Type[] typeParams, + StringBuilders builders, + out string boxFuncName, + out ParameterInfo[] boxCppParams) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Box"); + AppendTypeNameWithoutSuffixes( + type.Name, + builders.TempStrBuilder); + AppendTypeNames( + typeParams, + builders.TempStrBuilder); + boxFuncName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] boxParams = { + new ParameterInfo + { + Name = "val", + ParameterType = type, + DereferencedParameterType = type, + IsOut = false, + IsRef = false, + Kind = typeKind + } + }; + + boxCppParams = new ParameterInfo[0]; + + // C# delegate types + AppendCsharpDelegateType( + boxFuncName, + true, + type, + typeKind, + typeof(object), + boxParams, + builders.CsharpDelegateTypes); + + // C# init call args + AppendCsharpCsharpDelegate( + boxFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# box function + AppendCsharpFunctionBeginning( + typeof(object), + boxFuncName, + true, + TypeKind.Class, + typeof(object), + boxParams, + builders.CsharpFunctions); + builders.CsharpFunctions.Append( + "NativeScript.Bindings.ObjectStore.Store((object)val);"); + AppendCsharpFunctionReturn( + boxParams, + typeof(object), + TypeKind.Class, + null, + true, + builders.CsharpFunctions); + + // C++ function pointers + AppendCppFunctionPointerDefinition( + boxFuncName, + true, + GetTypeName(type), + typeKind, + boxParams, + typeof(object), + builders.CppFunctionPointers); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + boxFuncName, + true, + GetTypeName(type), + typeKind, + boxParams, + typeof(object), + builders.CppInitBodyParameterReads); + } + + static void AppendUnboxing( + Type type, + TypeKind typeKind, + Type[] typeParams, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Unbox"); + AppendTypeNameWithoutSuffixes( + type.Name, + builders.TempStrBuilder); + AppendTypeNames( + typeParams, + builders.TempStrBuilder); + string unboxFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("operator "); + AppendCppTypeFullName( + type, + builders.TempStrBuilder); + string unboxMethodDefinitionName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("explicit "); + builders.TempStrBuilder.Append(unboxMethodDefinitionName); + string unboxMethodDeclarationName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] unboxParams = { + new ParameterInfo + { + Name = "val", + ParameterType = typeof(object), + DereferencedParameterType = typeof(object), + IsOut = false, + IsRef = false, + Kind = TypeKind.Class + } + }; + + ParameterInfo[] unboxCppParams = new ParameterInfo[0]; + + // C# init params + + // C# delegate types + AppendCsharpDelegateType( + unboxFuncName, + true, + type, + typeKind, + type, + unboxParams, + builders.CsharpDelegateTypes); + + // C# init call args + AppendCsharpCsharpDelegate( + unboxFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# unbox function + AppendCsharpFunctionBeginning( + typeof(object), + unboxFuncName, + true, + TypeKind.Class, + type, + unboxParams, + builders.CsharpFunctions); + switch (typeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + AppendHandleStoreTypeName( + type, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(".Store(("); + AppendCsharpTypeFullName( + type, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(")val);"); + break; + default: + builders.CsharpFunctions.Append('('); + AppendCsharpTypeFullName( + type, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(")val;"); + break; + } + AppendCsharpFunctionReturn( + unboxParams, + type, + typeKind, + null, + true, + builders.CsharpFunctions); + + // C++ function pointers + AppendCppFunctionPointerDefinition( + unboxFuncName, + true, + GetTypeName(type), + typeKind, + unboxParams, + type, + builders.CppFunctionPointers); + + // C++ unbox method declaration and definition + AppendIndent( + 2, + builders.CppUnboxingMethodDeclarations); + AppendCppMethodDeclaration( + unboxMethodDeclarationName, + false, + false, + false, + null, + null, + unboxCppParams, + builders.CppUnboxingMethodDeclarations); + int indent = AppendNamespaceBeginning( + "System", + builders.CppMethodDefinitions); + AppendCppMethodDefinitionBegin( + GetTypeName(typeof(object)), + null, + unboxMethodDefinitionName, + null, + null, + unboxCppParams, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + AppendCppTypeFullName( + type, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(" returnVal("); + if (typeKind == TypeKind.ManagedStruct) + { + builders.CppMethodDefinitions.Append("Plugin::InternalUse::Only, "); + } + builders.CppMethodDefinitions.Append("Plugin::"); + builders.CppMethodDefinitions.Append(unboxFuncName); + builders.CppMethodDefinitions.AppendLine("(Handle));"); + AppendCppUnhandledExceptionHandling( + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return returnVal;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine("\t"); + + // C++ method definitions (end) + AppendCppMethodDefinitionsEnd( + indent, + builders.CppMethodDefinitions); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + unboxFuncName, + true, + GetTypeName(type), + typeKind, + unboxParams, + type, + builders.CppInitBodyParameterReads); + } + + static void AppendCppBoxingMethodNames( + Type baseType, + StringBuilder tempBuilder, + out string boxMethodDefinitionName, + out string boxMethodDeclarationName) + { + tempBuilder.Length = 0; + tempBuilder.Append("operator "); + AppendCppTypeFullName( + baseType, + tempBuilder); + boxMethodDefinitionName = tempBuilder.ToString(); + + tempBuilder.Length = 0; + tempBuilder.Append("explicit "); + tempBuilder.Append(boxMethodDefinitionName); + boxMethodDeclarationName = tempBuilder.ToString(); + } + + static void AppendCppBoxingMethodDeclaration( + string boxMethodDeclarationName, + ParameterInfo[] boxCppParams, + int indent, + StringBuilder output) + { + AppendIndent( + indent, + output); + AppendCppMethodDeclaration( + boxMethodDeclarationName, + false, + false, + false, + null, + null, + boxCppParams, + output); + } + + static void AppendCppBoxingMethodDefinition( + Type enclosingType, + Type[] enclosingTypeTypeParams, + Type boxedType, + TypeKind typeKind, + string boxMethodDefinitionName, + string boxFuncName, + ParameterInfo[] boxCppParams, + int indent, + StringBuilder output) + { + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), + null, + boxMethodDefinitionName, + enclosingTypeTypeParams, + null, + boxCppParams, + indent, + output); + AppendIndent( + indent, + output); + output.AppendLine("{"); + AppendIndent( + indent + 1, + output); + output.Append("int32_t handle = Plugin::"); + output.Append(boxFuncName); + output.Append('('); + if (typeKind == TypeKind.ManagedStruct) + { + output.Append("Handle"); + } + else + { + output.Append("*this"); + } + output.AppendLine(");"); + AppendCppUnhandledExceptionHandling( + indent + 1, + output); + AppendIndent( + indent + 1, + output); + output.AppendLine( + "if (handle)"); + AppendIndent( + indent + 1, + output); + output.AppendLine( + "{"); + AppendIndent( + indent + 2, + output); + AppendReferenceManagedHandleFunctionCall( + GetTypeName(typeof(object)), + TypeKind.Class, + null, + "handle", + output); + output.AppendLine(";"); + AppendIndent( + indent + 2, + output); + output.Append("return "); + AppendCppTypeFullName( + boxedType, + output); + output.AppendLine("(Plugin::InternalUse::Only, handle);"); + AppendIndent( + indent + 1, + output); + output.AppendLine( + "}"); + AppendIndent( + indent + 1, + output); + output.AppendLine("return nullptr;"); + AppendIndent( + indent, + output); + output.AppendLine("}"); + AppendIndent( + indent, + output); + output.AppendLine();; + } + + static void AppendHandleStoreTypeName( + Type type, + StringBuilder output) + { + output.Append("NativeScript.Bindings."); + if (IsManagedValueType(type)) + { + output.Append("StructStore<"); + AppendCsharpTypeFullName(type, output); + output.Append('>'); + } + else + { + output.Append("ObjectStore"); + } + } + + static void AppendConstructor( + string[] paramTypeNames, + string[] exceptionNames, + Type enclosingType, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + Assembly[] assemblies, + Type[] enclosingTypeParams, + Type[] genericArgTypes, + Type[] interfaceTypes, + int indent, + StringBuilders builders) + { + // Get the constructor's parameters + ParameterInfo[] parameters; + if (enclosingType.IsValueType + && !enclosingType.IsPrimitive + && !enclosingType.IsEnum + && paramTypeNames.Length == 0) + { + // Allow parameterless constructor for structs + parameters = new ParameterInfo[0]; + } + else + { + string[] constructorParamTypeNames; + if (enclosingType.IsGenericType) + { + constructorParamTypeNames = OverrideGenericTypeNames( + paramTypeNames, + genericArgTypes, + enclosingTypeParams); + } + else + { + constructorParamTypeNames = paramTypeNames; + } + parameters = GetConstructorParameters( + enclosingType, + false, + constructorParamTypeNames); + } + + Type[] exceptionTypes = GetTypes( + exceptionNames, + assemblies); + + // Build uppercase function name + builders.TempStrBuilder.Length = 0; + AppendNamespace( + enclosingType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.TempStrBuilder); + AppendTypeNames( + enclosingTypeParams, + builders.TempStrBuilder); + builders.TempStrBuilder.Append("Constructor"); + AppendParameterTypeNames( + parameters, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + TypeName enclosingTypeTypeName = GetTypeName(enclosingType); + + // Build C++ constructor method name + builders.TempStrBuilder.Length = 0; + AppendCppTypeName( + enclosingTypeTypeName, + builders.TempStrBuilder); + string cppMethodName = builders.TempStrBuilder.ToString(); + + // C# init param declaration + + // C# delegate type + Type delegateReturnType; + if (enclosingTypeKind == TypeKind.FullStruct) + { + delegateReturnType = enclosingType; + } + else + { + delegateReturnType = typeof(int); + } + AppendCsharpDelegateType( + funcName, + true, + enclosingType, + enclosingTypeKind, + delegateReturnType, + parameters, + builders.CsharpDelegateTypes); + + // C# init call param + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# function + if (enclosingTypeKind == TypeKind.FullStruct) + { + AppendCsharpFunctionBeginning( + enclosingType, + funcName, + true, + enclosingTypeKind, + enclosingType, + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("new "); + AppendCsharpTypeFullName( + enclosingType, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('('); + AppendCsharpFunctionCallParameters( + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(");"); + AppendCsharpFunctionReturn( + parameters, + enclosingType, + enclosingTypeKind, + exceptionTypes, + true, + builders.CsharpFunctions); + } + else + { + AppendCsharpFunctionBeginning( + enclosingType, + funcName, + true, + enclosingTypeKind, + typeof(int), + parameters, + builders.CsharpFunctions); + AppendHandleStoreTypeName( + enclosingType, + builders.CsharpFunctions); + builders.CsharpFunctions.Append( + ".Store(new "); + AppendCsharpTypeFullName( + enclosingType, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('('); + AppendCsharpFunctionCallParameters( + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("));"); + AppendCsharpFunctionReturn( + parameters, + typeof(int), + TypeKind.Primitive, + exceptionTypes, + true, + builders.CsharpFunctions); + } + + // C++ function pointer + AppendCppFunctionPointerDefinition( + funcName, + true, + enclosingTypeTypeName, + enclosingTypeKind, + parameters, + enclosingType, + builders.CppFunctionPointers); + + // C++ type declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppMethodName, + enclosingTypeIsStatic, + false, + false, + null, + null, + parameters, + builders.CppTypeDefinitions); + + // C++ method definition + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), + null, + cppMethodName, + enclosingTypeParams, + null, + parameters, + indent, + builders.CppMethodDefinitions); + if (enclosingTypeKind == TypeKind.Class) + { + AppendCppConstructorInitializerList( + interfaceTypes, + indent + 1, + builders.CppMethodDefinitions); + } + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + true, + GetTypeName(enclosingType), + enclosingTypeKind, + enclosingTypeParams, + enclosingType, + funcName, + parameters, + indent + 1, + builders.CppMethodDefinitions); + if (enclosingTypeKind == TypeKind.FullStruct) + { + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "*this = returnValue;"); + } + else + { + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "Handle = returnValue;"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "if (returnValue)"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "{"); + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + AppendReferenceManagedHandleFunctionCall( + GetTypeName(enclosingType), + enclosingTypeKind, + enclosingTypeParams, + "returnValue", + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(";"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "}"); + } + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + true, + GetTypeName(enclosingType), + enclosingTypeKind, + parameters, + enclosingType, + builders.CppInitBodyParameterReads); + } + + static void AppendProperty( + JsonProperty jsonProperty, + Type enclosingType, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + Type[] typeParams, + Type[] typeGenericArgumentTypes, + int indent, + Assembly[] assemblies, + StringBuilders builders) + { + JsonPropertyGet jsonPropertyGet = jsonProperty.Get; + if (jsonPropertyGet != null) + { + PropertyInfo property = null; + MethodInfo getMethod; + if (jsonPropertyGet.ParamTypes != null) + { + PropertyInfo[] properties = enclosingType.GetProperties(); + foreach (PropertyInfo curProperty in properties) + { + // Name must match + if (curProperty.Name != jsonProperty.Name) + { + continue; + } + + // Must have a get method + getMethod = curProperty.GetGetMethod(); + if (getMethod == null) + { + continue; + } + + // All parameters must match + if (CheckParametersMatch( + jsonPropertyGet.ParamTypes, + getMethod.GetParameters())) + { + property = curProperty; + break; + } + } + } + else + { + property = enclosingType.GetProperty(jsonProperty.Name); + } + + if (property == null) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Property '"); + builders.TempStrBuilder.Append(jsonProperty.Name); + builders.TempStrBuilder.Append("' not found on "); + builders.TempStrBuilder.Append(enclosingType); + throw new Exception(builders.TempStrBuilder.ToString()); + } + + getMethod = property.GetGetMethod(); + if (getMethod != null) + { + Type propertyType = property.PropertyType; + TypeKind propertyTypeKind = GetTypeKind(propertyType); + Type[] exceptionTypes = GetTypes( + jsonPropertyGet.Exceptions, + assemblies); + ParameterInfo[] parameters = ConvertParameters( + getMethod.GetParameters()); + OverrideGenericParameterTypes( + parameters, + typeGenericArgumentTypes, + typeParams); + AppendGetter( + property.Name, + "Property", + parameters, + enclosingTypeIsStatic, + enclosingTypeKind, + getMethod.IsStatic, + jsonPropertyGet.IsReadOnly, + enclosingType, + typeParams, + propertyType, + propertyTypeKind, + indent, + exceptionTypes, + builders); + } + } + + JsonPropertySet jsonPropertySet = jsonProperty.Set; + if (jsonPropertySet != null) + { + PropertyInfo property = null; + if (jsonPropertySet.ParamTypes != null) + { + PropertyInfo[] properties = enclosingType.GetProperties(); + foreach (PropertyInfo curProperty in properties) + { + // Name must match + if (curProperty.Name != jsonProperty.Name) + { + continue; + } + + // Must have a set method + MethodInfo setMethod = curProperty.GetSetMethod(); + if (setMethod == null) + { + continue; + } + + // All parameters must match + if (CheckParametersMatch( + jsonPropertySet.ParamTypes, + setMethod.GetParameters())) + { + property = curProperty; + break; + } + } + } + else + { + property = enclosingType.GetProperty(jsonProperty.Name); + } + + if (property == null) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Property '"); + builders.TempStrBuilder.Append(jsonProperty.Name); + builders.TempStrBuilder.Append("' not found on "); + builders.TempStrBuilder.Append(enclosingType); + throw new Exception(builders.TempStrBuilder.ToString()); + } + + MethodInfo method = property.GetSetMethod(); + if (method != null) + { + Type[] exceptionTypes = GetTypes( + jsonPropertySet.Exceptions, + assemblies); + ParameterInfo[] parameters = ConvertParameters( + method.GetParameters()); + OverrideGenericParameterTypes( + parameters, + typeGenericArgumentTypes, + typeParams); + AppendSetter( + property.Name, + "Property", + parameters, + enclosingTypeIsStatic, + enclosingTypeKind, + method.IsStatic, + jsonPropertySet.IsReadOnly, + enclosingType, + typeParams, + indent, + exceptionTypes, + builders); + } + } + } + + static void AppendFullValueTypeDefaultConstructor( + Type enclosingType, + int indent, + StringBuilders builders) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("();"); + + AppendIndent( + indent, + builders.CppMethodDefinitions); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("::"); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("()"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendFullValueTypeFields( + Type enclosingType, + int indent, + StringBuilders builders) + { + FieldInfo[] fields = enclosingType.GetFields( + BindingFlags.Instance + | BindingFlags.Public + | BindingFlags.NonPublic); + Array.Sort(fields, DefaultFieldOrderComparer); + foreach (FieldInfo field in fields) + { + AppendIndent( + indent, + builders.CppTypeDefinitions); + AppendCppTypeFullName( + field.FieldType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append(' '); + builders.CppTypeDefinitions.Append(field.Name); + builders.CppTypeDefinitions.AppendLine(";"); + } + } + + static void AppendField( + string jsonFieldName, + Type enclosingType, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + Type[] typeTypeParams, + Type[] typeGenericArgumentTypes, + int indent, + StringBuilders builders) + { + FieldInfo field = enclosingType.GetField(jsonFieldName); + Type fieldType = OverrideGenericType( + field.FieldType, + typeGenericArgumentTypes, + typeTypeParams); + TypeKind fieldTypeKind = GetTypeKind(fieldType); + Type[] exceptionTypes = new Type[0]; + AppendGetter( + field.Name, + "Field", + new ParameterInfo[0], + enclosingTypeIsStatic, + enclosingTypeKind, + field.IsStatic, + true, + enclosingType, + typeTypeParams, + fieldType, + fieldTypeKind, + indent, + exceptionTypes, + builders); + ParameterInfo setParam = new ParameterInfo(); + setParam.Name = "value"; + setParam.ParameterType = fieldType; + setParam.IsOut = false; + setParam.IsRef = false; + setParam.DereferencedParameterType = setParam.ParameterType; + setParam.Kind = GetTypeKind( + setParam.DereferencedParameterType); + ParameterInfo[] parameters = { setParam }; + AppendSetter( + field.Name, + "Field", + parameters, + enclosingTypeIsStatic, + enclosingTypeKind, + field.IsStatic, + false, + enclosingType, + typeTypeParams, + indent, + exceptionTypes, + builders); + } + + static void AppendEvent( + JsonEvent jsonEvent, + Type enclosingType, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + Type[] typeTypeParams, + int indent, + StringBuilders builders) + { + EventInfo eventInfo = enclosingType.GetEvent(jsonEvent.Name); + MethodInfo addMethod = eventInfo.GetAddMethod(); + MethodInfo removeMethod = eventInfo.GetRemoveMethod(); + Type eventType = eventInfo.EventHandlerType; + string uppercaseEventName = char.ToUpper(jsonEvent.Name[0]) + + jsonEvent.Name.Substring(1); + + ParameterInfo[] addRemoveParams = { + new ParameterInfo { + Name = "del", + ParameterType = eventType, + DereferencedParameterType = eventType, + IsOut = false, + IsRef = false, + Kind = TypeKind.Class, + IsVirtual = false + } + }; + + AppendEventAddRemoveMethod( + jsonEvent.Name, + uppercaseEventName, + "Add", + addMethod.IsStatic, + enclosingType, + enclosingTypeKind, + enclosingTypeIsStatic, + typeTypeParams, + addRemoveParams, + indent, + builders); + AppendEventAddRemoveMethod( + jsonEvent.Name, + uppercaseEventName, + "Remove", + removeMethod.IsStatic, + enclosingType, + enclosingTypeKind, + enclosingTypeIsStatic, + typeTypeParams, + addRemoveParams, + indent, + builders); + } + + static void AppendEventAddRemoveMethod( + string eventName, + string uppercaseEventName, + string operation, + bool methodIsStatic, + Type enclosingType, + TypeKind enclosingTypeKind, + bool enclosingTypeIsStatic, + Type[] typeTypeParams, + ParameterInfo[] methodParams, + int indent, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendNamespace( + enclosingType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.TempStrBuilder); + AppendTypeNames( + typeTypeParams, + builders.TempStrBuilder); + builders.TempStrBuilder.Append(operation); + builders.TempStrBuilder.Append("Event"); + builders.TempStrBuilder.Append(uppercaseEventName); + string funcName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(operation); + builders.TempStrBuilder.Append(uppercaseEventName); + string methodName = builders.TempStrBuilder.ToString(); + + // C# init param + + // C# delegate type + AppendCsharpDelegateType( + funcName, + methodIsStatic, + enclosingType, + enclosingTypeKind, + typeof(void), + methodParams, + builders.CsharpDelegateTypes); + + // C# init call arg + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# function + AppendCsharpFunctionBeginning( + enclosingType, + funcName, + methodIsStatic, + enclosingTypeKind, + typeof(void), + methodParams, + builders.CsharpFunctions); + AppendCsharpFunctionCallSubject( + enclosingType, + methodIsStatic, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('.'); + builders.CsharpFunctions.Append(eventName); + // TODO: More safely differenciate between add/removing event delegates + if (funcName.Contains("RemoveEvent")) + { + builders.CsharpFunctions.Append(" -= del;"); + } + else + { + builders.CsharpFunctions.Append(" += del;"); + } + AppendCsharpFunctionEnd( + typeof(void), + null, + methodParams, + builders.CsharpFunctions); + + // C++ function pointer + AppendCppFunctionPointerDefinition( + funcName, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + methodParams, + typeof(void), + builders.CppFunctionPointers); + + // C++ method declaration + Type cppReturnType = typeof(void); + string cppMethodName = methodName; + bool cppMethodIsStatic = methodIsStatic; + ParameterInfo[] cppParameters = methodParams; + ParameterInfo[] cppCallParameters = methodParams; + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppMethodName, + enclosingTypeIsStatic, + false, + cppMethodIsStatic, + cppReturnType, + null, + cppParameters, + builders.CppTypeDefinitions); + + // C++ method definition + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), + cppReturnType, + cppMethodName, + typeTypeParams, + null, + cppParameters, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + typeTypeParams, + typeof(void), + funcName, + cppCallParameters, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine("\t"); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + methodParams, + typeof(void), + builders.CppInitBodyParameterReads); + } + + static MethodInfo GetMethod( + JsonMethod jsonMethod, + Type enclosingType, + Type[] typeTypeParams, + Type[] genericArgTypes, + MethodInfo[] methods, + string[] methodGenericTypeNames) + { + // Map convenience method names to actual method names + switch (jsonMethod.Name) + { + case "+x": + jsonMethod.Name = "op_UnaryPlus"; + break; + case "-x": + jsonMethod.Name = "op_UnaryNegation"; + break; + case "!x": + jsonMethod.Name = "op_LogicalNot"; + break; + case "~x": + jsonMethod.Name = "op_OnesComplement"; + break; + case "x++": + jsonMethod.Name = "op_Increment"; + break; + case "x--": + jsonMethod.Name = "op_Decrement"; + break; + case "(true)x": + jsonMethod.Name = "op_True"; + break; + case "(false)x": + jsonMethod.Name = "op_False"; + break; + case "implicit": + jsonMethod.Name = "op_Implicit"; + break; + case "explicit": + jsonMethod.Name = "op_Explicit"; + break; + case "x+y": + jsonMethod.Name = "op_Addition"; + break; + case "x-y": + jsonMethod.Name = "op_Subtraction"; + break; + case "x*y": + jsonMethod.Name = "op_Multiply"; + break; + case "x/y": + jsonMethod.Name = "op_Division"; + break; + case "x%y": + jsonMethod.Name = "op_Modulus"; + break; + case "x&y": + jsonMethod.Name = "op_BitwiseAnd"; + break; + case "x|y": + jsonMethod.Name = "op_BitwiseOr"; + break; + case "x^y": + jsonMethod.Name = "op_ExclusiveOr"; + break; + case "x<>y": + jsonMethod.Name = "op_RightShift"; + break; + case "x==y": + jsonMethod.Name = "op_Equality"; + break; + case "x!=y": + jsonMethod.Name = "op_Inequality"; + break; + case "xy": + jsonMethod.Name = "op_GreaterThan"; + break; + case "x<=y": + jsonMethod.Name = "op_LessThanOrEqual"; + break; + case "x>=y": + jsonMethod.Name = "op_GreaterThanOrEqual"; + break; + } + + if (enclosingType.IsGenericType) + { + string[] overriddenParamTypeNames = OverrideGenericTypeNames( + jsonMethod.ParamTypes, + genericArgTypes, + typeTypeParams); + return GetMethod( + enclosingType, + methods, + jsonMethod.Name, + overriddenParamTypeNames, + methodGenericTypeNames); + } + else + { + return GetMethod( + enclosingType, + methods, + jsonMethod.Name, + jsonMethod.ParamTypes, + methodGenericTypeNames); + } + } + + static void AppendMethod( + JsonMethod jsonMethod, + Assembly[] assemblies, + Type enclosingType, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + MethodInfo[] methods, + Type[] typeTypeParams, + Type[] genericArgTypes, + int indent, + StringBuilders builders) + { + Type[] exceptionTypes = GetTypes( + jsonMethod.Exceptions, + assemblies); + + if (jsonMethod.GenericParams != null) + { + // Generate for each set of generic types + bool generateDeclaration = true; + foreach (JsonGenericParams jsonGenericParams + in jsonMethod.GenericParams) + { + MethodInfo method = GetMethod( + jsonMethod, + enclosingType, + typeTypeParams, + genericArgTypes, + methods, + jsonGenericParams.Types); + Type[] methodTypeParams = GetTypes( + jsonGenericParams.Types, + assemblies); + method = method.MakeGenericMethod(methodTypeParams); + ParameterInfo[] parameters = ConvertParameters( + method.GetParameters()); + Type returnType = method.ReturnType; + TypeKind returnTypeKind = GetTypeKind(returnType); + AppendMethod( + enclosingType, + method.Name, + enclosingTypeIsStatic, + enclosingTypeKind, + method.IsStatic, + jsonMethod.IsReadOnly, + returnType, + returnTypeKind, + typeTypeParams, + methodTypeParams, + parameters, + generateDeclaration, + indent, + exceptionTypes, + builders); + generateDeclaration = false; + } + } + else + { + MethodInfo method = GetMethod( + jsonMethod, + enclosingType, + typeTypeParams, + genericArgTypes, + methods, + null); + ParameterInfo[] parameters = ConvertParameters( + method.GetParameters()); + Type returnType = method.ReturnType; + TypeKind returnTypeKind = GetTypeKind(returnType); + AppendMethod( + enclosingType, + method.Name, + enclosingTypeIsStatic, + enclosingTypeKind, + method.IsStatic, + jsonMethod.IsReadOnly, + returnType, + returnTypeKind, + typeTypeParams, + null, + parameters, + true, + indent, + exceptionTypes, + builders); + } + } + + static Type OverrideGenericType( + Type genericType, + Type[] genericArgumentTypes, + Type[] overrideTypes) + { + if (genericType.IsGenericParameter) + { + for (int i = 0, len = genericArgumentTypes.Length; i < len; ++i) + { + if (genericType == genericArgumentTypes[i]) + { + return overrideTypes[i]; + } + } + } + return genericType; + } + + static void OverrideGenericParameterTypes( + ParameterInfo[] parameters, + Type[] typeGenericArgumentTypes, + Type[] typeParams) + { + foreach (ParameterInfo info in parameters) + { + info.ParameterType = OverrideGenericType( + info.ParameterType, + typeGenericArgumentTypes, + typeParams); + } + } + + static string[] OverrideGenericTypeNames( + string[] typeNames, + Type[] genericArgTypes, + Type[] typeParams) + { + int numParams = typeNames.Length; + string[] overriddenParamTypeNames = new string[numParams]; + for (int i = 0; i < numParams; ++i) + { + string typeName = typeNames[i]; + foreach (Type genericArgType in genericArgTypes) + { + if (CheckTypeNameMatches( + typeName, + genericArgType)) + { + typeName = typeParams[i].FullName; + break; + } + } + overriddenParamTypeNames[i] = typeName; + } + return overriddenParamTypeNames; + } + + static void AppendMethod( + Type enclosingType, + string methodName, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + bool methodIsStatic, + bool isReadOnly, + Type returnType, + TypeKind returnTypeKind, + Type[] enclosingTypeParams, + Type[] methodTypeParams, + ParameterInfo[] parameters, + bool generateDeclaration, + int indent, + Type[] exceptionTypes, + StringBuilders builders) + { + // Build uppercase function name + builders.TempStrBuilder.Length = 0; + AppendNamespace( + enclosingType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + enclosingType.Name, + builders.TempStrBuilder); + AppendTypeNames( + enclosingTypeParams, + builders.TempStrBuilder); + builders.TempStrBuilder.Append("Method"); + builders.TempStrBuilder.Append(methodName); + AppendTypeNames( + methodTypeParams, + builders.TempStrBuilder); + AppendParameterTypeNames( + parameters, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + // C# init param declaration + + // C# delegate type + AppendCsharpDelegateType( + funcName, + methodIsStatic, + enclosingType, + enclosingTypeKind, + returnType, + parameters, + builders.CsharpDelegateTypes); + + // C# init call param + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# function + AppendCsharpFunctionBeginning( + enclosingType, + funcName, + methodIsStatic, + enclosingTypeKind, + returnType, + parameters, + builders.CsharpFunctions); + if (methodName.StartsWith("op_")) + { + string op; + switch (methodName) + { + case "op_UnaryPlus": + op = "+"; + break; + case "op_UnaryNegation": + op = "-"; + break; + case "op_LogicalNot": + op = "!"; + break; + case "op_OnesComplement": + op = "~"; + break; + case "op_Increment": + op = "++"; + break; + case "op_Decrement": + op = "--"; + break; + case "op_Implicit": + op = string.Empty; + break; + case "op_Explicit": + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append('('); + AppendTypeNameWithoutGenericSuffix( + returnType.Name, + builders.TempStrBuilder); + builders.TempStrBuilder.Append(')'); + op = builders.TempStrBuilder.ToString(); + break; + case "op_True": + op = "(true)"; + break; + case "op_False": + op = "(false)"; + break; + case "op_Addition": + op = "+"; + break; + case "op_Subtraction": + op = "-"; + break; + case "op_Multiply": + op = "*"; + break; + case "op_Division": + op = "/"; + break; + case "op_Modulus": + op = "%"; + break; + case "op_BitwiseAnd": + op = "&"; + break; + case "op_BitwiseOr": + op = "|"; + break; + case "op_ExclusiveOr": + op = "^"; + break; + case "op_LeftShift": + op = "<<"; + break; + case "op_RightShift": + op = ">>"; + break; + case "op_Equality": + op = "=="; + break; + case "op_Inequality": + op = "!="; + break; + case "op_LessThan": + op = "<"; + break; + case "op_GreaterThan": + op = ">"; + break; + case "op_LessThanOrEqual": + op = "<="; + break; + case "op_GreaterThanOrEqual": + op = ">="; + break; + default: + throw new Exception( + "Unsupported overloaded operator: " + methodName); + } + switch (parameters.Length) + { + case 1: + builders.CsharpFunctions.Append(op); + builders.CsharpFunctions.Append(parameters[0].Name); + break; + case 2: + builders.CsharpFunctions.Append(parameters[0].Name); + builders.CsharpFunctions.Append(' '); + builders.CsharpFunctions.Append(op); + builders.CsharpFunctions.Append(' '); + builders.CsharpFunctions.Append(parameters[1].Name); + break; + default: + throw new Exception( + "Unsupported number of overloaded operator params: " + + parameters.Length); + } + } + else + { + AppendCsharpFunctionCallSubject( + enclosingType, + methodIsStatic, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('.'); + builders.CsharpFunctions.Append(methodName); + AppendCSharpTypeParameters( + methodTypeParams, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('('); + AppendCsharpFunctionCallParameters( + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(')'); + } + builders.CsharpFunctions.Append(';'); + if (!isReadOnly + && !methodIsStatic + && enclosingTypeKind == TypeKind.ManagedStruct) + { + AppendStructStoreReplace( + enclosingType, + "thisHandle", + "thiz", + builders.CsharpFunctions); + } + AppendCsharpFunctionReturn( + parameters, + returnType, + returnTypeKind, + exceptionTypes, + false, + builders.CsharpFunctions); + + // C++ function pointer + AppendCppFunctionPointerDefinition( + funcName, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + parameters, + returnType, + builders.CppFunctionPointers); + + // C++ method declaration + string cppMethodName; + bool cppMethodIsStatic; + ParameterInfo[] cppParameters; + ParameterInfo[] cppCallParameters; + Type cppReturnType = returnType; + if (methodName.StartsWith("op_")) + { + switch (methodName) + { + case "op_UnaryPlus": + cppMethodName = "operator+"; + break; + case "op_UnaryNegation": + cppMethodName = "operator-"; + break; + case "op_LogicalNot": + cppMethodName = "operator!"; + break; + case "op_OnesComplement": + cppMethodName = "operator~"; + break; + case "op_Increment": + cppMethodName = "operator++"; + break; + case "op_Decrement": + cppMethodName = "operator--"; + break; + case "op_Implicit": + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("operator "); + AppendCppTypeFullName( + returnType, + builders.TempStrBuilder); + cppMethodName = builders.TempStrBuilder.ToString(); + cppReturnType = null; + break; + case "op_Explicit": + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("explicit operator "); + AppendCppTypeFullName( + returnType, + builders.TempStrBuilder); + cppMethodName = builders.TempStrBuilder.ToString(); + cppReturnType = null; + break; + case "op_True": + cppMethodName = "TrueOperator"; + break; + case "op_False": + cppMethodName = "FalseOperator"; + break; + case "op_Addition": + cppMethodName = "operator+"; + break; + case "op_Subtraction": + cppMethodName = "operator-"; + break; + case "op_Multiply": + cppMethodName = "operator*"; + break; + case "op_Division": + cppMethodName = "operator/"; + break; + case "op_Modulus": + cppMethodName = "operator%"; + break; + case "op_BitwiseAnd": + cppMethodName = "operator&"; + break; + case "op_BitwiseOr": + cppMethodName = "operator|"; + break; + case "op_ExclusiveOr": + cppMethodName = "operator^"; + break; + case "op_LeftShift": + cppMethodName = "operator<<"; + break; + case "op_RightShift": + cppMethodName = "operator>>"; + break; + case "op_Equality": + cppMethodName = "operator=="; + break; + case "op_Inequality": + cppMethodName = "operator!="; + break; + case "op_LessThan": + cppMethodName = "operator<"; + break; + case "op_GreaterThan": + cppMethodName = "operator>"; + break; + case "op_LessThanOrEqual": + cppMethodName = "operator<="; + break; + case "op_GreaterThanOrEqual": + cppMethodName = "operator>="; + break; + default: + throw new Exception( + "Unsupported overloaded operator: " + methodName); + } + cppMethodIsStatic = false; + ParameterInfo thisParam; + switch (enclosingTypeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + thisParam = new ParameterInfo{ + Name = "Handle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }; + break; + default: + thisParam = new ParameterInfo{ + Name = "*this", + ParameterType = enclosingType, + DereferencedParameterType = enclosingType, + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }; + break; + } + switch (parameters.Length) + { + case 1: + cppParameters = new ParameterInfo[0]; + cppCallParameters = new [] { + thisParam }; + break; + case 2: + cppParameters = new [] { + parameters[0] }; + cppCallParameters = new [] { + thisParam, + parameters[0] + }; + break; + default: + throw new Exception( + "Unsupported number of overloaded operator parameters: " + + parameters.Length); + } + } + else + { + cppMethodName = methodName; + cppMethodIsStatic = methodIsStatic; + cppParameters = parameters; + cppCallParameters = parameters; + } + if (generateDeclaration) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppMethodName, + enclosingTypeIsStatic, + // Mark as virtual if method/class is not static or generic + cppMethodIsStatic || enclosingTypeIsStatic || methodTypeParams != null? false : true, + cppMethodIsStatic, + cppReturnType, + methodTypeParams, + cppParameters, + builders.CppTypeDefinitions); + } + + // C++ method definition + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), + cppReturnType, + cppMethodName, + enclosingTypeParams, + methodTypeParams, + cppParameters, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + enclosingTypeParams, + returnType, + funcName, + cppCallParameters, + indent + 1, + builders.CppMethodDefinitions); + AppendCppMethodReturn( + returnType, + returnTypeKind, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine("\t"); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + parameters, + returnType, + builders.CppInitBodyParameterReads); + } + + static void AppendCSharpTypeParameters( + Type[] typeParams, + StringBuilder output) + { + if (typeParams != null && typeParams.Length > 0) + { + output.Append('<'); + for (int i = 0; i < typeParams.Length; ++i) + { + Type typeParam = typeParams[i]; + AppendCsharpTypeFullName(typeParam, output); + if (i != typeParams.Length - 1) + { + output.Append(", "); + } + } + output.Append('>'); + } + } + + static void AppendCppTypeParameters( + Type[] typeParams, + StringBuilder output) + { + if (typeParams != null && typeParams.Length > 0) + { + output.Append('<'); + for (int i = 0; i < typeParams.Length; ++i) + { + Type typeParam = typeParams[i]; + AppendCppTypeFullName(typeParam, output); + if (i != typeParams.Length - 1) + { + output.Append(", "); + } + } + output.Append('>'); + } + } + + static void AppendCppFunctionCall( + string funcName, + ParameterInfo[] parameters, + Type returnType, + bool enclosingTypeIsStatic, + int indent, + StringBuilder output) + { + foreach (ParameterInfo param in parameters) + { + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + { + AppendIndent( + indent, + output); + output.Append("int "); + output.Append(param.Name); + output.Append("Handle = "); + AppendHandleStoreTypeName( + param.DereferencedParameterType, + output); + output.Append('.'); + if (param.Kind == TypeKind.Class) + { + output.Append("GetHandle"); + } + else + { + output.Append("Store"); + } + output.Append('('); + output.Append(param.Name); + output.AppendLine(");"); + } + } + if (!enclosingTypeIsStatic) + { + AppendIndent( + indent, + output); + output.AppendLine( + "int thisHandle = NativeScript.Bindings.ObjectStore.GetHandle(this);"); + } + AppendIndent( + indent, + output); + if (returnType != typeof(void)) + { + output.Append("var returnVal = "); + } + output.Append("NativeScript.Bindings."); + output.Append(funcName); + output.Append('('); + if (!enclosingTypeIsStatic) + { + output.Append("thisHandle"); + if (parameters.Length > 0) + { + output.Append(", "); + } + } + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo param = parameters[i]; + output.Append(param.Name); + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + { + output.Append("Handle"); + } + if (i != parameters.Length - 1) + { + output.Append(", "); + } + } + output.AppendLine(");"); + AppendIndent( + indent, + output); + output.AppendLine("if (NativeScript.Bindings.UnhandledCppException != null)"); + AppendIndent( + indent, + output); + output.AppendLine("{"); + AppendIndent( + indent + 1, + output); + output.AppendLine("Exception ex = NativeScript.Bindings.UnhandledCppException;"); + AppendIndent( + indent + 1, + output); + output.AppendLine("NativeScript.Bindings.UnhandledCppException = null;"); + AppendIndent( + indent + 1, + output); + output.AppendLine("throw ex;"); + AppendIndent( + indent, + output); + output.AppendLine("}"); + } + + static void AppendArray( + JsonArray jsonArray, + Assembly[] assemblies, + StringBuilders builders) + { + // Get element type + Type elementType = GetType( + jsonArray.Type, + assemblies); + TypeKind elementTypeKind = GetTypeKind(elementType); + + // Default ranks to just 1 + int[] ranks; + if (jsonArray.Ranks == null + || jsonArray.Ranks.Length == 0) + { + ranks = new[]{ 1 }; + } + else + { + ranks = jsonArray.Ranks; + } + + // C++ element proxy for [1-R] for all ranks R + Type[] cppTypeParams = { elementType }; + foreach (int rank in ranks) + { + // Build array name + builders.TempStrBuilder.Length = 0; + AppendCppArrayTypeName( + rank, + builders.TempStrBuilder); + string cppArrayTypeName = builders.TempStrBuilder.ToString(); + + for (int i = 1; i <= rank; ++i) + { + AppendArrayElementProxy( + elementType, + elementTypeKind, + i, + rank, + cppTypeParams, + cppArrayTypeName, + builders); + } + } + + foreach (int rank in ranks) + { + // Build array name + builders.TempStrBuilder.Length = 0; + AppendCppArrayTypeName( + rank, + builders.TempStrBuilder); + string cppArrayTypeName = builders.TempStrBuilder.ToString(); + + // Build array name with element type + builders.TempStrBuilder.Append('<'); + AppendCppTypeFullName( + elementType, + builders.TempStrBuilder); + builders.TempStrBuilder.Append('>'); + string cppGenericArrayTypeName = builders.TempStrBuilder.ToString(); + + // Build element proxy name + builders.TempStrBuilder.Length = 0; + AppendCppArrayElementProxyName( + 1, + rank, + elementType, + builders.TempStrBuilder); + string cppElementProxyTypeName = builders.TempStrBuilder.ToString(); + + // Build "TypeArray" name + builders.TempStrBuilder.Length = 0; + AppendNamespace( + elementType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + elementType.Name, + builders.TempStrBuilder); + builders.TempStrBuilder.Append(cppArrayTypeName); + string bindingArrayTypeName = builders.TempStrBuilder.ToString(); + + // MakeArrayType() creates a Type for a "vector" + // MakeArrayType(int) creates a Type for a multi-dimensional array + // Use MakeArrayType() instead of MakeArrayType(1) to create a vector + // instead of a multi-dimensional array with one dimension. + // This avoids problems like the name being "float[*]", which is + // invalid C# code. + Type arrayType; + if (rank == 1) + { + arrayType = elementType.MakeArrayType(); + } + else + { + arrayType = elementType.MakeArrayType(rank); + } + + // C++ type declaration + int indent = AppendCppTypeDeclaration( + GetTypeName(cppArrayTypeName, "System"), + false, + cppTypeParams, + builders.CppTemplateSpecializationDeclarations); + + // C++ type definition (beginning) + Type[] interfaceTypes = GetDirectInterfaces(arrayType); + AppendCppTypeDefinitionBegin( + GetTypeName(cppArrayTypeName, "System"), + TypeKind.Class, + cppTypeParams, + GetTypeName("Array", "System"), + null, + interfaceTypes, + false, + indent, + builders.CppTypeDefinitions); + + // C++ method definitions (beginning) + Type[] cppCtorInitTypes = GetCppCtorInitTypes( + arrayType, + false); + int localRank = rank; + int cppMethodDefinitionsIndent = AppendCppMethodDefinitionsBegin( + GetTypeName(cppArrayTypeName, "System"), + TypeKind.Class, + cppTypeParams, + cppCtorInitTypes, + false, + (extraIndent, subject) => { + AppendIndent( + extraIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(subject); + builders.CppMethodDefinitions.AppendLine( + "InternalLength = 0;"); + if (localRank > 1) + { + for (int i = 0; i < localRank; ++i) + { + AppendIndent( + extraIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(subject); + builders.CppMethodDefinitions.Append( + "InternalLengths["); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.AppendLine( + "] = 0;"); + } + } + }, + (extraIndent, subject) => { + AppendIndent( + extraIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append( + "InternalLength = "); + builders.CppMethodDefinitions.Append(subject); + builders.CppMethodDefinitions.AppendLine( + "InternalLength;"); + if (localRank > 1) + { + for (int i = 0; i < localRank; ++i) + { + AppendIndent( + extraIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append( + "InternalLengths["); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.Append( + "] = "); + builders.CppMethodDefinitions.Append(subject); + builders.CppMethodDefinitions.Append( + "InternalLengths["); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.AppendLine( + "];"); + } + } + }, + indent, + builders.CppMethodDefinitions); + + // C++ fields + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine( + "int32_t InternalLength;"); + if (rank > 1) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append( + "int32_t InternalLengths["); + builders.CppTypeDefinitions.Append(rank); + builders.CppTypeDefinitions.AppendLine("];"); + } + + AppendArrayConstructor( + elementType, + arrayType, + cppArrayTypeName, + rank, + bindingArrayTypeName, + cppCtorInitTypes, + indent, + builders); + + // Base GetLength + AppendArrayCppGetLengthFunction( + indent, + cppArrayTypeName, + cppTypeParams, + builders); + + // GetLength for multi-dimensional arrays + if (rank > 1) + { + AppendArrayMultidimensionalGetLength( + elementType, + arrayType, + cppArrayTypeName, + rank, + bindingArrayTypeName, + indent, + builders); + } + + AppendArrayCppGetRankFunction( + indent, + cppArrayTypeName, + cppTypeParams, + rank, + builders); + + AppendArrayGetItem( + elementType, + elementTypeKind, + arrayType, + cppArrayTypeName, + rank, + builders); + + AppendArraySetItem( + elementType, + arrayType, + cppArrayTypeName, + rank, + builders); + + // C++ operator[] method declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("Plugin::"); + AppendCppArrayElementProxyName( + 1, + rank, + elementType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append(' '); + AppendTypeNameWithoutGenericSuffix( + "operator[]", + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("(int32_t index);"); + + // C++ operator[] method definition + AppendCppArrayIndexOperatorMethodDefinition( + 0, + cppMethodDefinitionsIndent, + GetTypeName(cppGenericArrayTypeName, "System"), + cppElementProxyTypeName, + builders.CppMethodDefinitions); + + // C++ type definition (end) + AppendCppTypeDefinitionEnd( + false, + indent, + builders.CppTypeDefinitions); + + // C++ method definitions (ending) + AppendCppMethodDefinitionsEnd( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + if (rank == 1) + { + AppendArrayIterator( + elementType, + cppGenericArrayTypeName, + bindingArrayTypeName, + builders.CppTypeDefinitions, + builders.CppMethodDefinitions); + } + } + } + + static void AppendArrayIterator( + Type elementType, + string cppGenericArrayTypeName, + string bindingArrayTypeName, + StringBuilder cppTypeDefinitions, + StringBuilder cppMethodDefinitions) + { + // Iterator type definition + cppTypeDefinitions.AppendLine("namespace Plugin"); + cppTypeDefinitions.AppendLine("{"); + cppTypeDefinitions.Append("\tstruct "); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.AppendLine("Iterator"); + cppTypeDefinitions.AppendLine("\t{"); + cppTypeDefinitions.Append("\t\tSystem::"); + cppTypeDefinitions.Append(cppGenericArrayTypeName); + cppTypeDefinitions.AppendLine("& array;"); + cppTypeDefinitions.AppendLine("\t\tint index;"); + cppTypeDefinitions.Append("\t\t"); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.Append("Iterator(System::"); + cppTypeDefinitions.Append(cppGenericArrayTypeName); + cppTypeDefinitions.AppendLine("& array, int32_t index);"); + cppTypeDefinitions.Append("\t\t"); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.AppendLine("Iterator& operator++();"); + cppTypeDefinitions.Append("\t\tbool operator!=(const "); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.AppendLine("Iterator& other);"); + cppTypeDefinitions.Append("\t\t"); + AppendCppTypeFullName( + elementType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine(" operator*();"); + cppTypeDefinitions.AppendLine("\t};"); + cppTypeDefinitions.AppendLine("}"); + cppTypeDefinitions.AppendLine();; + + // begin() and end() declarations + cppTypeDefinitions.AppendLine("namespace System"); + cppTypeDefinitions.AppendLine("{"); + cppTypeDefinitions.Append("\tPlugin::"); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.Append("Iterator begin(System::"); + cppTypeDefinitions.Append(cppGenericArrayTypeName); + cppTypeDefinitions.AppendLine("& array);"); + cppTypeDefinitions.Append("\tPlugin::"); + cppTypeDefinitions.Append(bindingArrayTypeName); + cppTypeDefinitions.Append("Iterator end(System::"); + cppTypeDefinitions.Append(cppGenericArrayTypeName); + cppTypeDefinitions.AppendLine("& array);"); + cppTypeDefinitions.AppendLine("}"); + cppTypeDefinitions.AppendLine();; + + // Iterator method definitions + cppMethodDefinitions.AppendLine("namespace Plugin"); + cppMethodDefinitions.AppendLine("{"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator(System::"); + cppMethodDefinitions.Append(cppGenericArrayTypeName); + cppMethodDefinitions.AppendLine("& array, int32_t index)"); + cppMethodDefinitions.AppendLine("\t\t: array(array)"); + cppMethodDefinitions.AppendLine("\t\t, index(index)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator& "); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.AppendLine("operator++()"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\tindex++;"); + cppMethodDefinitions.AppendLine("\t\treturn *this;"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append("\tbool "); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.Append("operator!=(const "); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.AppendLine("Iterator& other)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\treturn index != other.index;"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + AppendCppTypeFullName( + elementType, + cppMethodDefinitions); + cppMethodDefinitions.Append(' '); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.AppendLine("operator*()"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\treturn array[index];"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("}"); + cppMethodDefinitions.AppendLine();; + + // begin() and end() definitions + cppMethodDefinitions.AppendLine("namespace System"); + cppMethodDefinitions.AppendLine("{"); + cppMethodDefinitions.Append("\tPlugin::"); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator begin(System::"); + cppMethodDefinitions.Append(cppGenericArrayTypeName); + cppMethodDefinitions.AppendLine("& array)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.Append("\t\treturn Plugin::"); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.AppendLine("Iterator(array, 0);"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append("\tPlugin::"); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.Append("Iterator end(System::"); + cppMethodDefinitions.Append(cppGenericArrayTypeName); + cppMethodDefinitions.AppendLine("& array)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.Append("\t\treturn Plugin::"); + cppMethodDefinitions.Append(bindingArrayTypeName); + cppMethodDefinitions.AppendLine("Iterator(array, array.GetLength() - 1);"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("}"); + cppMethodDefinitions.AppendLine();; + } + + static void AppendGenericEnumerableIterator( + Type enumerableType, + Type enumeratorType, + Type elementType, + string bindingEnumerableTypeName, + StringBuilder cppTypeDefinitions, + StringBuilder cppMethodDefinitions) + { + // Iterator type definition + cppTypeDefinitions.AppendLine("namespace Plugin"); + cppTypeDefinitions.AppendLine("{"); + cppTypeDefinitions.Append("\tstruct "); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.AppendLine("Iterator"); + cppTypeDefinitions.AppendLine("\t{"); + cppTypeDefinitions.Append("\t\t"); + AppendCppTypeFullName( + enumeratorType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine(" enumerator;"); + cppTypeDefinitions.AppendLine("\t\tbool hasMore;"); + cppTypeDefinitions.Append("\t\t"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.AppendLine("Iterator(decltype(nullptr));"); + cppTypeDefinitions.Append("\t\t"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.Append("Iterator("); + AppendCppTypeFullName( + enumerableType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine("& enumerable);"); + cppTypeDefinitions.Append("\t\t~"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.AppendLine("Iterator();"); + cppTypeDefinitions.Append("\t\t"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.AppendLine("Iterator& operator++();"); + cppTypeDefinitions.Append("\t\tbool operator!=(const "); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.AppendLine("Iterator& other);"); + cppTypeDefinitions.Append("\t\t"); + AppendCppTypeFullName( + elementType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine(" operator*();"); + cppTypeDefinitions.AppendLine("\t};"); + cppTypeDefinitions.AppendLine("}"); + cppTypeDefinitions.AppendLine();; + + // begin() and end() declarations + int indent = AppendNamespaceBeginning( + enumerableType.Namespace, + cppTypeDefinitions); + AppendIndent( + indent, + cppTypeDefinitions); + cppTypeDefinitions.Append("Plugin::"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.Append("Iterator begin("); + AppendCppTypeFullName( + enumerableType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine("& enumerable);"); + AppendIndent( + indent, + cppTypeDefinitions); + cppTypeDefinitions.Append("Plugin::"); + cppTypeDefinitions.Append(bindingEnumerableTypeName); + cppTypeDefinitions.Append("Iterator end("); + AppendCppTypeFullName( + enumerableType, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine("& enumerable);"); + AppendNamespaceEnding( + indent, + cppTypeDefinitions); + cppTypeDefinitions.AppendLine();; + + // Iterator method definitions + cppMethodDefinitions.AppendLine("namespace Plugin"); + cppMethodDefinitions.AppendLine("{"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.AppendLine("Iterator(decltype(nullptr))"); + cppMethodDefinitions.AppendLine("\t\t: enumerator(nullptr)"); + cppMethodDefinitions.AppendLine("\t\t, hasMore(false)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator("); + AppendCppTypeFullName( + enumerableType, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("& enumerable)"); + cppMethodDefinitions.AppendLine("\t\t: enumerator(enumerable.GetEnumerator())"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\thasMore = enumerator.MoveNext();"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::~"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.AppendLine("Iterator()"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\tif (enumerator != nullptr)"); + cppMethodDefinitions.AppendLine("\t\t{"); + cppMethodDefinitions.AppendLine("\t\t\tenumerator.Dispose();"); + cppMethodDefinitions.AppendLine("\t\t}"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator& "); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.AppendLine("operator++()"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\thasMore = enumerator.MoveNext();"); + cppMethodDefinitions.AppendLine("\t\treturn *this;"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append("\tbool "); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.Append("operator!=(const "); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.AppendLine("Iterator& other)"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\treturn hasMore;"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("\t"); + cppMethodDefinitions.Append('\t'); + AppendCppTypeFullName( + elementType, + cppMethodDefinitions); + cppMethodDefinitions.Append(' '); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator::"); + cppMethodDefinitions.AppendLine("operator*()"); + cppMethodDefinitions.AppendLine("\t{"); + cppMethodDefinitions.AppendLine("\t\treturn enumerator.GetCurrent();"); + cppMethodDefinitions.AppendLine("\t}"); + cppMethodDefinitions.AppendLine("}"); + cppMethodDefinitions.AppendLine();; + + // begin() and end() definitions + indent = AppendNamespaceBeginning( + enumerableType.Namespace, + cppMethodDefinitions); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.Append("Plugin::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator begin("); + AppendCppTypeFullName( + enumerableType, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("& enumerable)"); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + cppMethodDefinitions); + cppMethodDefinitions.Append("return Plugin::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.AppendLine("Iterator(enumerable);"); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine();; + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.Append("Plugin::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.Append("Iterator end("); + AppendCppTypeFullName( + enumerableType, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("& enumerable)"); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + cppMethodDefinitions); + cppMethodDefinitions.Append("return Plugin::"); + cppMethodDefinitions.Append(bindingEnumerableTypeName); + cppMethodDefinitions.AppendLine("Iterator(nullptr);"); + AppendIndent( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine("}"); + AppendNamespaceEnding( + indent, + cppMethodDefinitions); + cppMethodDefinitions.AppendLine();; + } + + static void AppendCppArrayIndexOperatorMethodDefinition( + int rank, + int indent, + TypeName enclosingTypeTypeName, + string nextCppElementProxyTypeName, + StringBuilder output) + { + AppendIndent( + indent, + output); + AppendCppTypeFullName( + GetTypeName(nextCppElementProxyTypeName, "Plugin"), + output); + output.Append(' '); + output.Append(enclosingTypeTypeName.Namespace); + output.Append("::"); + AppendTypeNameWithoutGenericSuffix( + enclosingTypeTypeName.Name, + output); + output.AppendLine("::operator[](int32_t index)"); + AppendIndent( + indent, + output); + output.AppendLine("{"); + AppendIndent( + indent + 1, + output); + output.Append("return Plugin::"); + output.Append(nextCppElementProxyTypeName); + output.Append("(Plugin::InternalUse::Only, Handle, "); + for (int i = 0; i < rank; ++i) + { + output.Append("Index"); + output.Append(i); + output.Append(", "); + } + output.AppendLine("index);"); + AppendIndent( + indent, + output); + output.AppendLine("}"); + AppendIndent( + indent, + output); + output.AppendLine();; + } + + static void AppendCppArrayTypeName( + int rank, + StringBuilder output) + { + output.Append("Array"); + output.Append(rank); + } + + static void AppendCppArrayElementProxyName( + int rank, + int maxRank, + Type elementType, + StringBuilder output) + { + output.Append("ArrayElementProxy"); + output.Append(rank); + output.Append('_'); + output.Append(maxRank); + output.Append('<'); + AppendCppTypeFullName( + elementType, + output); + output.Append('>'); + } + + static ParameterInfo[] BuildArrayGetItemsParams( + int rank, + string indexName) + { + ParameterInfo[] parameters = new ParameterInfo[rank]; + for (int i = 0; i < rank; ++i) + { + ParameterInfo param = new ParameterInfo(); + param.Name = indexName + i; + param.ParameterType = typeof(int); + param.IsOut = false; + param.IsRef = false; + param.DereferencedParameterType = param.ParameterType; + param.Kind = GetTypeKind( + param.DereferencedParameterType); + parameters[i] = param; + } + return parameters; + } + + static ParameterInfo[] BuildArraySetItemsParams( + int rank, + string indexName, + Type elementType) + { + ParameterInfo[] parameters = new ParameterInfo[rank+1]; + for (int i = 0; i < rank; ++i) + { + ParameterInfo param = new ParameterInfo(); + param.Name = indexName + i; + param.ParameterType = typeof(int); + param.IsOut = false; + param.IsRef = false; + param.DereferencedParameterType = param.ParameterType; + param.Kind = GetTypeKind( + param.DereferencedParameterType); + parameters[i] = param; + } + + ParameterInfo lastParamInfo = new ParameterInfo(); + lastParamInfo.Name = "item"; + lastParamInfo.ParameterType = elementType; + lastParamInfo.IsOut = false; + lastParamInfo.IsRef = false; + lastParamInfo.DereferencedParameterType = lastParamInfo.ParameterType; + lastParamInfo.Kind = GetTypeKind( + lastParamInfo.DereferencedParameterType); + parameters[rank] = lastParamInfo; + + return parameters; + } + + static void AppendArrayGetItemFuncName( + TypeName elementTypeTypeName, + string bindingArrayTypeName, + int rank, + StringBuilder output) + { + AppendNamespace( + elementTypeTypeName.Namespace, + string.Empty, + output); + output.Append(elementTypeTypeName.Name); + AppendTypeNameWithoutGenericSuffix( + bindingArrayTypeName, + output); + output.Append("GetItem"); + output.Append(rank); + } + + static void AppendArraySetItemFuncName( + TypeName elementTypeTypeName, + string bindingArrayTypeName, + int rank, + StringBuilder output) + { + AppendNamespace( + elementTypeTypeName.Namespace, + string.Empty, + output); + output.Append(elementTypeTypeName.Name); + AppendTypeNameWithoutGenericSuffix( + bindingArrayTypeName, + output); + output.Append("SetItem"); + output.Append(rank); + } + + static void AppendArrayElementProxy( + Type elementType, + TypeKind elementTypeKind, + int rank, + int maxRank, + Type[] cppTypeParams, + string cppArrayTypeName, + StringBuilders builders) + { + // Build element proxy name + builders.TempStrBuilder.Length = 0; + AppendCppArrayElementProxyName( + rank, + maxRank, + elementType, + builders.TempStrBuilder); + string cppElementProxyTypeName = builders.TempStrBuilder.ToString(); + + // Build next element proxy name + builders.TempStrBuilder.Length = 0; + AppendCppArrayElementProxyName( + rank + 1, + maxRank, + elementType, + builders.TempStrBuilder); + string nextCppElementProxyTypeName = builders.TempStrBuilder.ToString(); + + // GetItem name + builders.TempStrBuilder.Length = 0; + AppendArrayGetItemFuncName( + GetTypeName(elementType), + cppArrayTypeName, + rank, + builders.TempStrBuilder); + string getItemFuncName = builders.TempStrBuilder.ToString(); + + // SetItem name + builders.TempStrBuilder.Length = 0; + AppendArraySetItemFuncName( + GetTypeName(elementType), + cppArrayTypeName, + rank, + builders.TempStrBuilder); + string setItemFuncName = builders.TempStrBuilder.ToString(); + + // GetItem call params + ParameterInfo[] getItemCallParams = BuildArrayGetItemsParams( + rank, + "Index"); + + // SetItem params + ParameterInfo[] setItemCallParams = BuildArraySetItemsParams( + rank, + "Index", + elementType); + + // C++ element proxy type declaration + int indent = AppendNamespaceBeginning( + "Plugin", + builders.CppTemplateSpecializationDeclarations); + AppendIndent(indent, builders.CppTemplateSpecializationDeclarations); + builders.CppTemplateSpecializationDeclarations.Append("template<> struct "); + AppendTypeNameWithoutGenericSuffix( + cppElementProxyTypeName, + builders.CppTemplateSpecializationDeclarations); + builders.CppTemplateSpecializationDeclarations.AppendLine(";"); + AppendNamespaceEnding( + indent, + builders.CppTemplateSpecializationDeclarations); + builders.CppTemplateSpecializationDeclarations.AppendLine();; + + // C++ element proxy type definition + AppendNamespaceBeginning( + "Plugin", + builders.CppTypeDefinitions); + AppendIndent( + indent, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("template<> struct "); + builders.CppTypeDefinitions.Append(cppElementProxyTypeName); + builders.CppTypeDefinitions.AppendLine();; + AppendIndent( + indent, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("int32_t Handle;"); + for (int i = 0; i < rank; ++i) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("int32_t Index"); + builders.CppTypeDefinitions.Append(i); + builders.CppTypeDefinitions.AppendLine(";"); + } + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append(cppElementProxyTypeName); + builders.CppTypeDefinitions.Append( + "(Plugin::InternalUse, int32_t handle, "); + for (int i = 0; i < rank; ++i) + { + builders.CppTypeDefinitions.Append("int32_t index"); + builders.CppTypeDefinitions.Append(i); + if (i != rank - 1) + { + builders.CppTypeDefinitions.Append(", "); + } + } + builders.CppTypeDefinitions.AppendLine(");"); + if (rank == maxRank) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("void operator=("); + AppendCppTypeFullName( + elementType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine(" item);"); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("operator "); + AppendCppTypeFullName( + elementType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("();"); + } + else + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append("Plugin::"); + AppendCppArrayElementProxyName( + rank + 1, + maxRank, + elementType, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.Append(" operator[]("); + builders.CppTypeDefinitions.AppendLine("int32_t index);"); + } + AppendIndent( + indent, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("};"); + builders.CppTypeDefinitions.AppendLine("}"); + builders.CppTypeDefinitions.AppendLine();; + + // C++ element proxy method definitions (beginning) + int cppMethodDefinitionsIndent = AppendNamespaceBeginning( + "Plugin", + builders.CppMethodDefinitions); + + // C++ element proxy constructor definition + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(cppElementProxyTypeName); + builders.CppMethodDefinitions.Append( + "::ArrayElementProxy"); + builders.CppMethodDefinitions.Append(rank); + builders.CppMethodDefinitions.Append('_'); + builders.CppMethodDefinitions.Append(maxRank); + builders.CppMethodDefinitions.Append( + "(Plugin::InternalUse, int32_t handle, "); + for (int i = 0; i < rank; ++i) + { + builders.CppMethodDefinitions.Append("int32_t index"); + builders.CppMethodDefinitions.Append(i); + if (i != rank - 1) + { + builders.CppMethodDefinitions.Append(", "); + } + } + builders.CppMethodDefinitions.AppendLine(")"); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("Handle = handle;"); + for (int i = 0; i < rank; ++i) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("Index"); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.Append(" = index"); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.AppendLine(";"); + } + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + if (rank == maxRank) + { + // C++ element proxy operator= definition + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("void "); + builders.CppMethodDefinitions.Append(cppElementProxyTypeName); + builders.CppMethodDefinitions.Append("::"); + builders.CppMethodDefinitions.Append("operator=("); + AppendCppTypeFullName( + elementType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(" item)"); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + false, + GetTypeName(cppArrayTypeName, "System"), + TypeKind.Class, + cppTypeParams, + typeof(void), + setItemFuncName, + setItemCallParams, + cppMethodDefinitionsIndent + 1, + builders.CppMethodDefinitions); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C++ element proxy type conversion operator definition + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(cppElementProxyTypeName); + builders.CppMethodDefinitions.Append("::"); + builders.CppMethodDefinitions.Append("operator "); + AppendCppTypeFullName( + elementType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("()"); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + false, + GetTypeName(cppArrayTypeName, "System"), + TypeKind.Class, + cppTypeParams, + elementType, + getItemFuncName, + getItemCallParams, + indent + 1, + builders.CppMethodDefinitions); + AppendCppMethodReturn( + elementType, + elementTypeKind, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + } + else + { + AppendCppArrayIndexOperatorMethodDefinition( + rank, + cppMethodDefinitionsIndent, + GetTypeName(cppElementProxyTypeName, "Plugin"), + nextCppElementProxyTypeName, + builders.CppMethodDefinitions); + } + + // C++ method definitions (ending) + AppendCppMethodDefinitionsEnd( + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + } + + static void AppendArrayConstructor( + Type elementType, + Type arrayType, + string cppArrayTypeName, + int rank, + string csharpTypeName, + Type[] cppCtorInitTypes, + int indent, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendNamespace( + elementType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + csharpTypeName, + builders.TempStrBuilder); + builders.TempStrBuilder.Append("Constructor"); + builders.TempStrBuilder.Append(rank); + string funcName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] parameters = new ParameterInfo[rank]; + for (int i = 0; i < rank; ++i) + { + ParameterInfo info = new ParameterInfo(); + info.Name = "length" + i; + info.ParameterType = typeof(int); + info.IsOut = false; + info.IsRef = false; + info.DereferencedParameterType = info.ParameterType; + info.Kind = TypeKind.Primitive; + parameters[i] = info; + } + + TypeName cppArrayTypeTypeName = GetTypeName( + cppArrayTypeName, + "System"); + + // C# Delegate Type + AppendCsharpDelegateType( + funcName, + true, + arrayType, + TypeKind.Class, + arrayType, + parameters, + builders.CsharpDelegateTypes); + + // C# Init Call + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# Init Param + + // C# function + AppendCsharpFunctionBeginning( + arrayType, + funcName, + true, + TypeKind.Class, + arrayType, + parameters, + builders.CsharpFunctions); + AppendHandleStoreTypeName( + arrayType, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(".Store(new "); + AppendCsharpTypeFullName( + elementType, + builders.CsharpFunctions); + builders.CsharpFunctions.Append('['); + for (int i = 0; i < rank; ++i) + { + builders.CsharpFunctions.Append("length"); + builders.CsharpFunctions.Append(i); + if (i != rank-1) + { + builders.CsharpFunctions.Append(", "); + } + } + builders.CsharpFunctions.Append("]);"); + AppendCsharpFunctionReturn( + parameters, + arrayType, + TypeKind.Class, + null, + true, + builders.CsharpFunctions); + + // C++ function pointer definition + AppendCppFunctionPointerDefinition( + funcName, + true, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppFunctionPointers); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + true, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppInitBodyParameterReads); + + // C++ method declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppArrayTypeName, + false, + false, + false, + null, + null, + parameters, + builders.CppTypeDefinitions); + + // C++ method definition + Type[] cppTypeParams = { elementType }; + AppendCppMethodDefinitionBegin( + GetTypeName(cppArrayTypeName, "System"), + null, + cppArrayTypeName, + cppTypeParams, + null, + parameters, + indent, + builders.CppMethodDefinitions); + string separator = ": "; + foreach (Type interfaceType in cppCtorInitTypes) + { + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(separator); + AppendCppTypeFullName( + interfaceType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("(nullptr)"); + separator = ", "; + } + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + true, + cppArrayTypeTypeName, + TypeKind.Class, + cppTypeParams, + arrayType, + funcName, + parameters, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "Handle = returnValue;"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "if (returnValue)"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "{"); + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + AppendReferenceManagedHandleFunctionCall( + cppArrayTypeTypeName, + TypeKind.Class, + cppTypeParams, + "returnValue", + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(";"); + if (rank > 1) + { + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("InternalLength = "); + for (int i = 0; i < rank; ++i) + { + builders.CppMethodDefinitions.Append("length"); + builders.CppMethodDefinitions.Append(i); + if (i != rank - 1) + { + builders.CppMethodDefinitions.Append(" * "); + } + } + builders.CppMethodDefinitions.AppendLine(";"); + for (int i = 0; i < rank; ++i) + { + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("InternalLengths["); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.Append("] = length"); + builders.CppMethodDefinitions.Append(i); + builders.CppMethodDefinitions.AppendLine(";"); + } + } + else + { + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "InternalLength = length0;"); + } + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendArrayCppGetLengthFunction( + int indent, + string cppArrayTypeName, + Type[] cppTypeParams, + StringBuilders builders) + { + ParameterInfo[] parameters = new ParameterInfo[0]; + + // C++ method declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + "GetLength", + false, + false, + false, + typeof(int), + null, + parameters, + builders.CppTypeDefinitions); + + // C++ method definition + AppendCppMethodDefinitionBegin( + GetTypeName(cppArrayTypeName, "System"), + typeof(int), + "GetLength", + cppTypeParams, + null, + parameters, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "int32_t returnVal = InternalLength;"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("if (returnVal == 0)"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "returnVal = Array::GetLength();"); + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "InternalLength = returnVal;"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("};"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return returnVal;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendArrayCppGetRankFunction( + int indent, + string cppArrayTypeName, + Type[] cppTypeParams, + int rank, + StringBuilders builders) + { + ParameterInfo[] parameters = new ParameterInfo[0]; + + // C++ method declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + "GetRank", + false, + false, + false, + typeof(int), + null, + parameters, + builders.CppTypeDefinitions); + + // C++ method definition + AppendCppMethodDefinitionBegin( + GetTypeName(cppArrayTypeName, "System"), + typeof(int), + "GetRank", + cppTypeParams, + null, + parameters, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("return "); + builders.CppMethodDefinitions.Append(rank); + builders.CppMethodDefinitions.AppendLine(";"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendArrayMultidimensionalGetLength( + Type elementType, + Type arrayType, + string cppArrayTypeName, + int rank, + string csharpTypeName, + int indent, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendNamespace( + elementType.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutGenericSuffix( + csharpTypeName, + builders.TempStrBuilder); + builders.TempStrBuilder.Append("GetLength"); + builders.TempStrBuilder.Append(rank); + string funcName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] parameters = { + new ParameterInfo { + Name = "dimension", + ParameterType = typeof(int), + IsOut = false, + IsRef = false, + DereferencedParameterType = typeof(int), + Kind = TypeKind.Primitive, + } + }; + + TypeName cppArrayTypeTypeName = GetTypeName( + cppArrayTypeName, + "System"); + + // C# Delegate Type + AppendCsharpDelegateType( + funcName, + false, + arrayType, + TypeKind.Class, + typeof(int), + parameters, + builders.CsharpDelegateTypes); + + // C# Init Call + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# Init Param + + // C# function + AppendCsharpFunctionBeginning( + arrayType, + funcName, + false, + TypeKind.Class, + typeof(int), + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append( + "thiz.GetLength(dimension);"); + AppendCsharpFunctionReturn( + parameters, + typeof(int), + TypeKind.Primitive, + null, + false, + builders.CsharpFunctions); + + // C++ function pointer definition + AppendCppFunctionPointerDefinition( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppFunctionPointers); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppInitBodyParameterReads); + + // C++ method declaration + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + "GetLength", + false, + false, + false, + typeof(int), + null, + parameters, + builders.CppTypeDefinitions); + + // C++ method definition + Type[] cppTypeParams = { elementType }; + AppendCppMethodDefinitionBegin( + GetTypeName(cppArrayTypeName, "System"), + typeof(int), + "GetLength", + cppTypeParams, + null, + parameters, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append( + "assert(dimension >= 0 && dimension < "); + builders.CppMethodDefinitions.Append(rank); + builders.CppMethodDefinitions.AppendLine(");"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "int32_t length = InternalLengths[dimension];"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("if (length)"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return length;"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendCppPluginFunctionCall( + false, + GetTypeName(cppArrayTypeName, "System"), + TypeKind.Class, + cppTypeParams, + typeof(int), + funcName, + parameters, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine( + "InternalLengths[dimension] = returnValue;"); + AppendCppMethodReturn( + typeof(int), + TypeKind.Primitive, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + } + + static void AppendArrayGetItem( + Type elementType, + TypeKind elementTypeKind, + Type arrayType, + string cppArrayTypeName, + int rank, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendArrayGetItemFuncName( + GetTypeName(elementType), + cppArrayTypeName, + rank, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] parameters = BuildArrayGetItemsParams( + rank, + "index"); + + // C# Delegate Type + AppendCsharpDelegateType( + funcName, + false, + arrayType, + TypeKind.Class, + elementType, + parameters, + builders.CsharpDelegateTypes); + + // C# Init Call + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# Init Param + + // C# function + AppendCsharpFunctionBeginning( + arrayType, + funcName, + false, + TypeKind.Class, + elementType, + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("thiz["); + for (int i = 0; i < rank; ++i) + { + builders.CsharpFunctions.Append("index"); + builders.CsharpFunctions.Append(i); + if (i != rank-1) + { + builders.CsharpFunctions.Append(", "); + } + } + builders.CsharpFunctions.Append("];"); + AppendCsharpFunctionReturn( + parameters, + elementType, + elementTypeKind, + null, + false, + builders.CsharpFunctions); + + TypeName cppArrayTypeTypeName = GetTypeName( + "System", + cppArrayTypeName); + + // C++ function pointer definition + AppendCppFunctionPointerDefinition( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + elementType, + builders.CppFunctionPointers); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + elementType, + builders.CppInitBodyParameterReads); + } + + static void AppendArraySetItem( + Type elementType, + Type arrayType, + string cppArrayTypeName, + int rank, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendArraySetItemFuncName( + GetTypeName(elementType), + cppArrayTypeName, + rank, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + // Build parameters as indexes then element + ParameterInfo[] parameters = BuildArraySetItemsParams( + rank, + "index", + elementType); + + // C# Delegate Type + AppendCsharpDelegateType( + funcName, + false, + arrayType, + TypeKind.Class, + typeof(void), + parameters, + builders.CsharpDelegateTypes); + + // C# Init Call + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C# Init Param + + // C# function + AppendCsharpFunctionBeginning( + arrayType, + funcName, + false, + TypeKind.Class, + typeof(void), + parameters, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("thiz["); + for (int i = 0; i < rank; ++i) + { + builders.CsharpFunctions.Append("index"); + builders.CsharpFunctions.Append(i); + if (i != rank-1) + { + builders.CsharpFunctions.Append(", "); + } + } + builders.CsharpFunctions.Append("] = item;"); + AppendCsharpFunctionReturn( + parameters, + typeof(void), + TypeKind.None, + null, + false, + builders.CsharpFunctions); + + TypeName cppArrayTypeTypeName = GetTypeName( + "System", + cppArrayTypeName); + + // C++ function pointer definition + AppendCppFunctionPointerDefinition( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppFunctionPointers); + + // C++ init body + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + false, + cppArrayTypeTypeName, + TypeKind.Class, + parameters, + arrayType, + builders.CppInitBodyParameterReads); + } + + static void AppendDelegate( + JsonDelegate jsonDelegate, + Assembly[] assemblies, + int defaultMaxSimultaneous, + StringBuilders builders) + { + Type type = GetType( + jsonDelegate.Type, + assemblies); + if (jsonDelegate.GenericParams != null) + { + for (int i = 0; i < jsonDelegate.GenericParams.Length; ++i) + { + // C++ template declaration + AppendCppTemplateDeclaration( + GetTypeName(type), + builders.CppTemplateDeclarations); + } + + foreach (JsonGenericParams jsonGenericParams + in jsonDelegate.GenericParams) + { + Type[] typeParams = GetTypes( + jsonGenericParams.Types, + assemblies); + Type genericType = type.MakeGenericType(typeParams); + + // Build numbered C++ class name (e.g. Action_2) + builders.TempStrBuilder.Length = 0; + AppendTypeNameWithoutSuffixes( + type.Name, + builders.TempStrBuilder); + builders.TempStrBuilder.Append('_'); + builders.TempStrBuilder.Append( + jsonGenericParams.Types.Length); + string cppTypeName = builders.TempStrBuilder.ToString(); + + // Max simultaneous handles of this type + int maxSimultaneous = jsonGenericParams.MaxSimultaneous != 0 + ? jsonGenericParams.MaxSimultaneous + : jsonDelegate.MaxSimultaneous != 0 + ? jsonDelegate.MaxSimultaneous + : defaultMaxSimultaneous; + + AppendDelegate( + genericType, + cppTypeName, + typeParams, + maxSimultaneous, + builders); + } + } + else + { + int maxSimultaneous = jsonDelegate.MaxSimultaneous != 0 + ? jsonDelegate.MaxSimultaneous + : defaultMaxSimultaneous; + AppendDelegate( + type, + type.Name, + null, + maxSimultaneous, + builders); + } + } + + static void AppendDelegate( + Type type, + string cppTypeName, + Type[] typeParams, + int maxSimultaneous, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + AppendNamespace( + type.Namespace, + string.Empty, + builders.TempStrBuilder); + AppendTypeNameWithoutSuffixes( + type.Name, + builders.TempStrBuilder); + AppendTypeNames( + typeParams, + builders.TempStrBuilder); + string bindingTypeName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Release"); + builders.TempStrBuilder.Append(bindingTypeName); + string releaseFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(bindingTypeName); + builders.TempStrBuilder.Append("Constructor"); + string constructorFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(bindingTypeName); + builders.TempStrBuilder.Append("Add"); + string addFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(bindingTypeName); + builders.TempStrBuilder.Append("Remove"); + string removeFuncName = builders.TempStrBuilder.ToString(); + + TypeName typeTypeName = GetTypeName(type); + + // C++ type declaration + int indent = AppendCppTypeDeclaration( + typeTypeName, + false, + typeParams, + typeParams != null ? + builders.CppTemplateSpecializationDeclarations : + builders.CppTypeDeclarations); + + ParameterInfo[] addRemoveParams = { + new ParameterInfo + { + Name = "del", + ParameterType = type, + DereferencedParameterType = type, + IsOut = false, + IsRef = false, + Kind = TypeKind.Class, + IsVirtual = true + }}; + + ParameterInfo[] releaseParams = { + new ParameterInfo + { + Name = "handle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }, + new ParameterInfo + { + Name = "classHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }}; + + ParameterInfo[] constructorParams = { + new ParameterInfo + { + Name = "cppHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }, + new ParameterInfo + { + Name = "handle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = true, + IsRef = false, + Kind = TypeKind.Primitive + }, + new ParameterInfo + { + Name = "classHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = true, + IsRef = false, + Kind = TypeKind.Primitive + }}; + + AppendCppPointerFreeListStateAndFunctions( + GetTypeName(cppTypeName, type.Namespace), + typeParams, + bindingTypeName, + builders.CppGlobalStateAndFunctions); + + AppendCppPointerFreeListInit( + typeParams, + GetTypeName(cppTypeName, type.Namespace), + maxSimultaneous, + bindingTypeName, + builders.CppInitBodyArrays, + builders.CppInitBodyFirstBoot); + + // C++ type definition (begin) + AppendCppTypeDefinitionBegin( + GetTypeName(cppTypeName, type.Namespace), + TypeKind.Class, + typeParams, + GetTypeName(typeof(object)), + null, + null, + false, + indent, + builders.CppTypeDefinitions); + + // C++ type fields + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("int32_t CppHandle;"); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("int32_t ClassHandle;"); + + // C++ method declarations + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppTypeName, + false, + false, + false, + null, + null, + new ParameterInfo[0], + builders.CppTypeDefinitions); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + "operator+=", + false, + false, + false, + typeof(void), + null, + addRemoveParams, + builders.CppTypeDefinitions); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + "operator-=", + false, + false, + false, + typeof(void), + null, + addRemoveParams, + builders.CppTypeDefinitions); + + // C++ function pointers + AppendCppFunctionPointerDefinition( + releaseFuncName, + true, + default(TypeName), + TypeKind.None, + releaseParams, + typeof(void), + builders.CppFunctionPointers); + AppendCppFunctionPointerDefinition( + constructorFuncName, + true, + default(TypeName), + TypeKind.None, + constructorParams, + typeof(void), + builders.CppFunctionPointers); + AppendCppFunctionPointerDefinition( + addFuncName, + false, + default(TypeName), + TypeKind.None, + addRemoveParams, + typeof(void), + builders.CppFunctionPointers); + AppendCppFunctionPointerDefinition( + removeFuncName, + false, + default(TypeName), + TypeKind.None, + addRemoveParams, + typeof(void), + builders.CppFunctionPointers); + + // C++ and C# init params + AppendCppInitBodyFunctionPointerParameterRead( + releaseFuncName, + true, + default(TypeName), + TypeKind.None, + releaseParams, + typeof(void), + builders.CppInitBodyParameterReads); + AppendCppInitBodyFunctionPointerParameterRead( + constructorFuncName, + true, + default(TypeName), + TypeKind.None, + constructorParams, + typeof(void), + builders.CppInitBodyParameterReads); + AppendCppInitBodyFunctionPointerParameterRead( + addFuncName, + false, + default(TypeName), + TypeKind.None, + addRemoveParams, + typeof(void), + builders.CppInitBodyParameterReads); + AppendCppInitBodyFunctionPointerParameterRead( + removeFuncName, + false, + default(TypeName), + TypeKind.None, + addRemoveParams, + typeof(void), + builders.CppInitBodyParameterReads); + AppendCsharpCsharpDelegate( + releaseFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + AppendCsharpCsharpDelegate( + constructorFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + AppendCsharpCsharpDelegate( + addFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + AppendCsharpCsharpDelegate( + removeFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C++ method definitions (end) + int cppMethodDefinitionsIndent = AppendNamespaceBeginning( + type.Namespace, + builders.CppMethodDefinitions); + + AppendCppBaseTypeConstructor( + bindingTypeName, + typeTypeName, + TypeKind.Class, + cppTypeName, + typeParams, + new Type[0], + new ParameterInfo[0], + constructorParams, + true, + constructorFuncName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeNullptrConstructor( + bindingTypeName, + typeTypeName, + typeParams, + new Type[0], + true, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeCopyConstructor( + bindingTypeName, + typeTypeName, + typeParams, + new Type[0], + true, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeMoveConstructor( + typeTypeName, + typeParams, + new Type[0], + true, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeHandleConstructor( + bindingTypeName, + typeTypeName, + typeParams, + new Type[0], + true, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeDestructor( + bindingTypeName, + typeTypeName, + typeParams, + true, + string.Empty, + releaseFuncName, + bindingTypeName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeAssignmentOperatorSameType( + typeTypeName, + typeParams, + true, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeAssignmentOperatorNullptr( + typeTypeName, + typeParams, + true, + releaseFuncName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeMoveAssignmentOperator( + bindingTypeName, + typeTypeName, + typeParams, + true, + releaseFuncName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeEqualityOperator( + typeTypeName, + typeParams, + cppMethodDefinitionsIndent, + true, + builders.CppMethodDefinitions); + + AppendCppBaseTypeInequalityOperator( + typeTypeName, + typeParams, + cppMethodDefinitionsIndent, + true, + builders.CppMethodDefinitions); + + // C++ add + AppendCppMethodDefinitionBegin( + GetTypeName(type), + typeof(void), + "operator+=", + typeParams, + null, + addRemoveParams, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("Plugin::"); + builders.CppMethodDefinitions.Append(addFuncName); + builders.CppMethodDefinitions.AppendLine("(Handle, del.Handle);"); + AppendCppUnhandledExceptionHandling( + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C++ remove + AppendCppMethodDefinitionBegin( + GetTypeName(type), + typeof(void), + "operator-=", + typeParams, + null, + addRemoveParams, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("Plugin::"); + builders.CppMethodDefinitions.Append(removeFuncName); + builders.CppMethodDefinitions.AppendLine("(Handle, del.Handle);"); + AppendCppUnhandledExceptionHandling( + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C# GetDelegate call + AppendCsharpGetDelegateCall( + GetTypeName(type), + typeParams, + "NativeInvoke", + builders.CsharpGetDelegateCalls); + + // C# class (beginning) + builders.CsharpBaseTypes.Append("class "); + builders.CsharpBaseTypes.Append(bindingTypeName); + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("{"); + + // C# class fields + builders.CsharpBaseTypes.AppendLine("\tpublic int CppHandle;"); + builders.CsharpBaseTypes.Append("\tpublic "); + AppendCsharpTypeFullName( + type, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.AppendLine(" Delegate;"); + builders.CsharpBaseTypes.AppendLine("\t"); + + // C# class constructor + builders.CsharpBaseTypes.Append("\tpublic "); + builders.CsharpBaseTypes.Append(bindingTypeName); + builders.CsharpBaseTypes.AppendLine("(int cppHandle)"); + builders.CsharpBaseTypes.AppendLine("\t{"); + builders.CsharpBaseTypes.AppendLine("\t\tCppHandle = cppHandle;"); + builders.CsharpBaseTypes.AppendLine("\t\tDelegate = NativeInvoke;"); + builders.CsharpBaseTypes.AppendLine("\t}"); + builders.CsharpBaseTypes.AppendLine("\t"); + + // Build the name of the C++ binding function that C# calls + builders.TempStrBuilder.Length = 0; + AppendNativeInvokeFuncName( + type, + typeParams, + "NativeInvoke", + builders.TempStrBuilder); + string nativeInvokeFuncName = builders.TempStrBuilder.ToString(); + + // operator() is how C# forwards the delegate invocation to C++ + MethodInfo invokeMethod = type.GetMethod("Invoke"); + AppendBaseTypeCppMethodCall( + type, + bindingTypeName, + typeTypeName, + typeParams, + invokeMethod, + "NativeInvoke", + nativeInvokeFuncName, + "operator()", + false, + true, + indent, + builders); + + // C# class (ending) + builders.CsharpBaseTypes.AppendLine("}"); + builders.CsharpBaseTypes.AppendLine();; + + // Invoke() is how C++ invokes the delegate + AppendBaseTypeMethodCallsCsharpMethod( + type, + bindingTypeName, + typeParams, + invokeMethod, + "Invoke", + null, + indent, + builders); + + // C# constructor delegate type + AppendCsharpDelegateType( + constructorFuncName, + true, + type, + TypeKind.Class, + typeof(void), + constructorParams, + builders.CsharpDelegateTypes); + + AppendCsharpBaseTypeConstructorFunction( + type, + GetTypeName(bindingTypeName, string.Empty), + true, + constructorFuncName, + constructorParams, + new ParameterInfo[0], + builders.CsharpFunctions); + + // C# release delegate type + AppendCsharpDelegateType( + releaseFuncName, + true, + type, + TypeKind.Class, + typeof(void), + releaseParams, + builders.CsharpDelegateTypes); + + AppendCsharpBaseTypeReleaseFunction( + type, + GetTypeName(bindingTypeName, string.Empty), + true, + releaseFuncName, + null, + releaseParams, + builders.CsharpFunctions); + + // C# add delegate type + AppendCsharpDelegateType( + addFuncName, + false, + type, + TypeKind.Class, + typeof(void), + addRemoveParams, + builders.CsharpDelegateTypes); + + // C# add function + AppendCsharpFunctionBeginning( + type, + addFuncName, + false, + TypeKind.Class, + typeof(void), + addRemoveParams, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("thiz += del;"); + AppendCsharpFunctionReturn( + addRemoveParams, + typeof(void), + TypeKind.Class, + null, + false, + builders.CsharpFunctions); + + // C# remove delegate type + AppendCsharpDelegateType( + removeFuncName, + false, + type, + TypeKind.Class, + typeof(void), + addRemoveParams, + builders.CsharpDelegateTypes); + + // C# remove function + AppendCsharpFunctionBeginning( + type, + removeFuncName, + false, + TypeKind.Class, + typeof(void), + addRemoveParams, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("thiz -= del;"); + AppendCsharpFunctionReturn( + addRemoveParams, + typeof(void), + TypeKind.Class, + null, + false, + builders.CsharpFunctions); + + // C++ method definitions (end) + AppendCppMethodDefinitionsEnd( + indent, + builders.CppMethodDefinitions); + + // C++ type definition (end) + AppendCppTypeDefinitionEnd( + false, + indent, + builders.CppTypeDefinitions); + } + + static void AppendBaseType( + Type type, + JsonBaseType jsonBaseType, + TypeName baseTypeTypeName, + Type[] typeParams, + int maxSimultaneous, + Assembly[] assemblies, + StringBuilders builders) + { + // Get specified derived type name + TypeName derivedTypeTypeName = SplitJsonTypeName( + jsonBaseType.DerivedName); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Release"); + builders.TempStrBuilder.Append(baseTypeTypeName.Name); + string releaseFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder.Length = 0; + AppendCppTypeName( + baseTypeTypeName, + builders.TempStrBuilder); + string cppBaseTypeName = builders.TempStrBuilder.ToString(); + + bool hasDefaultConstructor = !type.IsClass || + (type.GetConstructor(new Type[0]) != null || + type.GetConstructors().Length == 0); + + // Either use specified constructors, the default constructor, or + // nothing in the case of MonoBehaviour (where you can't call 'new') + JsonConstructor[] jsonConstructors = jsonBaseType.Constructors; + if (jsonConstructors == null) + { + // Base classes must have a default constructor or no + // constructors at all + if (!hasDefaultConstructor) + { + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Base type \""); + AppendCsharpTypeFullName( + type, + errorBuilder); + errorBuilder.Append( + ")\" doesn't have any specified constructors or a default constructor"); + throw new Exception(errorBuilder.ToString()); + } + + jsonConstructors = new[] + { + new JsonConstructor + { + ParamTypes = new string[0] + } + }; + } + + // Build constructor function names and parameter lists + int numConstructors = jsonConstructors.Length; + string[] constructorFuncNames = new string[numConstructors]; + string[] constructorFuncNameLowers = new string[numConstructors]; + ParameterInfo[][] cppConstructorParams = new ParameterInfo[numConstructors][]; + ParameterInfo[][] constructorParams = new ParameterInfo[numConstructors][]; + for (int i = 0; i < numConstructors; ++i) + { + JsonConstructor jsonCtor = jsonConstructors[i]; + Type[] paramTypes = GetTypes( + jsonCtor.ParamTypes, + assemblies); + + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(baseTypeTypeName.Name); + builders.TempStrBuilder.Append("Constructor"); + AppendTypeNames( + paramTypes, + builders.TempStrBuilder); + string constructorFuncName = builders.TempStrBuilder.ToString(); + + builders.TempStrBuilder[0] = char.ToLower( + builders.TempStrBuilder[0]); + string constructorFuncNameLower = builders.TempStrBuilder.ToString(); + + ParameterInfo[] parameters = GetConstructorParameters( + type, + true, + jsonCtor.ParamTypes); + int numParams = parameters.Length; + ParameterInfo[] fullParams = new ParameterInfo[numParams + 2]; + fullParams[0] = new ParameterInfo + { + Name = "cppHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }; + fullParams[1] = new ParameterInfo + { + Name = "handle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = true, + IsRef = false, + Kind = TypeKind.Primitive + }; + Array.Copy( + parameters, + 0, + fullParams, + 2, + numParams); + + constructorFuncNames[i] = constructorFuncName; + constructorFuncNameLowers[i] = constructorFuncNameLower; + cppConstructorParams[i] = parameters; + constructorParams[i] = fullParams; + } + + // Determine what the C++ class should derive from + Type cppBaseClass; + Type[] cppBaseClassTypeParams; + Type[] cppCtorInitTypes = GetCppCtorInitTypes( + type, + true); + Type[] cppInterfaceTypes; + if (type.IsInterface) + { + cppBaseClass = typeof(object); + cppBaseClassTypeParams = null; + cppInterfaceTypes = new [] { type }; + } + else + { + cppBaseClass = type; + cppBaseClassTypeParams = typeParams; + cppInterfaceTypes = new Type[0]; + } + + AppendCppPointerFreeListStateAndFunctions( + baseTypeTypeName, + null, + baseTypeTypeName.Name, + builders.CppGlobalStateAndFunctions); + + AppendCppPointerFreeListInit( + null, + baseTypeTypeName, + maxSimultaneous, + baseTypeTypeName.Name, + builders.CppInitBodyArrays, + builders.CppInitBodyFirstBoot); + + // C++ type declaration + int indent = AppendCppTypeDeclaration( + baseTypeTypeName, + false, + null, + builders.CppTypeDeclarations); + + ParameterInfo[] releaseParams = { + new ParameterInfo + { + Name = "handle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }}; + + // C++ type definition (begin) + AppendCppTypeDefinitionBegin( + baseTypeTypeName, + TypeKind.Class, + null, + GetTypeName(cppBaseClass), + cppBaseClassTypeParams, + cppInterfaceTypes, + false, + indent, + builders.CppTypeDefinitions); + + // C++ type fields + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + builders.CppTypeDefinitions.AppendLine("int32_t CppHandle;"); + + // C++ constructor declarations + for (int i = 0; i < numConstructors; ++i) + { + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + cppBaseTypeName, + false, + false, + false, + null, + null, + cppConstructorParams[i], + builders.CppTypeDefinitions); + } + + // C++ constructor declaration macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONSTRUCTOR_DECLARATION \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.AppendLine("(Plugin::InternalUse iu, int32_t handle);"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ constructor definition macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONSTRUCTOR_DEFINITION \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.Append("::"); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.AppendLine("(Plugin::InternalUse iu, int32_t handle) \\"); + AppendCppConstructorInitializerList( + cppCtorInitTypes, + indent + 1, + builders.CppMacros, + " \\\n"); + AppendIndent(indent + 1, builders.CppMacros); + builders.CppMacros.Append(", "); + AppendCppTypeFullName( + baseTypeTypeName, + builders.CppMacros); + builders.CppMacros.AppendLine("(iu, handle) \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("}"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ constructor inline definition macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONSTRUCTOR \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.AppendLine("(Plugin::InternalUse iu, int32_t handle) \\"); + AppendCppConstructorInitializerList( + cppCtorInitTypes, + indent + 1, + builders.CppMacros, + " \\\n"); + AppendIndent(indent + 1, builders.CppMacros); + builders.CppMacros.Append(", "); + AppendCppTypeFullName( + baseTypeTypeName, + builders.CppMacros); + builders.CppMacros.AppendLine("(iu, handle) \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("}"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ default contents declaration macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONTENTS_DECLARATION \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("void* operator new(size_t, void* p) noexcept; \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("void operator delete(void*, size_t) noexcept; \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ default contents definition macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONTENTS_DEFINITION \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.Append("void* "); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.AppendLine("::operator new(size_t, void* p) noexcept\\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent + 1, builders.CppMacros); + builders.CppMacros.AppendLine("return p; \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("} \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.Append("void "); + builders.CppMacros.Append(derivedTypeTypeName.Name); + builders.CppMacros.AppendLine("::operator delete(void*, size_t) noexcept \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("}"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ default contents inline definition macro + builders.CppMacros.Append("#define "); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Namespace, + builders.CppMacros); + builders.CppMacros.Append('_'); + AppendUppercaseWithUnderscores( + derivedTypeTypeName.Name, + builders.CppMacros); + builders.CppMacros.AppendLine("_DEFAULT_CONTENTS\\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("void* operator new(size_t, void* p) noexcept \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent + 1, builders.CppMacros); + builders.CppMacros.AppendLine("return p; \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("} \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("void operator delete(void*, size_t) noexcept \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("{ \\"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine("}"); + AppendIndent(indent, builders.CppMacros); + builders.CppMacros.AppendLine();; + + // C++ function pointers + AppendCppFunctionPointerDefinition( + releaseFuncName, + true, + default(TypeName), + TypeKind.None, + releaseParams, + typeof(void), + builders.CppFunctionPointers); + for (int i = 0; i < numConstructors; ++i) + { + AppendCppFunctionPointerDefinition( + constructorFuncNames[i], + true, + default(TypeName), + TypeKind.None, + constructorParams[i], + typeof(void), + builders.CppFunctionPointers); + } + + // C++ and C# init params + AppendCppInitBodyFunctionPointerParameterRead( + releaseFuncName, + true, + default(TypeName), + TypeKind.None, + releaseParams, + typeof(void), + builders.CppInitBodyParameterReads); + AppendCsharpCsharpDelegate( + releaseFuncName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + for (int i = 0; i < numConstructors; ++i) + { + string funcName = constructorFuncNames[i]; + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + true, + default(TypeName), + TypeKind.None, + constructorParams[i], + typeof(void), + builders.CppInitBodyParameterReads); + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + } + + // C++ method definitions (end) + int cppMethodDefinitionsIndent = AppendNamespaceBeginning( + baseTypeTypeName.Namespace, + builders.CppMethodDefinitions); + + for (int i = 0; i < numConstructors; ++i) + { + AppendCppBaseTypeConstructor( + baseTypeTypeName.Name, + baseTypeTypeName, + TypeKind.Class, + cppBaseTypeName, + typeParams, + cppCtorInitTypes, + cppConstructorParams[i], + constructorParams[i], + false, + constructorFuncNames[i], + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + } + + AppendCppBaseTypeNullptrConstructor( + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + cppCtorInitTypes, + false, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeCopyConstructor( + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + cppCtorInitTypes, + false, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeMoveConstructor( + baseTypeTypeName, + typeParams, + cppCtorInitTypes, + false, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeHandleConstructor( + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + cppCtorInitTypes, + false, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeDestructor( + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + false, + derivedTypeTypeName.Name, + releaseFuncName, + baseTypeTypeName.Name, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeAssignmentOperatorSameType( + baseTypeTypeName, + typeParams, + false, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeAssignmentOperatorNullptr( + baseTypeTypeName, + typeParams, + false, + releaseFuncName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeMoveAssignmentOperator( + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + false, + releaseFuncName, + cppMethodDefinitionsIndent, + builders.CppMethodDefinitions); + + AppendCppBaseTypeEqualityOperator( + baseTypeTypeName, + typeParams, + cppMethodDefinitionsIndent, + false, + builders.CppMethodDefinitions); + + AppendCppBaseTypeInequalityOperator( + baseTypeTypeName, + typeParams, + cppMethodDefinitionsIndent, + false, + builders.CppMethodDefinitions); + + if (!string.IsNullOrEmpty(derivedTypeTypeName.Name)) + { + // C++ whole object free list + AppendCppWholeObjectFreeListStateAndFunctions( + null, + baseTypeTypeName, + baseTypeTypeName.Name, + builders.CppGlobalStateAndFunctions); + AppendCppWholeObjectFreeListInit( + maxSimultaneous, + baseTypeTypeName.Name, + builders.CppInitBodyArrays, + builders.CppInitBodyFirstBoot); + + // C++ binding function to create the base class + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("New"); + builders.TempStrBuilder.Append(baseTypeTypeName.Name); + string cppDefaultConstructorBindingFunctionName = builders.TempStrBuilder.ToString(); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("DLLEXPORT int32_t "); + builders.CppMethodDefinitions.Append(cppDefaultConstructorBindingFunctionName); + builders.CppMethodDefinitions.AppendLine("(int32_t handle)"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + AppendCppTypeFullName( + baseTypeTypeName, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("* memory = Plugin::StoreWhole"); + builders.CppMethodDefinitions.Append(baseTypeTypeName.Name); + builders.CppMethodDefinitions.AppendLine("();"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + AppendCppTypeFullName( + derivedTypeTypeName, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("* thiz = new (memory) "); + AppendCppTypeFullName( + derivedTypeTypeName, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("(Plugin::InternalUse::Only, handle);"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("return thiz->CppHandle;"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine(); + + // C# usage of the C++ binding function to create from C# default constructor + ParameterInfo[] cppDefaultConstructorBindingFunctionParams = ConvertParameters( + new[] { typeof(int) }); + AppendCsharpDelegate( + true, + GetTypeName(string.Empty, string.Empty), + null, + cppDefaultConstructorBindingFunctionName, + cppDefaultConstructorBindingFunctionParams, + typeof(int), + TypeKind.None, + builders.CsharpCppDelegates); + AppendCsharpImport( + GetTypeName(string.Empty, string.Empty), + null, + cppDefaultConstructorBindingFunctionName, + ConvertParameters(Type.EmptyTypes), + typeof(int), + builders.CsharpImports); + AppendCsharpGetDelegateCall( + GetTypeName(string.Empty, string.Empty), + null, + cppDefaultConstructorBindingFunctionName, + builders.CsharpGetDelegateCalls); + + // C++ binding function to destroy the base class + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Destroy"); + builders.TempStrBuilder.Append(baseTypeTypeName.Name); + string cppDestroyBindingFunctionName = builders.TempStrBuilder.ToString(); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("DLLEXPORT void "); + builders.CppMethodDefinitions.Append(cppDestroyBindingFunctionName); + builders.CppMethodDefinitions.AppendLine("(int32_t cppHandle)"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + AppendCppTypeFullName( + baseTypeTypeName, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("* instance = Plugin::Get"); + builders.CppMethodDefinitions.Append(baseTypeTypeName.Name); + builders.CppMethodDefinitions.AppendLine("(cppHandle);"); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("instance->~"); + AppendCppTypeName( + baseTypeTypeName, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("();"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine(); + + // C# usage of the C++ binding function to destroy from C# default constructor + ParameterInfo[] cppDestroyBindingFunctionParams = ConvertParameters( + new [] { typeof(int) }); + AppendCsharpDelegate( + true, + GetTypeName(string.Empty, string.Empty), + null, + cppDestroyBindingFunctionName, + cppDestroyBindingFunctionParams, + typeof(void), + TypeKind.None, + builders.CsharpCppDelegates); + ParameterInfo[] cppDestroyImportFunctionParams = ConvertParameters( + new Type[0]); + AppendCsharpImport( + GetTypeName(string.Empty, string.Empty), + null, + cppDestroyBindingFunctionName, + cppDestroyImportFunctionParams, + typeof(void), + builders.CsharpImports); + AppendCsharpGetDelegateCall( + GetTypeName(string.Empty, string.Empty), + null, + cppDestroyBindingFunctionName, + builders.CsharpGetDelegateCalls); + + // C# DestroyFunction enumerator + builders.CsharpDestroyFunctionEnumerators.Append("\t\t\t"); + builders.CsharpDestroyFunctionEnumerators.Append(baseTypeTypeName.Name); + builders.CsharpDestroyFunctionEnumerators.AppendLine(","); + + // C# Destroy queue cases + builders.CsharpDestroyQueueCases.Append("\t\t\t\t\t\tcase DestroyFunction."); + builders.CsharpDestroyQueueCases.Append(baseTypeTypeName.Name); + builders.CsharpDestroyQueueCases.AppendLine(":"); + builders.CsharpDestroyQueueCases.Append("\t\t\t\t\t\t\t"); + builders.CsharpDestroyQueueCases.Append(cppDestroyBindingFunctionName); + builders.CsharpDestroyQueueCases.AppendLine("(entry.CppHandle);"); + builders.CsharpDestroyQueueCases.AppendLine("\t\t\t\t\t\t\tbreak;"); + } + + // C# class (beginning) + builders.CsharpBaseTypes.Append("namespace "); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Namespace); + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("{"); + builders.CsharpBaseTypes.Append("\tclass "); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + if (jsonBaseType != null) + { + builders.CsharpBaseTypes.Append(" : "); + AppendCsharpTypeFullName( + type, + builders.CsharpBaseTypes); + } + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("\t{"); + + // C# class fields + builders.CsharpBaseTypes.AppendLine("\t\tpublic int CppHandle;"); + builders.CsharpBaseTypes.AppendLine("\t\t"); + + if (derivedTypeTypeName.Name != null) + { + // C# class default constructor if the base class has one + if (hasDefaultConstructor) + { + builders.CsharpBaseTypes.Append("\t\tpublic "); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + builders.CsharpBaseTypes.AppendLine("()"); + builders.CsharpBaseTypes.AppendLine("\t\t{"); + builders.CsharpBaseTypes.AppendLine( + "\t\t\tint handle = NativeScript.Bindings.ObjectStore.Store(this);"); + builders.CsharpBaseTypes.Append( + "\t\t\tCppHandle = NativeScript.Bindings.New"); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + builders.CsharpBaseTypes.AppendLine("(handle);"); + builders.CsharpBaseTypes.AppendLine("\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t"); + } + + // C# finalizer/destructor + builders.CsharpBaseTypes.Append("\t\t~"); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + builders.CsharpBaseTypes.AppendLine("()"); + builders.CsharpBaseTypes.AppendLine("\t\t{"); + builders.CsharpBaseTypes.AppendLine("\t\t\tif (CppHandle != 0)"); + builders.CsharpBaseTypes.AppendLine("\t\t\t{"); + builders.CsharpBaseTypes.Append( + "\t\t\t\tNativeScript.Bindings.QueueDestroy(NativeScript.Bindings.DestroyFunction."); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + builders.CsharpBaseTypes.AppendLine(", CppHandle);"); + builders.CsharpBaseTypes.AppendLine("\t\t\t\tCppHandle = 0;"); + builders.CsharpBaseTypes.AppendLine("\t\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t"); + } + + // C# class constructors + for (int i = 0; i < numConstructors; ++i) + { + builders.CsharpBaseTypes.Append("\t\tpublic "); + builders.CsharpBaseTypes.Append(baseTypeTypeName.Name); + builders.CsharpBaseTypes.Append("(int cppHandle"); + ParameterInfo[] parameters = cppConstructorParams[i]; + if (parameters.Length > 0) + { + builders.CsharpBaseTypes.Append(", "); + AppendCsharpParams( + parameters, + builders.CsharpBaseTypes); + } + builders.CsharpBaseTypes.AppendLine(")"); + builders.CsharpBaseTypes.Append("\t\t\t: base("); + AppendCsharpFunctionCallParameters( + parameters, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.AppendLine(")"); + builders.CsharpBaseTypes.AppendLine("\t\t{"); + builders.CsharpBaseTypes.AppendLine("\t\t\tCppHandle = cppHandle;"); + builders.CsharpBaseTypes.AppendLine("\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t"); + } + + // C# constructor delegate type + for (int i = 0; i < numConstructors; ++i) + { + AppendCsharpDelegateType( + constructorFuncNames[i], + true, + type, + TypeKind.Class, + typeof(void), + constructorParams[i], + builders.CsharpDelegateTypes); + } + + for (int i = 0; i < numConstructors; ++i) + { + AppendCsharpBaseTypeConstructorFunction( + type, + baseTypeTypeName, + false, + constructorFuncNames[i], + constructorParams[i], + cppConstructorParams[i], + builders.CsharpFunctions); + } + + // C# release delegate type + AppendCsharpDelegateType( + releaseFuncName, + true, + type, + TypeKind.Class, + typeof(void), + releaseParams, + builders.CsharpDelegateTypes); + + AppendCsharpBaseTypeReleaseFunction( + type, + baseTypeTypeName, + false, + releaseFuncName, + jsonBaseType.DerivedName, + releaseParams, + builders.CsharpFunctions); + + // All abstract methods + foreach (MethodInfo methodInfo in type.GetMethods()) + { + // Property methods like "get_X" have a "special name" + if (methodInfo.IsAbstract && !methodInfo.IsSpecialName) + { + AppendBaseTypeNativeMethod( + type, + baseTypeTypeName, + typeParams, + methodInfo, + false, + indent, + builders); + } + } + + // All interface methods + if (type.IsInterface) + { + foreach (Type interfaceType in type.GetInterfaces()) + { + foreach (MethodInfo methodInfo in interfaceType.GetMethods()) + { + // Property methods like "get_X" have a "special name" + if (methodInfo.IsAbstract && !methodInfo.IsSpecialName) + { + AppendBaseTypeNativeMethod( + type, + baseTypeTypeName, + typeParams, + methodInfo, + false, + indent, + builders); + } + } + } + } + + // Specified virtual methods + if (jsonBaseType.OverrideMethods != null) + { + MethodInfo[] methods = type.GetMethods(); + Type[] genericArgTypes = type.GetGenericArguments(); + foreach (JsonMethod jsonMethod in jsonBaseType.OverrideMethods) + { + if (jsonMethod.GenericParams != null) + { + foreach (JsonGenericParams jsonGenericParams in + jsonMethod.GenericParams) + { + MethodInfo methodInfo = GetMethod( + jsonMethod, + type, + typeParams, + genericArgTypes, + methods, + jsonGenericParams.Types); + AppendBaseTypeNativeMethod( + type, + baseTypeTypeName, + typeParams, + methodInfo, + false, + indent, + builders); + } + } + else + { + MethodInfo methodInfo = GetMethod( + jsonMethod, + type, + typeParams, + genericArgTypes, + methods, + null); + AppendBaseTypeNativeMethod( + type, + baseTypeTypeName, + typeParams, + methodInfo, + false, + indent, + builders); + } + } + } + + // All abstract properties + foreach (PropertyInfo propertyInfo in type.GetProperties()) + { + MethodInfo getMethodInfo = propertyInfo.GetGetMethod(); + MethodInfo setMethodInfo = propertyInfo.GetSetMethod(); + if ((getMethodInfo == null || !getMethodInfo.IsAbstract) && + (setMethodInfo == null || !setMethodInfo.IsAbstract)) + { + continue; + } + AppendBaseTypeProperty( + type, + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + propertyInfo, + getMethodInfo, + setMethodInfo, + indent, + builders); + } + + // All interface properties + if (type.IsInterface) + { + foreach (Type interfaceType in type.GetInterfaces()) + { + foreach (PropertyInfo propertyInfo in + interfaceType.GetProperties()) + { + MethodInfo getMethodInfo = propertyInfo.GetGetMethod(); + MethodInfo setMethodInfo = propertyInfo.GetSetMethod(); + if ((getMethodInfo == null || !getMethodInfo.IsAbstract) && + (setMethodInfo == null || !setMethodInfo.IsAbstract)) + { + continue; + } + AppendBaseTypeProperty( + type, + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + propertyInfo, + getMethodInfo, + setMethodInfo, + indent, + builders); + } + } + } + + // Specified virtual properties + if (jsonBaseType.OverrideProperties != null) + { + PropertyInfo[] properties = type.GetProperties(); + foreach (JsonProperty jsonProperty in jsonBaseType.OverrideProperties) + { + PropertyInfo propertyInfo = null; + foreach (PropertyInfo curPropertyInfo in properties) + { + if (curPropertyInfo.Name == jsonProperty.Name) + { + propertyInfo = curPropertyInfo; + break; + } + } + if (propertyInfo == null) + { + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Property \""); + AppendCsharpTypeFullName( + type, + errorBuilder); + errorBuilder.Append('.'); + errorBuilder.Append(jsonProperty.Name); + errorBuilder.Append(")\" not found"); + throw new Exception(errorBuilder.ToString()); + } + + MethodInfo getMethodInfo = propertyInfo.GetGetMethod(); + MethodInfo setMethodInfo = propertyInfo.GetSetMethod(); + if ((getMethodInfo == null || !getMethodInfo.IsVirtual) && + (setMethodInfo == null || !setMethodInfo.IsVirtual)) + { + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Property \""); + AppendCsharpTypeFullName( + type, + errorBuilder); + errorBuilder.Append('.'); + errorBuilder.Append(jsonProperty.Name); + errorBuilder.Append( + ")\" doesn't have either a virtual 'get' or 'set' to override"); + throw new Exception(errorBuilder.ToString()); + } + AppendBaseTypeProperty( + type, + baseTypeTypeName.Name, + baseTypeTypeName, + typeParams, + propertyInfo, + getMethodInfo, + setMethodInfo, + indent, + builders); + } + } + + // All abstract events + foreach (EventInfo eventInfo in type.GetEvents()) + { + MethodInfo addMethodInfo = eventInfo.GetAddMethod(); + MethodInfo removeMethodInfo = eventInfo.GetRemoveMethod(); + if ((addMethodInfo == null || !addMethodInfo.IsAbstract) && + (removeMethodInfo == null || !removeMethodInfo.IsAbstract)) + { + continue; + } + AppendBaseTypeEvent( + type, + baseTypeTypeName, + typeParams, + eventInfo, + addMethodInfo, + removeMethodInfo, + indent, + builders); + } + + // All interface events + if (type.IsInterface) + { + foreach (Type interfaceType in type.GetInterfaces()) + { + foreach (EventInfo eventInfo in interfaceType.GetEvents()) + { + MethodInfo addMethodInfo = eventInfo.GetAddMethod(); + MethodInfo removeMethodInfo = eventInfo.GetRemoveMethod(); + if ((addMethodInfo == null || !addMethodInfo.IsAbstract) && + (removeMethodInfo == null || !removeMethodInfo.IsAbstract)) + { + continue; + } + AppendBaseTypeEvent( + type, + baseTypeTypeName, + typeParams, + eventInfo, + addMethodInfo, + removeMethodInfo, + indent, + builders); + } + } + } + + // Specified virtual events + if (jsonBaseType.OverrideEvents != null) + { + EventInfo[] events = type.GetEvents(); + foreach (JsonEvent jsonEvent in jsonBaseType.OverrideEvents) + { + EventInfo eventInfo = null; + foreach (EventInfo curEventInfo in events) + { + if (curEventInfo.Name == jsonEvent.Name) + { + eventInfo = curEventInfo; + break; + } + } + if (eventInfo == null) + { + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Event \""); + AppendCsharpTypeFullName( + type, + errorBuilder); + errorBuilder.Append('.'); + errorBuilder.Append(jsonEvent.Name); + errorBuilder.Append(")\" not found"); + throw new Exception(errorBuilder.ToString()); + } + + MethodInfo addMethodInfo = eventInfo.GetAddMethod(); + MethodInfo removeMethodInfo = eventInfo.GetRemoveMethod(); + if ((addMethodInfo == null || !addMethodInfo.IsVirtual) && + (removeMethodInfo == null || !removeMethodInfo.IsVirtual)) + { + // Throw an exception so the user knows what to fix in the JSON + StringBuilder errorBuilder = new StringBuilder(1024); + errorBuilder.Append("Event \""); + AppendCsharpTypeFullName( + type, + errorBuilder); + errorBuilder.Append('.'); + errorBuilder.Append(jsonEvent.Name); + errorBuilder.Append( + ")\" doesn't have either a virtual 'add' or 'remove' to override"); + throw new Exception(errorBuilder.ToString()); + } + AppendBaseTypeEvent( + type, + baseTypeTypeName, + typeParams, + eventInfo, + addMethodInfo, + removeMethodInfo, + indent, + builders); + } + } + + // C# class (ending) + builders.CsharpBaseTypes.AppendLine("\t}"); + builders.CsharpBaseTypes.AppendLine("}"); + builders.CsharpBaseTypes.AppendLine(); + + // C++ method definitions (end) + AppendCppMethodDefinitionsEnd( + indent, + builders.CppMethodDefinitions); + + // C++ type definition (end) + AppendCppTypeDefinitionEnd( + false, + indent, + builders.CppTypeDefinitions); + } + + static void AppendBaseTypeNativeMethod( + Type type, + TypeName typeTypeName, + Type[] typeParams, + MethodInfo methodInfo, + bool typeIsDelegate, + int indent, + StringBuilders builders) + { + AppendCsharpGetDelegateCall( + GetTypeName(type), + typeParams, + methodInfo.Name, + builders.CsharpGetDelegateCalls); + + // Build the name of the C++ binding function that C# calls + builders.TempStrBuilder.Length = 0; + AppendNativeInvokeFuncName( + type, + typeParams, + methodInfo.Name, + builders.TempStrBuilder); + string nativeInvokeFuncName = builders.TempStrBuilder.ToString(); + + AppendBaseTypeCppMethodCall( + type, + typeTypeName.Name, + typeTypeName, + typeParams, + methodInfo, + methodInfo.Name, + nativeInvokeFuncName, + methodInfo.Name, + IsNonDelegateClass(type), + typeIsDelegate, + indent, + builders); + } + + static void AppendBaseTypeProperty( + Type type, + string typeName, + TypeName typeTypeName, + Type[] typeParams, + PropertyInfo propertyInfo, + MethodInfo getMethodInfo, + MethodInfo setMethodInfo, + int indent, + StringBuilders builders) + { + bool isOverride = IsNonDelegateClass(type); + + ParameterInfo[] parameters; + if (getMethodInfo != null && getMethodInfo.IsVirtual) + { + parameters = ConvertParameters( + getMethodInfo.GetParameters()); + } + else + { + System.Reflection.ParameterInfo[] setParams = + setMethodInfo.GetParameters(); + parameters = ConvertParameters(setParams, 1); + } + + builders.CsharpBaseTypes.Append("\t\tpublic "); + if (isOverride) + { + builders.CsharpBaseTypes.Append("override "); + } + AppendCsharpTypeFullName( + propertyInfo.PropertyType, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.Append(' '); + if (parameters.Length == 0) + { + builders.CsharpBaseTypes.Append(propertyInfo.Name); + } + else + { + builders.CsharpBaseTypes.Append("this["); + AppendCsharpParams( + parameters, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.Append(']'); + } + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("\t\t{"); + + TypeKind propertyTypeKind = GetTypeKind( + propertyInfo.PropertyType); + + if (getMethodInfo != null && getMethodInfo.IsVirtual) + { + AppendBaseTypeNativePropertyOrEvent( + type, + typeName, + typeParams, + typeTypeName, + propertyInfo.Name, + propertyTypeKind, + getMethodInfo, + "Get", + false, + indent, + builders); + } + + if (setMethodInfo != null && setMethodInfo.IsVirtual) + { + AppendBaseTypeNativePropertyOrEvent( + type, + typeName, + typeParams, + typeTypeName, + propertyInfo.Name, + propertyTypeKind, + setMethodInfo, + "Set", + false, + indent, + builders); + } + + builders.CsharpBaseTypes.AppendLine("\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t"); + } + + static void AppendBaseTypeEvent( + Type type, + TypeName typeTypeName, + Type[] typeParams, + EventInfo eventInfo, + MethodInfo addMethodInfo, + MethodInfo removeMethodInfo, + int indent, + StringBuilders builders) + { + bool isOverride = IsNonDelegateClass(type); + + builders.CsharpBaseTypes.Append("\t\tpublic "); + if (isOverride) + { + builders.CsharpBaseTypes.Append("override "); + } + builders.CsharpBaseTypes.Append("event "); + AppendCsharpTypeFullName( + eventInfo.EventHandlerType, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.Append(' '); + builders.CsharpBaseTypes.Append(eventInfo.Name); + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("\t\t{"); + + TypeKind eventHandlerTypeKind = GetTypeKind( + eventInfo.EventHandlerType); + + if (addMethodInfo != null && addMethodInfo.IsVirtual) + { + AppendBaseTypeNativePropertyOrEvent( + type, + typeTypeName.Name, + typeParams, + typeTypeName, + eventInfo.Name, + eventHandlerTypeKind, + addMethodInfo, + "Add", + false, + indent, + builders); + } + + if (removeMethodInfo != null && removeMethodInfo.IsVirtual) + { + AppendBaseTypeNativePropertyOrEvent( + type, + typeTypeName.Name, + typeParams, + typeTypeName, + eventInfo.Name, + eventHandlerTypeKind, + removeMethodInfo, + "Remove", + false, + indent, + builders); + } + + builders.CsharpBaseTypes.AppendLine("\t\t\t}"); + builders.CsharpBaseTypes.AppendLine("\t\t\t"); + } + + static void AppendBaseTypeNativePropertyOrEvent( + Type type, + string typeName, + Type[] typeParams, + TypeName typeTypeName, + string propertyOrEventName, + TypeKind propertyOrEventTypeKind, + MethodInfo methodInfo, + string operationType, + bool typeIsDelegate, + int indent, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(operationType); + builders.TempStrBuilder.Append(propertyOrEventName); + string funcName = builders.TempStrBuilder.ToString(); + + AppendCsharpGetDelegateCall( + GetTypeName(type), + typeParams, + funcName, + builders.CsharpGetDelegateCalls); + + // Build the name of the C++ binding function that C# calls + builders.TempStrBuilder.Length = 0; + AppendNativeInvokeFuncName( + type, + typeParams, + funcName, + builders.TempStrBuilder); + string nativeInvokeFuncName = builders.TempStrBuilder.ToString(); + + ParameterInfo[] invokeParams = AppendBaseTypeCppNativeInvokeCall( + type, + typeName, + typeTypeName, + typeParams, + methodInfo, + funcName, + funcName, + typeIsDelegate, + indent, + builders); + + // C# method that calls the C++ binding function + ParameterInfo[] invokeParamsWithThis = PrependThisParameter( + invokeParams); + builders.CsharpBaseTypes.Append("\t\t\t"); + builders.CsharpBaseTypes.Append(char.ToLower(operationType[0])); + builders.CsharpBaseTypes.Append( + operationType, + 1, + operationType.Length - 1); + builders.CsharpBaseTypes.AppendLine();; + builders.CsharpBaseTypes.AppendLine("\t\t\t{"); + AppendCsharpBaseTypeCppMethodCallMethodBody( + methodInfo, + nativeInvokeFuncName, + invokeParamsWithThis, + propertyOrEventTypeKind, + 4, + builders.CsharpBaseTypes); + builders.CsharpBaseTypes.AppendLine("\t\t\t}"); + } + + static void AppendCsharpParams( + ParameterInfo[] parameters, + StringBuilder output) + { + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo param = parameters[i]; + AppendCsharpTypeFullName( + param.ParameterType, + output); + output.Append(' '); + output.Append(param.Name); + if (i != parameters.Length - 1) + { + output.Append(", "); + } + } + } + + static void AppendBaseTypeMethodCallsCsharpMethod( + Type type, + string typeName, + Type[] typeParams, + MethodInfo methodInfo, + string methodName, + string csharpMethodName, + int indent, + StringBuilders builders) + { + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(typeName); + builders.TempStrBuilder.Append(methodName); + string funcName = builders.TempStrBuilder.ToString(); + + // C++ method declaration for the method + ParameterInfo[] invokeParams = ConvertParameters( + methodInfo.GetParameters()); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + methodName, + false, + false, + false, + methodInfo.ReturnType, + null, + invokeParams, + builders.CppTypeDefinitions); + + // C++ function pointer for the C# binding function + AppendCppFunctionPointerDefinition( + funcName, + false, + default(TypeName), + TypeKind.None, + invokeParams, + methodInfo.ReturnType, + builders.CppFunctionPointers); + + // C++ and C# Init parameter and body for the C# binding function + AppendCppInitBodyFunctionPointerParameterRead( + funcName, + false, + default(TypeName), + TypeKind.None, + invokeParams, + methodInfo.ReturnType, + builders.CppInitBodyParameterReads); + AppendCsharpCsharpDelegate( + funcName, + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); + + // C++ method definition for the method + TypeKind returnTypeKind = GetTypeKind( + methodInfo.ReturnType); + AppendCppMethodDefinitionBegin( + GetTypeName(type), + methodInfo.ReturnType, + methodName, + typeParams, + null, + invokeParams, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendCppPluginFunctionCall( + false, + GetTypeName(type), + TypeKind.Class, + typeParams, + methodInfo.ReturnType, + funcName, + invokeParams, + indent + 1, + builders.CppMethodDefinitions); + AppendCppMethodReturn( + methodInfo.ReturnType, + returnTypeKind, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C# delegate type for the binding function that C++ calls + ParameterInfo[] invokeParamsWithThis = new ParameterInfo[ + invokeParams.Length + 1]; + for (int i = 0; i < invokeParams.Length; ++i) + { + invokeParamsWithThis[i+1] = invokeParams[i]; + } + invokeParamsWithThis[0] = new ParameterInfo { + Name = "thisHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }; + AppendCsharpDelegateType( + funcName, + true, + type, + TypeKind.Class, + methodInfo.ReturnType, + invokeParamsWithThis, + builders.CsharpDelegateTypes); + + // C# binding function that C++ calls to invoke the method + AppendCsharpFunctionBeginning( + type, + funcName, + true, + TypeKind.Class, + methodInfo.ReturnType, + invokeParamsWithThis, + builders.CsharpFunctions); + builders.CsharpFunctions.Append("(("); + AppendCsharpTypeFullName( + type, + builders.CsharpFunctions); + builders.CsharpFunctions.Append( + ")NativeScript.Bindings.ObjectStore.Get(thisHandle))"); + if (csharpMethodName != null) + { + builders.CsharpFunctions.Append('.'); + builders.CsharpFunctions.Append(csharpMethodName); + } + builders.CsharpFunctions.Append('('); + AppendCsharpFunctionCallParameters( + invokeParams, + builders.CsharpFunctions); + builders.CsharpFunctions.Append(");"); + AppendCsharpFunctionReturn( + invokeParams, + methodInfo.ReturnType, + returnTypeKind, + null, + false, + builders.CsharpFunctions); + } + + static void AppendNativeInvokeFuncName( + Type type, + Type[] typeParams, + string funcName, + StringBuilder output) + { + AppendNamespace( + type.Namespace, + string.Empty, + output); + AppendTypeNameWithoutSuffixes( + type.Name, + output); + AppendTypeNames( + typeParams, + output); + output.Append(funcName); + } + + static void AppendBaseTypeCppMethodCall( + Type type, + string typeName, + TypeName typeTypeName, + Type[] typeParams, + MethodInfo invokeMethod, + string funcName, + string nativeInvokeFuncName, + string methodName, + bool isOverride, + bool typeIsDelegate, + int indent, + StringBuilders builders) + { + ParameterInfo[] invokeParams = AppendBaseTypeCppNativeInvokeCall( + type, + typeName, + typeTypeName, + typeParams, + invokeMethod, + funcName, + methodName, + typeIsDelegate, + indent, + builders); + + // C# method that calls the C++ binding function + ParameterInfo[] invokeParamsWithThis = PrependThisParameter( + invokeParams); + TypeKind invokeReturnTypeKind = GetTypeKind( + invokeMethod.ReturnType); + AppendCsharpBaseTypeCppMethodCallMethod( + isOverride, + invokeMethod, + funcName, + invokeParams, + nativeInvokeFuncName, + invokeParamsWithThis, + invokeReturnTypeKind, + builders.CsharpBaseTypes); + } + + static ParameterInfo[] AppendBaseTypeCppNativeInvokeCall( + Type type, + string typeName, + TypeName typeTypeName, + Type[] typeParams, + MethodInfo invokeMethod, + string funcName, + string methodName, + bool typeIsDelegate, + int indent, + StringBuilders builders) + { + // C++ method declaration + ParameterInfo[] invokeParams = ConvertParameters( + invokeMethod.GetParameters()); + AppendIndent( + indent + 1, + builders.CppTypeDefinitions); + AppendCppMethodDeclaration( + methodName, + false, + true, + false, + invokeMethod.ReturnType, + null, + invokeParams, + builders.CppTypeDefinitions); + + // C++ method definition. This is a no-op that game code overrides. + AppendCppMethodDefinitionBegin( + typeTypeName, + invokeMethod.ReturnType, + methodName, + typeIsDelegate ? typeParams : null, + null, + invokeParams, + indent, + builders.CppMethodDefinitions); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + if (invokeMethod.ReturnType != typeof(void)) + { + TypeKind returnTypeKind = GetTypeKind(invokeMethod.ReturnType); + AppendIndent( + indent + 1, + builders.CppMethodDefinitions); + if (returnTypeKind == TypeKind.Class || + returnTypeKind == TypeKind.ManagedStruct) + { + builders.CppMethodDefinitions.AppendLine("return nullptr;"); + } + else + { + builders.CppMethodDefinitions.AppendLine("return {};"); + } + } + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + indent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C++ binding function that C# calls. Calls the C++ method. + TypeKind invokeReturnTypeKind = GetTypeKind( + invokeMethod.ReturnType); + AppendCppBaseTypeMethodInvokeBindingFunction( + funcName, + type, + typeParams, + invokeMethod, + methodName, + invokeReturnTypeKind, + invokeParams, + indent, + typeName, + builders.CppMethodDefinitions); + + // C# delegate for the C++ binding function + AppendCsharpDelegate( + false, + GetTypeName(type), + typeParams, + funcName, + invokeParams, + invokeMethod.ReturnType, + invokeReturnTypeKind, + builders.CsharpCppDelegates); + + // C# import for the C++ binding function + AppendCsharpImport( + GetTypeName(type), + typeParams, + funcName, + invokeParams, + invokeMethod.ReturnType, + builders.CsharpImports); + + return invokeParams; + } + + static ParameterInfo[] PrependThisParameter( + ParameterInfo[] invokeParams) + { + ParameterInfo[] invokeParamsWithThis = new ParameterInfo[ + invokeParams.Length + 1]; + for (int i = 0; i < invokeParams.Length; ++i) + { + invokeParamsWithThis[i+1] = invokeParams[i]; + } + invokeParamsWithThis[0] = new ParameterInfo { + Name = "thisHandle", + ParameterType = typeof(int), + DereferencedParameterType = typeof(int), + IsOut = false, + IsRef = false, + Kind = TypeKind.Primitive + }; + return invokeParamsWithThis; + } + + static void AppendCsharpBaseTypeReleaseFunction( + Type type, + TypeName bindingTypeTypeName, + bool typeIsDelegate, + string releaseFuncName, + string derivedName, + ParameterInfo[] releaseParams, + StringBuilder output) + { + AppendCsharpFunctionBeginning( + type, + releaseFuncName, + true, + TypeKind.Class, + typeof(void), + releaseParams, + output); + if (typeIsDelegate || derivedName != null) + { + AppendCsharpTypeFullName( + bindingTypeTypeName, + output); + output.AppendLine(" thiz;"); + } + if (typeIsDelegate) + { + output.AppendLine("\t\t\t\tif (classHandle != 0)"); + output.AppendLine("\t\t\t\t{"); + output.Append("\t\t\t\t\tthiz = ("); + AppendCsharpTypeFullName( + bindingTypeTypeName, + output); + output.AppendLine(")ObjectStore.Remove(classHandle);"); + output.AppendLine("\t\t\t\t\tthiz.CppHandle = 0;"); + output.AppendLine("\t\t\t\t}"); + output.AppendLine("\t\t\t\t"); + } + if (derivedName != null) + { + output.Append("\t\t\t\tthiz = ("); + AppendCsharpTypeFullName( + bindingTypeTypeName, + output); + output.AppendLine(")ObjectStore.Get(handle);"); + output.AppendLine("\t\t\t\tint cppHandle = thiz.CppHandle;"); + output.AppendLine("\t\t\t\tthiz.CppHandle = 0;"); + output.Append("\t\t\t\tQueueDestroy(DestroyFunction."); + output.Append(bindingTypeTypeName.Name); + output.AppendLine(", cppHandle);"); + } + output.Append("\t\t\t\tObjectStore.Remove(handle);"); + AppendCsharpFunctionReturn( + releaseParams, + typeof(void), + TypeKind.Class, + null, + true, + output); + } + + static void AppendCsharpBaseTypeCppMethodCallMethod( + bool isOverride, + MethodInfo invokeMethod, + string funcName, + ParameterInfo[] invokeParams, + string nativeInvokeFuncName, + ParameterInfo[] invokeParamsWithThis, + TypeKind invokeReturnTypeKind, + StringBuilder output) + { + output.Append("\t\tpublic "); + if (isOverride) + { + output.Append("override "); + } + AppendCsharpTypeFullName( + invokeMethod.ReturnType, + output); + output.Append(' '); + output.Append(funcName); + output.Append("("); + AppendCsharpParams( + invokeParams, + output); + output.AppendLine(")"); + output.AppendLine("\t\t{"); + AppendCsharpBaseTypeCppMethodCallMethodBody( + invokeMethod, + nativeInvokeFuncName, + invokeParamsWithThis, + invokeReturnTypeKind, + 3, + output); + output.AppendLine("\t\t}"); + output.AppendLine("\t"); + } + + static void AppendCsharpBaseTypeCppMethodCallMethodBody( + MethodInfo invokeMethod, + string nativeInvokeFuncName, + ParameterInfo[] invokeParamsWithThis, + TypeKind invokeReturnTypeKind, + int indent, + StringBuilder output) + { + AppendIndent( + indent, + output); + output.AppendLine("if (CppHandle != 0)"); + AppendIndent( + indent, + output); + output.AppendLine("{"); + AppendIndent( + indent + 1, + output); + output.AppendLine("int thisHandle = CppHandle;"); + AppendCppFunctionCall( + nativeInvokeFuncName, + invokeParamsWithThis, + invokeMethod.ReturnType, + true, + indent + 1, + output); + if (invokeMethod.ReturnType != typeof(void)) + { + AppendIndent( + indent + 1, + output); + output.Append("return "); + switch (invokeReturnTypeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + if (invokeMethod.ReturnType != typeof(object)) + { + output.Append('('); + AppendCsharpTypeFullName( + invokeMethod.ReturnType, + output); + output.Append(')'); + } + AppendHandleStoreTypeName( + invokeMethod.ReturnType, + output); + output.AppendLine(".Get(returnVal);"); + break; + default: + output.AppendLine("returnVal;"); + break; + } + } + AppendIndent( + indent, + output); + output.AppendLine("}"); + if (invokeMethod.ReturnType != typeof(void)) + { + AppendIndent( + indent, + output); + output.Append("return default("); + AppendCsharpTypeFullName( + invokeMethod.ReturnType, + output); + output.AppendLine(");"); + } + } + + static void AppendCsharpBaseTypeConstructorFunction( + Type type, + TypeName typeTypeName, + bool typeIsDelegate, + string constructorFuncName, + ParameterInfo[] constructorParams, + ParameterInfo[] cppConstructorParams, + StringBuilder output) + { + AppendCsharpFunctionBeginning( + type, + constructorFuncName, + true, + TypeKind.Class, + typeof(void), + constructorParams, + output); + output.Append("var thiz = new "); + AppendCsharpTypeFullName(typeTypeName, output); + output.Append("(cppHandle"); + if (cppConstructorParams.Length > 0) + { + output.Append(", "); + AppendCsharpFunctionCallParameters( + cppConstructorParams, + output); + } + output.AppendLine(");"); + if (typeIsDelegate) + { + output.AppendLine( + "\t\t\t\tclassHandle = NativeScript.Bindings.ObjectStore.Store(thiz);"); + output.Append( + "\t\t\t\thandle = NativeScript.Bindings.ObjectStore.Store(thiz.Delegate);"); + } + else + { + output.Append( + "\t\t\t\thandle = NativeScript.Bindings.ObjectStore.Store(thiz);"); + } + AppendCsharpFunctionReturn( + constructorParams, + typeof(void), + TypeKind.Class, + null, + true, + output); + } + + static void AppendCppBaseTypeMethodInvokeBindingFunction( + string funcName, + Type type, + Type[] typeParams, + MethodInfo method, + string methodName, + TypeKind methodReturnTypeKind, + ParameterInfo[] methodParams, + int indent, + string typeName, + StringBuilder output) + { + AppendIndent( + indent, + output); + output.Append("DLLEXPORT "); + if (method.ReturnType == typeof(void)) + { + output.Append("void"); + } + else if (method.ReturnType == typeof(bool)) + { + // C linkage requires us to use primitive types + output.Append("int32_t"); + } + else if (method.ReturnType == typeof(char)) + { + // C linkage requires us to use primitive types + output.Append("int16_t"); + } + else + { + switch (methodReturnTypeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + output.Append("int32_t"); + break; + case TypeKind.Primitive: + AppendCppPrimitiveTypeName( + method.ReturnType, + output); + break; + default: + AppendCppTypeFullName( + method.ReturnType, + output); + break; + } + } + output.Append(' '); + AppendCsharpDelegateName( + GetTypeName(type), + typeParams, + funcName, + output); + output.Append("(int32_t cppHandle"); + if (methodParams.Length > 0) + { + output.Append(", "); + } + for (int i = 0; i < methodParams.Length; ++i) + { + ParameterInfo param = methodParams[i]; + switch (param.Kind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + output.Append("int32_t "); + output.Append(param.Name); + output.Append("Handle"); + break; + case TypeKind.Primitive: + AppendCppPrimitiveTypeName( + param.ParameterType, + output); + output.Append(' '); + output.Append(param.Name); + break; + default: + AppendCppTypeFullName( + param.ParameterType, + output); + output.Append(' '); + output.Append(param.Name); + break; + } + if (i != methodParams.Length - 1) + { + output.Append(", "); + } + } + output.AppendLine(")"); + AppendIndent( + indent, + output); + output.AppendLine("{"); + AppendIndent( + indent + 1, + output); + output.AppendLine("try"); + AppendIndent( + indent + 1, + output); + output.AppendLine("{"); + foreach (ParameterInfo parameter in methodParams) + { + if (parameter.Kind == TypeKind.Class || + parameter.Kind == TypeKind.ManagedStruct) + { + AppendIndent( + indent + 2, + output); + output.Append("auto "); + output.Append(parameter.Name); + output.Append(" = "); + AppendCppTypeFullName( + parameter.ParameterType, + output); + output.Append("(Plugin::InternalUse::Only, "); + output.Append(parameter.Name); + output.AppendLine("Handle);"); + } + } + AppendIndent( + indent + 2, + output); + if (method.ReturnType != typeof(void)) + { + output.Append("return "); + } + output.Append("Plugin::Get"); + output.Append(typeName); + output.Append("(cppHandle)->"); + output.Append(methodName); + output.Append("("); + for (int i = 0; i < methodParams.Length; ++i) + { + ParameterInfo parameter = methodParams[i]; + if (parameter.Kind == TypeKind.Class || + parameter.Kind == TypeKind.ManagedStruct) + { + output.Append(parameter.Name); + } + else + { + output.Append(parameter.Name); + } + if (i != methodParams.Length - 1) + { + output.Append(", "); + } + } + output.Append(")"); + if ( + method.ReturnType != typeof(void) && + (methodReturnTypeKind == TypeKind.Class || + methodReturnTypeKind == TypeKind.ManagedStruct)) + { + output.Append(".Handle"); + } + output.AppendLine(";"); + AppendIndent( + indent + 1, + output); + output.AppendLine("}"); + AppendIndent( + indent + 1, + output); + output.AppendLine( + "catch (System::Exception ex)"); + AppendIndent( + indent + 1, + output); + output.AppendLine("{"); + AppendIndent( + indent + 2, + output); + output.AppendLine( + "Plugin::SetException(ex.Handle);"); + if (method.ReturnType != typeof(void)) + { + AppendIndent( + indent + 2, + output); + output.AppendLine( + "return {};"); + } + AppendIndent( + indent + 1, + output); + output.AppendLine("}"); + AppendIndent( + indent + 1, + output); + output.AppendLine("catch (...)"); + AppendIndent( + indent + 1, + output); + output.AppendLine("{"); + AppendIndent( + indent + 2, + output); + output.Append( + "System::String msg = \"Unhandled exception invoking "); + AppendCppTypeFullName( + type, + output); + output.AppendLine("\";"); + AppendIndent( + indent + 2, + output); + output.AppendLine( + "System::Exception ex(msg);"); + AppendIndent( + indent + 2, + output); + output.AppendLine( + "Plugin::SetException(ex.Handle);"); + if (method.ReturnType != typeof(void)) + { + AppendIndent( + indent + 2, + output); + output.AppendLine( + "return {};"); + } + AppendIndent( + indent + 1, + output); + output.AppendLine("}"); + AppendIndent( + indent, + output); + output.AppendLine("}"); + AppendIndent( + indent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeInequalityOperator( + TypeName typeTypeName, + Type[] typeParams, + int cppMethodDefinitionsIndent, + bool typeIsDelegate, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.Append("bool "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::operator!=(const "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("& other) const"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "return Handle != other.Handle;"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeEqualityOperator( + TypeName typeTypeName, + Type[] typeParams, + int cppMethodDefinitionsIndent, + bool typeIsDelegate, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.Append("bool "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::operator==(const "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("& other) const"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "return Handle == other.Handle;"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeMoveAssignmentOperator( + string bindingTypeName, + TypeName typeTypeName, + Type[] typeParams, + bool typeIsDelegate, + string releaseFuncName, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("& "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::operator=("); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("&& other)"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("Plugin::Remove"); + output.Append(bindingTypeName); + output.AppendLine("(CppHandle);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("CppHandle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t handle = Handle;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t classHandle = ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("Handle = 0;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "if (Plugin::DereferenceManagedClassNoRelease(handle))"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 3, + output); + output.Append("Plugin::"); + output.Append(releaseFuncName); + output.Append("(handle"); + if (typeIsDelegate) + { + output.Append(", classHandle"); + } + output.AppendLine(");"); + AppendCppUnhandledExceptionHandling( + cppMethodDefinitionsIndent + 3, + output); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "ClassHandle = other.ClassHandle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("other.ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("Handle = other.Handle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("other.Handle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("return *this;"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeAssignmentOperatorNullptr( + TypeName typeTypeName, + Type[] typeParams, + bool typeIsDelegate, + string releaseFuncName, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("& "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine( + "::operator=(decltype(nullptr))"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t handle = Handle;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t classHandle = ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("Handle = 0;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "if (Plugin::DereferenceManagedClassNoRelease(handle))"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 3, + output); + output.Append("Plugin::"); + output.Append(releaseFuncName); + output.Append("(handle"); + if (typeIsDelegate) + { + output.Append(", classHandle"); + } + output.AppendLine(");"); + AppendCppUnhandledExceptionHandling( + cppMethodDefinitionsIndent + 3, + output); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("Handle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("return *this;"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeAssignmentOperatorSameType( + TypeName typeTypeName, + Type[] typeParams, + bool typeIsDelegate, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("& "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::operator=(const "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("& other)"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendSetHandle( + typeTypeName, + TypeKind.Class, + typeParams, + cppMethodDefinitionsIndent + 1, + "this", + "other.Handle", + output); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "ClassHandle = other.ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("return *this;"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeDestructor( + string typeName, + TypeName typeTypeName, + Type[] typeParams, + bool typeIsDelegate, + string derivedTypeName, + string releaseFuncName, + string bindingTypeName, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::~"); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("()"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + if (!string.IsNullOrEmpty(derivedTypeName)) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("Plugin::RemoveWhole"); + output.Append(bindingTypeName); + output.AppendLine("(this);"); + } + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("Plugin::Remove"); + output.Append(typeName); + output.AppendLine("(CppHandle);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("CppHandle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t handle = Handle;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("int32_t classHandle = ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("Handle = 0;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "if (Plugin::DereferenceManagedClassNoRelease(handle))"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 3, + output); + output.Append("Plugin::"); + output.Append(releaseFuncName); + output.Append("(handle"); + if (typeIsDelegate) + { + output.Append(", classHandle"); + } + output.AppendLine(");"); + AppendCppUnhandledExceptionHandling( + cppMethodDefinitionsIndent + 3, + output); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeHandleConstructor( + string bindingTypeName, + TypeName typeTypeName, + Type[] typeParams, + Type[] interfaceTypes, + bool typeIsDelegate, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::"); + AppendCppTypeName( + typeTypeName, + output); + output.AppendLine( + "(Plugin::InternalUse, int32_t handle)"); + AppendCppConstructorInitializerList( + interfaceTypes, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("Handle = handle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("CppHandle = Plugin::Store"); + output.Append(bindingTypeName); + output.AppendLine("(this);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "Plugin::ReferenceManagedClass(Handle);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeMoveConstructor( + TypeName typeTypeName, + Type[] typeParams, + Type[] interfaceTypes, + bool typeIsDelegate, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::"); + AppendCppTypeName( + typeTypeName, + output); + output.Append("("); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("&& other)"); + AppendCppConstructorInitializerList( + interfaceTypes, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "Handle = other.Handle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "CppHandle = other.CppHandle;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "ClassHandle = other.ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("other.Handle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("other.CppHandle = 0;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("other.ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeCopyConstructor( + string typeName, + TypeName typeTypeName, + Type[] typeParams, + Type[] interfaceTypes, + bool typeIsDelegate, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::"); + AppendCppTypeName( + typeTypeName, + output); + output.Append("(const "); + AppendCppTypeFullName( + typeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.AppendLine("& other)"); + AppendCppConstructorInitializerList( + interfaceTypes, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "Handle = other.Handle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("CppHandle = Plugin::Store"); + output.Append(typeName); + output.AppendLine("(this);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "Plugin::ReferenceManagedClass(Handle);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine( + "ClassHandle = other.ClassHandle;"); + } + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeNullptrConstructor( + string typeName, + TypeName cppTypeTypeName, + Type[] typeParams, + Type[] interfaceTypes, + bool typeIsDelegate, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendIndent( + cppMethodDefinitionsIndent, + output); + AppendCppTypeName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeIsDelegate ? typeParams : null, + output); + output.Append("::"); + AppendCppTypeName( + cppTypeTypeName, + output); + output.AppendLine("(decltype(nullptr))"); + AppendCppConstructorInitializerList( + interfaceTypes, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("CppHandle = Plugin::Store"); + output.Append(typeName); + output.AppendLine("(this);"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppBaseTypeConstructor( + string bindingTypeName, + TypeName typeTypeName, + TypeKind typeKind, + string cppTypeName, + Type[] typeParams, + Type[] interfaceTypes, + ParameterInfo[] cppParameters, + ParameterInfo[] parameters, + bool typeIsDelegate, + string constructorFuncName, + int cppMethodDefinitionsIndent, + StringBuilder output) + { + AppendCppMethodDefinitionBegin( + typeTypeName, + null, + cppTypeName, + typeIsDelegate ? typeParams : null, + null, + cppParameters, + cppMethodDefinitionsIndent, + output); + AppendCppConstructorInitializerList( + interfaceTypes, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.Append("CppHandle = Plugin::Store"); + output.Append(bindingTypeName); + output.AppendLine("(this);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("System::Int32* handle = (System::Int32*)&Handle;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("int32_t cppHandle = CppHandle;"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("System::Int32* classHandle = (System::Int32*)&ClassHandle;"); + } + AppendCppPluginFunctionCall( + true, + GetTypeName(bindingTypeName, typeTypeName.Namespace), + typeKind, + typeParams, + null, + constructorFuncName, + parameters, + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("if (Handle)"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine( + "Plugin::ReferenceManagedClass(Handle);"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("else"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("{"); + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.Append("Plugin::Remove"); + output.Append(bindingTypeName); + output.AppendLine("(CppHandle);"); + if (typeIsDelegate) + { + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("ClassHandle = 0;"); + } + AppendIndent( + cppMethodDefinitionsIndent + 2, + output); + output.AppendLine("CppHandle = 0;"); + AppendIndent( + cppMethodDefinitionsIndent + 1, + output); + output.AppendLine("}"); + AppendCppUnhandledExceptionHandling( + cppMethodDefinitionsIndent + 1, + output); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine("}"); + AppendIndent( + cppMethodDefinitionsIndent, + output); + output.AppendLine();; + } + + static void AppendCppPointerFreeListInit( + Type[] typeParams, + TypeName cppTypeTypeName, + int maxSimultaneous, + string typeName, + StringBuilder output, + StringBuilder outputFirstBoot) + { + output.Append("\tPlugin::"); + output.Append(typeName); + output.Append("FreeListSize = "); + output.Append(maxSimultaneous); + output.AppendLine(";"); + + output.Append("\tPlugin::"); + output.Append(typeName); + output.Append("FreeList = ("); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("**)curMemory;"); + + output.Append("\tcurMemory += "); + output.Append(maxSimultaneous); + output.Append(" * sizeof("); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("*);"); + + output.AppendLine("\t"); + + outputFirstBoot.Append("\t\tfor (int32_t i = 0, end = Plugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.AppendLine("FreeListSize - 1; i < end; ++i)"); + outputFirstBoot.AppendLine("\t\t{"); + outputFirstBoot.Append("\t\t\tPlugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.Append("FreeList[i] = ("); + AppendCppTypeFullName( + cppTypeTypeName, + outputFirstBoot); + AppendCppTypeParameters( + typeParams, + outputFirstBoot); + outputFirstBoot.Append("*)(Plugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.AppendLine("FreeList + i + 1);"); + outputFirstBoot.AppendLine("\t\t}"); + + outputFirstBoot.Append("\t\tPlugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.Append("FreeList[Plugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.AppendLine("FreeListSize - 1] = nullptr;"); + + outputFirstBoot.Append("\t\tPlugin::NextFree"); + outputFirstBoot.Append(typeName); + outputFirstBoot.Append(" = Plugin::"); + outputFirstBoot.Append(typeName); + outputFirstBoot.AppendLine("FreeList + 1;"); + + outputFirstBoot.AppendLine("\t\t"); + } + + static void AppendCppPointerFreeListStateAndFunctions( + TypeName cppTypeTypeName, + Type[] typeParams, + string bindingTypeName, + StringBuilder output) + { + // Section comment + output.Append("\t// Free list for "); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine(" pointers"); + output.AppendLine("\t"); + + // Size variable + output.Append("\tint32_t "); + output.Append(bindingTypeName); + output.AppendLine("FreeListSize;"); + + // Free list variable + output.Append('\t'); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("** "); + output.Append(bindingTypeName); + output.AppendLine("FreeList;"); + + // Next free variable + output.Append('\t'); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("** NextFree"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.AppendLine("\t"); + + // Store function + output.Append("\tint32_t Store"); + output.Append(bindingTypeName); + output.Append('('); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("* del)"); + output.AppendLine("\t{"); + output.Append("\t\tassert(NextFree"); + output.Append(bindingTypeName); + output.AppendLine(" != nullptr);"); + output.Append("\t\t"); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("** pNext = NextFree"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.Append("\t\tNextFree"); + output.Append(bindingTypeName); + output.Append(" = ("); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("**)*pNext;"); + output.AppendLine("\t\t*pNext = del;"); + output.Append("\t\treturn (int32_t)(pNext - "); + output.Append(bindingTypeName); + output.AppendLine("FreeList);"); + output.AppendLine("\t}"); + output.AppendLine("\t"); + + // Get function + output.Append('\t'); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("* Get"); + output.Append(bindingTypeName); + output.AppendLine("(int32_t handle)"); + output.AppendLine("\t{"); + output.Append( + "\t\tassert(handle >= 0 && handle < "); + output.Append(bindingTypeName); + output.AppendLine("FreeListSize);"); + output.Append("\t\treturn "); + output.Append(bindingTypeName); + output.AppendLine("FreeList[handle];"); + output.AppendLine("\t}"); + output.AppendLine("\t"); + + // Remove function + output.Append("\tvoid Remove"); + output.Append(bindingTypeName); + output.AppendLine("(int32_t handle)"); + output.AppendLine("\t{"); + output.Append("\t\t"); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("** pRelease = "); + output.Append(bindingTypeName); + output.AppendLine("FreeList + handle;"); + output.Append("\t\t*pRelease = ("); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("*)NextFree"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.Append("\t\tNextFree"); + output.Append(bindingTypeName); + output.AppendLine(" = pRelease;"); + output.AppendLine("\t}"); + output.AppendLine("\t"); + } + + static void AppendCppWholeObjectFreeListInit( + int maxSimultaneous, + string bindingTypeName, + StringBuilder output, + StringBuilder outputFirstBoot) + { + output.Append("\tPlugin::"); + output.Append(bindingTypeName); + output.Append("FreeWholeListSize = "); + output.Append(maxSimultaneous); + output.AppendLine(";"); + + output.Append("\tPlugin::"); + output.Append(bindingTypeName); + output.Append("FreeWholeList = (Plugin::"); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListEntry*)curMemory;"); + + output.Append("\tcurMemory += "); + output.Append(maxSimultaneous); + output.Append(" * sizeof(Plugin::"); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListEntry);"); + + output.AppendLine("\t"); + + outputFirstBoot.Append("\t\tfor (int32_t i = 0, end = Plugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.AppendLine("FreeWholeListSize - 1; i < end; ++i)"); + outputFirstBoot.AppendLine("\t\t{"); + outputFirstBoot.Append("\t\t\tPlugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.Append("FreeWholeList[i].Next = Plugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.AppendLine("FreeWholeList + i + 1;"); + outputFirstBoot.AppendLine("\t\t}"); + + outputFirstBoot.Append("\t\tPlugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.Append("FreeWholeList[Plugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.AppendLine("FreeWholeListSize - 1].Next = nullptr;"); + + outputFirstBoot.Append("\t\tPlugin::NextFreeWhole"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.Append(" = Plugin::"); + outputFirstBoot.Append(bindingTypeName); + outputFirstBoot.AppendLine("FreeWholeList + 1;"); + + outputFirstBoot.AppendLine("\t\t"); + } + + static void AppendCppWholeObjectFreeListStateAndFunctions( + Type[] typeParams, + TypeName cppTypeTypeName, + string bindingTypeName, + StringBuilder output) + { + // Section comment + output.Append("\t// Free list for whole "); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine(" objects"); + output.AppendLine("\t"); + + // Union with a pointer and a whole object + output.Append("\tunion "); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListEntry"); + output.AppendLine("\t{"); + output.Append("\t\t"); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListEntry* Next;"); + output.Append("\t\t"); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine(" Value;"); + output.AppendLine("\t};"); + + // Size + output.Append("\tint32_t "); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListSize;"); + + // Free list entries + output.Append('\t'); + output.Append(bindingTypeName); + output.Append("FreeWholeListEntry* "); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeList;"); + + // Pointer to next free entry + output.Append('\t'); + output.Append(bindingTypeName); + output.Append("FreeWholeListEntry* NextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.AppendLine("\t"); + + // Store function + output.Append('\t'); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("* StoreWhole"); + output.Append(bindingTypeName); + output.AppendLine("()"); + output.AppendLine("\t{"); + output.Append("\t\tassert(NextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(" != nullptr);"); + output.Append("\t\t"); + output.Append(bindingTypeName); + output.Append("FreeWholeListEntry* pNext = NextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.Append("\t\tNextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(" = pNext->Next;"); + output.AppendLine("\t\treturn &pNext->Value;"); + output.AppendLine("\t}"); + output.AppendLine("\t"); + + // Remove function + output.Append("\tvoid RemoveWhole"); + output.Append(bindingTypeName); + output.Append('('); + AppendCppTypeFullName( + cppTypeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("* instance)"); + output.AppendLine("\t{"); + output.Append("\t\t"); + output.Append(bindingTypeName); + output.Append("FreeWholeListEntry* pRelease = ("); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListEntry*)instance;"); + output.Append("\t\tif (pRelease >= "); + output.Append(bindingTypeName); + output.Append("FreeWholeList && pRelease < "); + output.Append(bindingTypeName); + output.Append("FreeWholeList + ("); + output.Append(bindingTypeName); + output.AppendLine("FreeWholeListSize - 1))"); + output.AppendLine("\t\t{"); + output.Append("\t\t\tpRelease->Next = NextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(";"); + output.Append("\t\t\tNextFreeWhole"); + output.Append(bindingTypeName); + output.AppendLine(" = pRelease->Next;"); + output.AppendLine("\t\t}"); + output.AppendLine("\t}"); + output.AppendLine("\t"); + } + + static void AppendCsharpDelegate( + bool isStatic, + TypeName typeTypeName, + Type[] typeParams, + string funcName, + ParameterInfo[] parameters, + Type returnType, + TypeKind returnTypeKind, + StringBuilder output) + { + output.AppendLine("\t\t[UnmanagedFunctionPointer(CallingConvention.Cdecl)]"); + output.Append("\t\tpublic delegate "); + if (returnType == typeof(void)) + { + output.Append("void"); + } + else + { + switch (returnTypeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + output.Append("int"); + break; + default: + AppendCsharpTypeFullName( + returnType, + output); + break; + } + } + output.Append(' '); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.Append("DelegateType("); + if (!isStatic) + { + output.Append("int thisHandle"); + if (parameters.Length > 0) + { + output.Append(", "); + } + } + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo param = parameters[i]; + switch (param.Kind) + { + case TypeKind.FullStruct: + case TypeKind.Primitive: + case TypeKind.Enum: + AppendCsharpTypeFullName( + param.ParameterType, + output); + output.Append(" param"); + output.Append(i); + break; + default: + output.Append("int param"); + output.Append(i); + break; + } + if (i != parameters.Length-1) + { + output.Append(", "); + } + } + output.AppendLine(");"); + output.Append("\t\tpublic static "); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.Append("DelegateType "); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.AppendLine(";"); + output.AppendLine("\t\t"); + } + + static void AppendCsharpDelegateName( + TypeName typeTypeName, + Type[] typeParams, + string funcName, + StringBuilder output) + { + AppendNamespace( + typeTypeName.Namespace, + string.Empty, + output); + AppendTypeNameWithoutSuffixes( + typeTypeName.Name, + output); + AppendTypeNames( + typeParams, + output); + output.Append(funcName); + } + + static void AppendCsharpGetDelegateCall( + TypeName typeTypeName, + Type[] typeParams, + string funcName, + StringBuilder output) + { + output.Append("\t\t\t"); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.Append(" = GetDelegate<"); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.Append("DelegateType>(libraryHandle, \""); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.AppendLine("\");"); + } + + static void AppendCsharpImport( + TypeName typeTypeName, + Type[] typeParams, + string funcName, + ParameterInfo[] parameters, + Type returnType, + StringBuilder output + ) + { + output.AppendLine("\t\t[DllImport(PLUGIN_NAME, CallingConvention = CallingConvention.Cdecl)]"); + output.Append("\t\tpublic static extern "); + AppendCsharpTypeFullName(returnType, output); + output.Append(' '); + AppendCsharpDelegateName( + typeTypeName, + typeParams, + funcName, + output); + output.Append("(int thisHandle"); + if (parameters.Length > 0) + { + output.Append(", "); + } + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo param = parameters[i]; + switch (param.Kind) + { + case TypeKind.FullStruct: + case TypeKind.Primitive: + case TypeKind.Enum: + AppendCsharpTypeFullName( + param.ParameterType, + output); + output.Append(" param"); + output.Append(i); + break; + default: + output.Append("int param"); + output.Append(i); + break; + } + if (i != parameters.Length-1) + { + output.Append(", "); + } + } + output.AppendLine(");"); + output.AppendLine("\t\t"); + } + + static void AppendExceptions( + JsonDocument doc, + Assembly[] assemblies, + StringBuilders builders) + { + // Gather all specific types of exceptions + Dictionary exceptionTypes = new Dictionary(); + if (doc.Types != null) + { + foreach (JsonType jsonType in doc.Types) + { + if (jsonType.Methods != null) + { + foreach (JsonMethod jsonMethod in jsonType.Methods) { - if (method.ReturnType.Namespace + "." + method.ReturnType.Name != returnTypeName) + if (jsonMethod.Exceptions != null) { - continue; + AddUniqueTypes( + jsonMethod.Exceptions, + exceptionTypes, + assemblies); } } } - System.Reflection.ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; ++i) + if (jsonType.Constructors != null) { - Type paramType = parameters[i].ParameterType; - if (string.IsNullOrEmpty(paramType.Namespace)) + foreach (JsonConstructor jsonCtor in jsonType.Constructors) { - if (paramType.Name != paramTypeNames[i]) + if (jsonCtor.Exceptions != null) { - goto mismatch; + AddUniqueTypes( + jsonCtor.Exceptions, + exceptionTypes, + assemblies); } } - else + } + if (jsonType.Properties != null) + { + foreach (JsonProperty jsonProperty in jsonType.Properties) { - if (paramType.Namespace + "." + paramType.Name != paramTypeNames[i]) + JsonPropertyGet jsonPropertyGet = jsonProperty.Get; + if (jsonPropertyGet != null + && jsonPropertyGet.Exceptions != null) + { + AddUniqueTypes( + jsonPropertyGet.Exceptions, + exceptionTypes, + assemblies); + } + JsonPropertySet jsonPropertySet = jsonProperty.Set; + if (jsonPropertySet != null + && jsonPropertySet.Exceptions != null) { - goto mismatch; + AddUniqueTypes( + jsonPropertySet.Exceptions, + exceptionTypes, + assemblies); } } } - return method; - mismatch:; } } - return null; - } - - static void AppendTypeNames( - Type[] types, - StringBuilder output) - { - for (int i = 0, len = types.Length; i < len; ++i) + + foreach (Type exceptionType in exceptionTypes.Values) { - Type type = types[i]; - AppendNamespace(type.Namespace, string.Empty, output); - output.Append(type.Name); - if (i != len - 1) - { - output.Append('_'); - } + // Build function name + builders.TempStrBuilder.Length = 0; + AppendCsharpSetCsharpExceptionFunctionName( + exceptionType, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); + + // C++ thrower type + int throwerIndent = AppendNamespaceBeginning( + exceptionType.Namespace, + builders.CppMethodDefinitions); + AppendIndent( + throwerIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append("struct "); + builders.CppMethodDefinitions.Append(exceptionType.Name); + builders.CppMethodDefinitions.Append("Thrower : "); + AppendCppTypeFullName( + exceptionType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + AppendIndent( + throwerIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(exceptionType.Name); + builders.CppMethodDefinitions.AppendLine("Thrower(int32_t handle)"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(": System::Runtime::InteropServices::_Exception(nullptr)"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(", System::Runtime::Serialization::ISerializable(nullptr)"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(", System::Exception(nullptr)"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine(", System::SystemException(nullptr)"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.Append(", "); + AppendCppTypeFullName( + exceptionType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("(Plugin::InternalUse::Only, handle)"); + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + throwerIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("virtual void ThrowReferenceToThis()"); + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); + AppendIndent( + throwerIndent + 2, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("throw *this;"); + AppendIndent( + throwerIndent + 1, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent( + throwerIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("};"); + AppendNamespaceEnding( + throwerIndent, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; + + // C++ function + builders.CppMethodDefinitions.Append("DLLEXPORT void "); + builders.CppMethodDefinitions.Append(funcName); + builders.CppMethodDefinitions.AppendLine("(int32_t handle)"); + builders.CppMethodDefinitions.AppendLine("{"); + builders.CppMethodDefinitions.AppendLine("\tdelete Plugin::unhandledCsharpException;"); + builders.CppMethodDefinitions.Append("\tPlugin::unhandledCsharpException = new "); + AppendCppTypeFullName( + exceptionType, + builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("Thrower(handle);"); + builders.CppMethodDefinitions.AppendLine("}"); + builders.CppMethodDefinitions.AppendLine(); + + // Build parameters + ParameterInfo[] parameters = ConvertParameters( + new[]{ typeof(int) }); + + // C# imports + AppendCsharpImport( + GetTypeName(string.Empty, string.Empty), + null, + funcName, + ConvertParameters(Type.EmptyTypes), + typeof(void), + builders.CsharpImports); + + // C# delegate + AppendCsharpDelegate( + true, + GetTypeName(string.Empty, string.Empty), + null, + funcName, + parameters, + typeof(void), + TypeKind.None, + builders.CsharpCppDelegates + ); + + // C# GetDelegate call + AppendCsharpGetDelegateCall( + GetTypeName(string.Empty, string.Empty), + null, + funcName, + builders.CsharpGetDelegateCalls); } } - static void AppendNamespace( - string namespaceName, - string separator, - StringBuilder output) + static void AddUniqueTypes( + string[] typeNames, + Dictionary types, + Assembly[] assemblies) { - int startIndex = 0; - if (!string.IsNullOrEmpty(namespaceName)) + foreach (string typeName in typeNames) { - do + if (!types.ContainsKey(typeName)) { - int dotIndex = namespaceName.IndexOf( - '.', - startIndex); - if (dotIndex < 0) - { - break; - } - output.Append( - namespaceName, - startIndex, - dotIndex - startIndex); - output.Append(separator); - startIndex = dotIndex + 1; + Type type = GetType( + typeName, + assemblies); + types.Add( + typeName, + type); } - while (true); - output.Append( - namespaceName, - startIndex, - namespaceName.Length - startIndex); - } - } - - static ParameterInfo[] ConvertParameters( - System.Reflection.ParameterInfo[] reflectionParameters) - { - int num = reflectionParameters.Length; - ParameterInfo[] parameters = new ParameterInfo[num]; - for (int i = 0; i < num; ++i) - { - var reflectionInfo = reflectionParameters[i]; - ParameterInfo info = new ParameterInfo(); - info.Name = reflectionInfo.Name; - info.ParameterType = reflectionInfo.ParameterType; - parameters[i] = info; - } - return parameters; - } - - static ParameterInfo[] ConvertParameters( - Type[] paramTypes) - { - int num = paramTypes.Length; - ParameterInfo[] parameters = new ParameterInfo[num]; - for (int i = 0; i < num; ++i) - { - Type paramType = paramTypes[i]; - ParameterInfo info = new ParameterInfo(); - info.Name = "param" + i; - info.ParameterType = paramType; - parameters[i] = info; } - return parameters; } static void AppendGetter( string fieldName, - string enclosingTypeNameLower, string syntaxType, ParameterInfo[] parameters, - bool isStatic, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + bool methodIsStatic, + bool isReadOnly, Type enclosingType, + Type[] enclosingTypeParams, Type fieldType, + TypeKind fieldTypeKind, int indent, - StringBuilders stringBuilders) + Type[] exceptionTypes, + StringBuilders builders) { - // Build uppercased field name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(char.ToUpper(fieldName[0])); - stringBuilders.TempStrBuilder.Append( + // Build uppercase field name + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(char.ToUpper(fieldName[0])); + builders.TempStrBuilder.Append( fieldName, 1, fieldName.Length-1); - string fieldNameUpper = stringBuilders.TempStrBuilder.ToString(); + string fieldNameUpper = builders.TempStrBuilder.ToString(); // Build uppercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(enclosingType.Name); - stringBuilders.TempStrBuilder.Append(syntaxType); - stringBuilders.TempStrBuilder.Append("Get"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string funcName = stringBuilders.TempStrBuilder.ToString(); - - // Build lowercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(enclosingTypeNameLower); - stringBuilders.TempStrBuilder.Append(syntaxType); - stringBuilders.TempStrBuilder.Append("Get"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string funcNameLower = stringBuilders.TempStrBuilder.ToString(); + builders.TempStrBuilder.Length = 0; + AppendFieldPropertyFuncName( + GetTypeName(enclosingType), + enclosingTypeParams, + syntaxType, + "Get", + fieldName, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); // Build method name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append("Get"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string methodName = stringBuilders.TempStrBuilder.ToString(); + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Get"); + builders.TempStrBuilder.Append(fieldNameUpper); + string methodName = builders.TempStrBuilder.ToString(); // C# init param declaration - AppendCsharpInitParam( - funcNameLower, - stringBuilders.CsharpInitParams); // C# delegate type AppendCsharpDelegateType( funcName, - isStatic, + methodIsStatic, + enclosingType, + enclosingTypeKind, fieldType, parameters, - stringBuilders.CsharpDelegateTypes); + builders.CsharpDelegateTypes); // C# init call param - AppendCsharpInitCallArg( + AppendCsharpCsharpDelegate( funcName, - stringBuilders.CsharpInitCall); + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); // C# function AppendCsharpFunctionBeginning( enclosingType, funcName, - isStatic, + methodIsStatic, + enclosingTypeKind, fieldType, - null, parameters, - stringBuilders.CsharpFunctions); + builders.CsharpFunctions); AppendCsharpFunctionCallSubject( enclosingType, - isStatic, - stringBuilders.CsharpFunctions); - stringBuilders.CsharpFunctions.Append(fieldName); - stringBuilders.CsharpFunctions.Append(';'); + methodIsStatic, + builders.CsharpFunctions); + if (parameters.Length > 0) + { + builders.CsharpFunctions.Append('['); + for (int i = 0; i < parameters.Length; ++i) + { + builders.CsharpFunctions.Append(parameters[0].Name); + if (i != parameters.Length-1) + { + builders.CsharpFunctions.Append(", "); + } + } + builders.CsharpFunctions.Append("]"); + } + else + { + builders.CsharpFunctions.Append('.'); + builders.CsharpFunctions.Append(fieldName); + } + builders.CsharpFunctions.Append(';'); + if (!isReadOnly + && !methodIsStatic + && enclosingTypeKind == TypeKind.ManagedStruct) + { + AppendStructStoreReplace( + enclosingType, + "thisHandle", + "thiz", + builders.CsharpFunctions); + } AppendCsharpFunctionReturn( + parameters, fieldType, - stringBuilders.CsharpFunctions); + fieldTypeKind, + exceptionTypes, + false, + builders.CsharpFunctions); // C++ function pointer AppendCppFunctionPointerDefinition( funcName, - isStatic, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, parameters, fieldType, - stringBuilders.CppFunctionPointers); + builders.CppFunctionPointers); // C++ method declaration - AppendIndent(indent + 1, stringBuilders.CppTypeDefinitions); + AppendIndent(indent + 1, builders.CppTypeDefinitions); AppendCppMethodDeclaration( methodName, - isStatic, + enclosingTypeIsStatic, + false, + methodIsStatic, fieldType, null, parameters, - stringBuilders.CppTypeDefinitions); + builders.CppTypeDefinitions); // C++ method definition - AppendCppMethodDefinition( - enclosingType, + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), fieldType, methodName, + enclosingTypeParams, null, parameters, indent, - stringBuilders.CppMethodDefinitions); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("{\n"); - AppendIndent(indent + 1, stringBuilders.CppMethodDefinitions); - AppendCppMethodReturn( - fieldType, - stringBuilders.CppMethodDefinitions); + builders.CppMethodDefinitions); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); AppendCppPluginFunctionCall( - isStatic, + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + enclosingTypeParams, fieldType, funcName, parameters, - stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append(";\n"); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("}\n"); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("\n"); - - // C++ init params - AppendCppInitParam( - funcNameLower, - isStatic, - parameters, + indent + 1, + builders.CppMethodDefinitions); + AppendCppMethodReturn( fieldType, - stringBuilders.CppInitParams); + fieldTypeKind, + indent + 1, + builders.CppMethodDefinitions); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; // C++ init body - AppendCppInitBody( + AppendCppInitBodyFunctionPointerParameterRead( funcName, - funcNameLower, - stringBuilders.CppInitBody); + methodIsStatic, + GetTypeName(enclosingType), + enclosingTypeKind, + parameters, + fieldType, + builders.CppInitBodyParameterReads); } static void AppendSetter( string fieldName, string syntaxType, - string enclosingTypeNameLower, ParameterInfo[] parameters, - bool isStatic, + bool enclosingTypeIsStatic, + TypeKind enclosingTypeKind, + bool methodIsStatic, + bool isReadOnly, Type enclosingType, - Type fieldType, + Type[] enclosingTypeParams, int indent, - StringBuilders stringBuilders) + Type[] exceptionTypes, + StringBuilders builders) { + TypeName enclosingTypeTypeName = GetTypeName(enclosingType); + // Build uppercased field name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(char.ToUpper(fieldName[0])); - stringBuilders.TempStrBuilder.Append( + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append(char.ToUpper(fieldName[0])); + builders.TempStrBuilder.Append( fieldName, 1, fieldName.Length-1); - string fieldNameUpper = stringBuilders.TempStrBuilder.ToString(); + string fieldNameUpper = builders.TempStrBuilder.ToString(); // Build uppercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(enclosingType.Name); - stringBuilders.TempStrBuilder.Append(syntaxType); - stringBuilders.TempStrBuilder.Append("Set"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string funcName = stringBuilders.TempStrBuilder.ToString(); - - // Build lowercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(enclosingTypeNameLower); - stringBuilders.TempStrBuilder.Append(syntaxType); - stringBuilders.TempStrBuilder.Append("Set"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string funcNameLower = stringBuilders.TempStrBuilder.ToString(); + builders.TempStrBuilder.Length = 0; + AppendFieldPropertyFuncName( + enclosingTypeTypeName, + enclosingTypeParams, + syntaxType, + "Set", + fieldName, + builders.TempStrBuilder); + string funcName = builders.TempStrBuilder.ToString(); // Build method name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append("Set"); - stringBuilders.TempStrBuilder.Append(fieldNameUpper); - string methodName = stringBuilders.TempStrBuilder.ToString(); + builders.TempStrBuilder.Length = 0; + builders.TempStrBuilder.Append("Set"); + builders.TempStrBuilder.Append(fieldNameUpper); + string methodName = builders.TempStrBuilder.ToString(); // C# init param declaration - AppendCsharpInitParam( - funcNameLower, - stringBuilders.CsharpInitParams); - + // C# delegate type AppendCsharpDelegateType( funcName, - isStatic, + methodIsStatic, + enclosingType, + enclosingTypeKind, typeof(void), parameters, - stringBuilders.CsharpDelegateTypes); + builders.CsharpDelegateTypes); // C# init call param - AppendCsharpInitCallArg( + AppendCsharpCsharpDelegate( funcName, - stringBuilders.CsharpInitCall); + builders.CsharpInitCall, + builders.CsharpCsharpDelegates); // C# function AppendCsharpFunctionBeginning( enclosingType, funcName, - isStatic, + methodIsStatic, + enclosingTypeKind, typeof(void), - null, parameters, - stringBuilders.CsharpFunctions); + builders.CsharpFunctions); AppendCsharpFunctionCallSubject( enclosingType, - isStatic, - stringBuilders.CsharpFunctions); - stringBuilders.CsharpFunctions.Append(fieldName); - stringBuilders.CsharpFunctions.Append(" = "); - if (fieldType.IsValueType) + methodIsStatic, + builders.CsharpFunctions); + if (parameters.Length > 1) { - stringBuilders.CsharpFunctions.Append("value;"); + builders.CsharpFunctions.Append('['); + for (int i = 0, end = parameters.Length-1; i < end; ++i) + { + builders.CsharpFunctions.Append(parameters[i].Name); + if (i != end-1) + { + builders.CsharpFunctions.Append(", "); + } + } + builders.CsharpFunctions.Append("] = "); + builders.CsharpFunctions.Append(parameters[1].Name); } else { - stringBuilders.CsharpFunctions.Append('('); - AppendCsharpTypeName( - fieldType, - stringBuilders.CsharpFunctions); - stringBuilders.CsharpFunctions.Append( - ")ObjectStore.Get(valueHandle);"); + builders.CsharpFunctions.Append('.'); + builders.CsharpFunctions.Append(fieldName); + builders.CsharpFunctions.Append(" = "); + builders.CsharpFunctions.Append("value"); + } + builders.CsharpFunctions.Append(';'); + if (!isReadOnly + && !methodIsStatic + && enclosingTypeKind == TypeKind.ManagedStruct) + { + AppendStructStoreReplace( + enclosingType, + "thisHandle", + "thiz", + builders.CsharpFunctions); } AppendCsharpFunctionReturn( + parameters, typeof(void), - stringBuilders.CsharpFunctions); + TypeKind.None, + exceptionTypes, + false, + builders.CsharpFunctions); // C++ function pointer AppendCppFunctionPointerDefinition( funcName, - isStatic, + methodIsStatic, + enclosingTypeTypeName, + enclosingTypeKind, parameters, typeof(void), - stringBuilders.CppFunctionPointers); + builders.CppFunctionPointers); // C++ method declaration - AppendIndent(indent + 1, stringBuilders.CppTypeDefinitions); + AppendIndent(indent + 1, builders.CppTypeDefinitions); AppendCppMethodDeclaration( methodName, - isStatic, + enclosingTypeIsStatic, + false, + methodIsStatic, typeof(void), null, parameters, - stringBuilders.CppTypeDefinitions); + builders.CppTypeDefinitions); // C++ method definition - AppendCppMethodDefinition( - enclosingType, + AppendCppMethodDefinitionBegin( + GetTypeName(enclosingType), typeof(void), methodName, + enclosingTypeParams, null, parameters, indent, - stringBuilders.CppMethodDefinitions); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("{\n"); - AppendIndent(indent + 1, stringBuilders.CppMethodDefinitions); + builders.CppMethodDefinitions); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("{"); AppendCppPluginFunctionCall( - isStatic, - typeof(void), - funcName, - parameters, - stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append(";\n"); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("}\n"); - AppendIndent(indent, stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append('\n'); - - // C++ init params - AppendCppInitParam( - funcNameLower, - isStatic, - parameters, - typeof(void), - stringBuilders.CppInitParams); - - // C++ init body - AppendCppInitBody( - funcName, - funcNameLower, - stringBuilders.CppInitBody); - } - - static void AppendMethod( - Type type, - string typeNameLower, - string methodName, - bool isStatic, - Type returnType, - Type[] typeParameters, - ParameterInfo[] parameters, - Type[] paramTypes, - int indent, - StringBuilders stringBuilders) - { - // Build uppercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(type.Name); - stringBuilders.TempStrBuilder.Append("Method"); - stringBuilders.TempStrBuilder.Append(methodName); - AppendTypeNames(paramTypes, stringBuilders.TempStrBuilder); - if (typeParameters != null) - { - foreach (Type typeParam in typeParameters) - { - AppendNamespace( - typeParam.Namespace, - string.Empty, - stringBuilders.TempStrBuilder); - stringBuilders.TempStrBuilder.Append(typeParam.Name); - } - } - string funcName = stringBuilders.TempStrBuilder.ToString(); - - // Build lowercase function name - stringBuilders.TempStrBuilder.Length = 0; - stringBuilders.TempStrBuilder.Append(typeNameLower); - stringBuilders.TempStrBuilder.Append("Method"); - stringBuilders.TempStrBuilder.Append(methodName); - AppendTypeNames(paramTypes, stringBuilders.TempStrBuilder); - if (typeParameters != null) - { - foreach (Type typeParam in typeParameters) - { - AppendNamespace( - typeParam.Namespace, - string.Empty, - stringBuilders.TempStrBuilder); - stringBuilders.TempStrBuilder.Append(typeParam.Name); - } - } - string funcNameLower = stringBuilders.TempStrBuilder.ToString(); - - // C# init param declaration - AppendCsharpInitParam( - funcNameLower, - stringBuilders.CsharpInitParams); - - // C# delegate type - AppendCsharpDelegateType( - funcName, - isStatic, - returnType, - parameters, - stringBuilders.CsharpDelegateTypes); - - // C# init call param - AppendCsharpInitCallArg( - funcName, - stringBuilders.CsharpInitCall); - - // C# function - AppendCsharpFunctionBeginning( - type, - funcName, - isStatic, - returnType, - typeParameters, - parameters, - stringBuilders.CsharpFunctions); - AppendCsharpFunctionCallSubject( - type, - isStatic, - stringBuilders.CsharpFunctions); - stringBuilders.CsharpFunctions.Append(methodName); - if (typeParameters != null) - { - stringBuilders.CsharpFunctions.Append('<'); - for (int i = 0; i < typeParameters.Length; ++i) - { - Type typeParam = typeParameters[i]; - AppendCsharpTypeName( - typeParam, - stringBuilders.CsharpFunctions); - if (i != typeParameters.Length - 1) - { - stringBuilders.CsharpFunctions.Append(", "); - } - } - stringBuilders.CsharpFunctions.Append('>'); - } - AppendCsharpFunctionCallParameters( - isStatic, - parameters, - stringBuilders.CsharpFunctions); - stringBuilders.CsharpFunctions.Append(';'); - AppendCsharpFunctionReturn( - returnType, - stringBuilders.CsharpFunctions); - - // C++ function pointer - AppendCppFunctionPointerDefinition( + methodIsStatic, + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + null, funcName, - isStatic, - parameters, - returnType, - stringBuilders.CppFunctionPointers); - - // C++ method declaration - AppendIndent( - indent + 1, - stringBuilders.CppTypeDefinitions); - AppendCppMethodDeclaration( - methodName, - isStatic, - returnType, - typeParameters, - parameters, - stringBuilders.CppTypeDefinitions); - - // C++ method definition - AppendCppMethodDefinition( - type, - returnType, - methodName, - typeParameters, parameters, - indent, - stringBuilders.CppMethodDefinitions); - AppendIndent( - indent, - stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("{\n"); - AppendIndent( indent + 1, - stringBuilders.CppMethodDefinitions); - AppendCppMethodReturn( - returnType, - stringBuilders.CppMethodDefinitions); - AppendCppPluginFunctionCall( - isStatic, - returnType, - funcName, - parameters, - stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append(";\n"); - AppendIndent( - indent, - stringBuilders.CppMethodDefinitions); - stringBuilders.CppMethodDefinitions.Append("}\n\t\n"); - - // C++ init params - AppendCppInitParam( - funcNameLower, - isStatic, - parameters, - returnType, - stringBuilders.CppInitParams); + builders.CppMethodDefinitions); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine("}"); + AppendIndent(indent, builders.CppMethodDefinitions); + builders.CppMethodDefinitions.AppendLine();; // C++ init body - AppendCppInitBody( + AppendCppInitBodyFunctionPointerParameterRead( funcName, - funcNameLower, - stringBuilders.CppInitBody); + methodIsStatic, + enclosingTypeTypeName, + enclosingTypeKind, + parameters, + typeof(void), + builders.CppInitBodyParameterReads); + } + + static void AppendFieldPropertyFuncName( + TypeName enclosingTypeTypeName, + Type[] enclosingTypeParams, + string syntaxType, + string operationType, + string fieldName, + StringBuilder output) + { + AppendNamespace( + enclosingTypeTypeName.Namespace, + string.Empty, + output); + AppendTypeNameWithoutGenericSuffix( + enclosingTypeTypeName.Name, + output); + AppendTypeNames( + enclosingTypeParams, + output); + output.Append(syntaxType); + output.Append(operationType); + output.Append(char.ToUpper(fieldName[0])); + output.Append(fieldName, 1, fieldName.Length-1); + } + + static void AppendCppTemplateDeclaration( + TypeName typeTypeName, + StringBuilder output) + { + int indent = AppendNamespaceBeginning( + typeTypeName.Namespace, + output); + AppendIndent( + indent, + output); + AppendCppTemplateTypenames( + typeTypeName.NumTypeParams, + 'T', + output); + output.Append("struct "); + AppendCppTypeName( + typeTypeName, + output); + output.Append(";"); + output.AppendLine();; + AppendNamespaceEnding( + indent, + output); + output.AppendLine();; } static int AppendCppTypeDeclaration( - string typeNamespace, - string typeName, + TypeName typeTypeName, bool isStatic, - StringBuilder output - ) + Type[] typeParams, + StringBuilder output) { int indent = AppendNamespaceBeginning( - typeNamespace, + typeTypeName.Namespace, output); AppendIndent(indent, output); if (isStatic) { output.Append("namespace "); - output.Append(typeName); - output.Append('\n'); + AppendTypeNameWithoutGenericSuffix( + typeTypeName.Name, + output); + output.AppendLine();; AppendIndent(indent, output); - output.Append("{\n"); + output.AppendLine("{"); AppendIndent(indent, output); output.Append('}'); } else { + if (typeParams != null) + { + output.Append("template<> "); + } output.Append("struct "); - output.Append(typeName); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); output.Append(";"); } - output.Append('\n'); + output.AppendLine();; AppendNamespaceEnding( indent, output); - output.Append('\n'); + output.AppendLine();; return indent; } static void AppendCppTypeDefinitionBegin( - string typeNamespace, - string typeName, - string baseTypeNamespace, - string baseTypeName, + TypeName typeTypeName, + TypeKind typeKind, + Type[] typeParams, + TypeName baseTypeTypeName, + Type[] baseTypeTypeParams, + Type[] interfaceTypes, bool isStatic, int indent, - StringBuilder output - ) + StringBuilder output) { AppendNamespaceBeginning( - typeNamespace, + typeTypeName.Namespace, output); AppendIndent( indent, @@ -1770,113 +11294,714 @@ StringBuilder output if (isStatic) { output.Append("namespace "); - output.Append(typeName); + AppendTypeNameWithoutGenericSuffix( + typeTypeName.Name, + output); } else { + if (typeParams != null) + { + output.Append("template<> "); + } output.Append("struct "); - output.Append(typeName); - output.Append(" : "); - output.Append(baseTypeNamespace); - output.Append("::"); - output.Append(baseTypeName); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters(typeParams, output); + switch (typeKind) + { + case TypeKind.Class: + // Only add the base type if it's not System.Object or + // there are no interfaces (since they always extend it) + string separator = " : virtual "; + if ( + (baseTypeTypeName.Name != null && + (baseTypeTypeName.Namespace != "System" || + baseTypeTypeName.Name != "Object")) || + (interfaceTypes == null || + interfaceTypes.Length == 0)) + { + output.Append(separator); + separator = ", virtual "; + AppendCppTypeFullName( + GetTypeName( + baseTypeTypeName.Name ?? "Object", + baseTypeTypeName.Namespace ?? "System", + baseTypeTypeParams != null ? baseTypeTypeParams.Length : 0), + output); + AppendCppTypeParameters( + baseTypeTypeParams, + output); + } + if (interfaceTypes != null) + { + foreach (Type interfaceType in interfaceTypes) + { + output.Append(separator); + separator = ", virtual "; + AppendCppTypeFullName( + GetTypeName(interfaceType), + output); + AppendCppTypeParameters( + interfaceType.GetGenericArguments(), + output); + } + } + break; + case TypeKind.ManagedStruct: + output.Append(" : Plugin::ManagedType"); + break; + } } - output.Append('\n'); + output.AppendLine();; AppendIndent( indent, output); - output.Append("{\n"); + output.AppendLine("{"); if (!isStatic) { - AppendIndent( - indent + 1, - output); - AppendSystemObjectLifecycleCall( - "SYSTEM_OBJECT_LIFECYCLE_DECLARATION", - typeName, - baseTypeNamespace, - baseTypeName, - output); - output.Append('\n'); + switch (typeKind) + { + case TypeKind.Class: + case TypeKind.ManagedStruct: + // Constructor from nullptr + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + output.AppendLine("(decltype(nullptr));"); + + // Constructor from handle + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + output.AppendLine( + "(Plugin::InternalUse, int32_t handle);"); + + // Copy constructor + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + output.Append("(const "); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("& other);"); + + // Move constructor + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + output.Append('('); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("&& other);"); + + // Destructor + AppendIndent(indent + 1, output); + output.Append("virtual ~"); + AppendCppTypeName( + typeTypeName, + output); + output.AppendLine("();"); + + // Assignment operator to same type + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("& operator=(const "); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("& other);"); + + // Assignment operator to nullptr + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("& operator=(decltype(nullptr));"); + + // Move assignment operator to same type + AppendIndent(indent + 1, output); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.Append("& operator=("); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("&& other);"); + + // Equality operator with same type + AppendIndent(indent + 1, output); + output.Append("bool operator==(const "); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("& other) const;"); + + // Inequality operator with same type + AppendIndent(indent + 1, output); + output.Append("bool operator!=(const "); + AppendCppTypeName( + typeTypeName, + output); + AppendCppTypeParameters( + typeParams, + output); + output.AppendLine("& other) const;"); + break; + } } } static void AppendCppTypeDefinitionEnd( bool isStatic, int indent, - StringBuilder cppTypeDefinitions - ) + StringBuilder output) { AppendIndent( indent, - cppTypeDefinitions); - cppTypeDefinitions.Append('}'); + output); + output.Append('}'); if (!isStatic) { - cppTypeDefinitions.Append(';'); + output.Append(';'); } - cppTypeDefinitions.Append('\n'); + output.AppendLine();; AppendNamespaceEnding( indent, - cppTypeDefinitions); - cppTypeDefinitions.Append('\n'); + output); + output.AppendLine();; } - static int AppendCppMethodDefinitionBegin( - string typeNamespace, - string typeName, - string baseTypeNamespace, - string baseTypeName, + static int AppendCppMethodDefinitionsBegin( + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + Type[] enclosingTypeParams, + Type[] interfaceTypes, bool isStatic, + Action extraDefault, + Action extraCopy, int indent, StringBuilder output) { int cppMethodDefinitionsIndent = AppendNamespaceBeginning( - typeNamespace, + enclosingTypeTypeName.Namespace, output); - if (!isStatic) + if (!isStatic && ( + enclosingTypeKind == TypeKind.Class + || enclosingTypeKind == TypeKind.ManagedStruct)) { + // Construct with nullptr AppendIndent(indent, output); - AppendSystemObjectLifecycleCall( - "SYSTEM_OBJECT_LIFECYCLE_DEFINITION", - typeName, - baseTypeNamespace, - baseTypeName, + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::"); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.AppendLine("(decltype(nullptr))"); + if (enclosingTypeKind == TypeKind.Class) + { + AppendCppConstructorInitializerList( + interfaceTypes, + indent + 1, + output); + } + AppendIndent(indent, output); + output.AppendLine("{"); + extraDefault(indent + 1, "this->"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Handle constructor + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::"); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.AppendLine("(Plugin::InternalUse, int32_t handle)"); + if (enclosingTypeKind == TypeKind.Class) + { + AppendCppConstructorInitializerList( + interfaceTypes, + indent + 1, + output); + } + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("Handle = handle;"); + AppendIndent(indent + 1, output); + output.AppendLine("if (handle)"); + AppendIndent(indent + 1, output); + output.AppendLine("{"); + AppendIndent(indent + 2, output); + AppendReferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + "handle", + output); + output.AppendLine(";"); + AppendIndent(indent + 1, output); + output.AppendLine("}"); + extraDefault(indent + 1, "this->"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Copy constructor + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::"); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.Append("(const "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("& other)"); + AppendIndent(indent + 1, output); + output.Append(": "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.AppendLine("(Plugin::InternalUse::Only, other.Handle)"); + AppendIndent(indent, output); + output.AppendLine("{"); + extraCopy(indent + 1, "other."); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Move constructor + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::"); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.Append("("); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("&& other)"); + AppendIndent(indent, output); + output.Append("\t: "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + output.AppendLine("(Plugin::InternalUse::Only, other.Handle)"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("other.Handle = 0;"); + extraCopy(indent + 1, "other."); + extraDefault(indent + 1, "other."); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Destructor + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::~"); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("()"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("if (Handle)"); + AppendIndent(indent + 1, output); + output.AppendLine("{"); + AppendIndent(indent + 2, output); + AppendDereferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + "Handle", + output); + output.AppendLine(";"); + AppendIndent(indent + 2, output); + output.AppendLine("Handle = 0;"); + AppendIndent(indent + 1, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Assignment operator to same type + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("& "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::operator=(const "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("& other)"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendSetHandle( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + indent + 1, + "this", + "other.Handle", + output); + extraCopy(indent + 1, "other."); + AppendIndent(indent + 1, output); + output.AppendLine("return *this;"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Assignment operator to nullptr + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("& "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("::operator=(decltype(nullptr))"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("if (Handle)"); + AppendIndent(indent + 1, output); + output.AppendLine("{"); + AppendIndent(indent + 2, output); + AppendDereferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + "Handle", + output); + output.AppendLine(";"); + AppendIndent(indent + 2, output); + output.AppendLine("Handle = 0;"); + AppendIndent(indent + 1, output); + output.AppendLine("}"); + AppendIndent(indent + 1, output); + output.AppendLine("return *this;"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Move assignment operator to same type + AppendIndent(indent, output); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("& "); + AppendCppTypeName( + enclosingTypeTypeName, output); - output.Append('\n'); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::operator=("); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("&& other)"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("if (Handle)"); + AppendIndent(indent + 1, output); + output.AppendLine("{"); + AppendIndent(indent + 2, output); + AppendDereferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + "Handle", + output); + output.AppendLine(";"); + AppendIndent(indent + 1, output); + output.AppendLine("}"); + AppendIndent(indent + 1, output); + output.AppendLine("Handle = other.Handle;"); + extraCopy(indent + 1, "other."); + AppendIndent(indent + 1, output); + output.AppendLine("other.Handle = 0;"); + extraDefault(indent + 1, "other."); + AppendIndent(indent + 1, output); + output.AppendLine("return *this;"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Equality operator with same type + AppendIndent(indent, output); + output.Append("bool "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::operator==(const "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("& other) const"); AppendIndent(indent, output); - output.Append('\n'); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("return Handle == other.Handle;"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + + // Inequality operator with same type + AppendIndent(indent, output); + output.Append("bool "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.Append("::operator!=(const "); + AppendCppTypeName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeParams, + output); + output.AppendLine("& other) const"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("return Handle != other.Handle;"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.AppendLine();; + } + return cppMethodDefinitionsIndent; + } + + static void AppendSetHandle( + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + Type[] enclosingTypeParams, + int indent, + string thisExpression, + string otherHandleExpression, + StringBuilder output) + { + string thisHandleExpression = thisExpression + "->Handle"; + AppendIndent(indent, output); + output.Append("if ("); + output.Append(thisHandleExpression); + output.AppendLine(")"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + AppendDereferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + thisHandleExpression, + output); + output.AppendLine(";"); + AppendIndent(indent, output); + output.AppendLine("}"); + AppendIndent(indent, output); + output.Append(thisHandleExpression); + output.Append(" = "); + output.Append(otherHandleExpression); + output.AppendLine(";"); + AppendIndent(indent, output); + output.Append("if ("); + output.Append(thisHandleExpression); + output.AppendLine(")"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + AppendReferenceManagedHandleFunctionCall( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + thisHandleExpression, + output); + output.AppendLine(";"); + AppendIndent(indent, output); + output.AppendLine("}"); + } + + static void AppendReferenceManagedHandleFunctionCall( + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + Type[] enclosingTypeParams, + string handleVariable, + StringBuilder output) + { + if (enclosingTypeKind == TypeKind.ManagedStruct) + { + output.Append("Plugin::ReferenceManaged"); + AppendReleaseFunctionNameSuffix( + enclosingTypeTypeName, + enclosingTypeParams, + output); + output.Append("(Handle)"); + } + else + { + output.Append("Plugin::ReferenceManagedClass("); + output.Append(handleVariable); + output.Append(")"); + } + } + + static void AppendDereferenceManagedHandleFunctionCall( + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + Type[] enclosingTypeParams, + string handleVariable, + StringBuilder output) + { + if (enclosingTypeKind == TypeKind.ManagedStruct) + { + output.Append("Plugin::DereferenceManaged"); + AppendReleaseFunctionNameSuffix( + enclosingTypeTypeName, + enclosingTypeParams, + output); + output.Append("(Handle)"); + } + else + { + output.Append("Plugin::DereferenceManagedClass("); + output.Append(handleVariable); + output.Append(")"); } - return cppMethodDefinitionsIndent; } - static void AppendCppMethodDefinitionEnd( + static void AppendCppMethodDefinitionsEnd( int indent, StringBuilder output) { RemoveTrailingChars(output); - output.Append('\n'); + output.AppendLine();; AppendNamespaceEnding( indent, output); - output.Append('\n'); - } - - static void AppendSystemObjectLifecycleCall( - string macroName, - string typeName, - string baseTypeNamespace, - string baseTypeName, - StringBuilder output) - { - output.Append(macroName); - output.Append('('); - output.Append(typeName); - output.Append(", "); - output.Append(baseTypeNamespace); - output.Append("::"); - output.Append(baseTypeName); - output.Append(")"); + output.AppendLine();; } static int AppendNamespaceBeginning( @@ -1897,9 +12022,9 @@ static int AppendNamespaceBeginning( AppendIndent(indent, output); output.Append("namespace "); output.Append(namespaceName, startIndex, len); - output.Append('\n'); + output.AppendLine();; AppendIndent(indent, output); - output.Append("{\n"); + output.AppendLine("{"); if (separatorIndex < 0) { break; @@ -1919,7 +12044,7 @@ static void AppendNamespaceEnding( for (; indent >= 0; --indent) { AppendIndent(indent, output); - output.Append("}\n"); + output.AppendLine("}"); } } @@ -1929,41 +12054,46 @@ static void AppendIndent( { output.Append('\t', indent); } - - static void AppendCsharpInitParam( - string funcName, - StringBuilder output) - { - output.Append("\t\t\tIntPtr "); - output.Append(funcName); - output.Append(",\n"); - } - - static void AppendCsharpInitCallArg( + + static void AppendCsharpCsharpDelegate( string funcName, - StringBuilder output) + StringBuilder initCallOutput, + StringBuilder delegateOutput) { - output.Append( - "\t\t\t\tMarshal.GetFunctionPointerForDelegate(new "); - output.Append(funcName); - output.Append("Delegate("); - output.Append(funcName); - output.Append(")),\n"); + initCallOutput.Append( + "\t\t\tMarshal.WriteIntPtr(memory, curMemory, Marshal.GetFunctionPointerForDelegate("); + initCallOutput.Append(funcName); + initCallOutput.Append("Delegate"); + initCallOutput.AppendLine("));"); + initCallOutput.AppendLine("\t\t\tcurMemory += IntPtr.Size;"); + + delegateOutput.Append("\t\tstatic readonly "); + delegateOutput.Append(funcName); + delegateOutput.Append("DelegateType "); + delegateOutput.Append(funcName); + delegateOutput.Append("Delegate = new "); + delegateOutput.Append(funcName); + delegateOutput.Append("DelegateType("); + delegateOutput.Append(funcName); + delegateOutput.AppendLine(");"); } static void AppendCsharpDelegateType( string funcName, bool isStatic, + Type enclosingType, + TypeKind enclosingTypeKind, Type returnType, ParameterInfo[] parameters, StringBuilder output) { + output.AppendLine("\t\t[UnmanagedFunctionPointer(CallingConvention.Cdecl)]"); output.Append("\t\tdelegate "); // Return type - if (returnType.IsValueType) + if (IsFullValueType(returnType)) { - AppendCsharpTypeName( + AppendCsharpTypeFullName( returnType, output); } @@ -1974,42 +12104,52 @@ static void AppendCsharpDelegateType( output.Append(' '); output.Append(funcName); - output.Append("Delegate("); + output.Append("DelegateType("); if (!isStatic) { - output.Append("int thisHandle"); + if (enclosingTypeKind == TypeKind.FullStruct) + { + output.Append("ref "); + AppendCsharpTypeFullName( + enclosingType, + output); + output.Append(" thiz"); + } + else + { + output.Append("int thisHandle"); + } if (parameters.Length > 0) { output.Append(", "); } } - AppendParameterDeclaration( + AppendCsharpBindingParameterDeclaration( parameters, - "int", - AppendCsharpTypeName, output); - output.Append(");\n"); + output.AppendLine(");"); } static void AppendCsharpFunctionBeginning( Type enclosingType, string funcName, bool isStatic, + TypeKind enclosingTypeKind, Type returnType, - Type[] typeParameters, ParameterInfo[] parameters, StringBuilder output) { output.Append("\t\t[MonoPInvokeCallback(typeof("); output.Append(funcName); - output.Append("Delegate))]\n\t\tstatic "); + output.AppendLine("DelegateType))]"); + output.Append("\t\tstatic "); // Return type if (returnType != null) { - if (returnType.IsValueType) + if (IsFullValueType(returnType)) { - AppendCsharpTypeName( + AppendCsharpTypeFullName( returnType, output); } @@ -2027,35 +12167,82 @@ static void AppendCsharpFunctionBeginning( output.Append("("); if (!isStatic) { - output.Append("int thisHandle"); + if (enclosingTypeKind == TypeKind.FullStruct) + { + output.Append("ref "); + AppendCsharpTypeFullName( + enclosingType, + output); + output.Append(" thiz"); + } + else + { + output.Append("int thisHandle"); + } if (parameters.Length > 0) { output.Append(", "); } } - AppendParameterDeclaration( + AppendCsharpBindingParameterDeclaration( parameters, - "int", - AppendCsharpTypeName, output); - output.Append(")\n\t\t{\n\t\t\t"); + output.AppendLine(")"); + output.AppendLine("\t\t{"); + output.Append("\t\t\t"); + + // Start try/catch block + output.AppendLine("try"); + output.AppendLine("\t\t\t{"); + output.Append("\t\t\t\t"); // Get "this" - if (!isStatic) + if (!isStatic + && enclosingTypeKind != TypeKind.FullStruct) { output.Append("var thiz = ("); - AppendCsharpTypeName( + AppendCsharpTypeFullName( + enclosingType, + output); + output.Append(')'); + AppendHandleStoreTypeName( enclosingType, output); + output.AppendLine( + ".Get(thisHandle);"); output.Append( - ")ObjectStore.Get(thisHandle);\n\t\t\t"); + "\t\t\t\t"); + } + + // Get managed type params from ObjectStore + foreach (ParameterInfo param in parameters) + { + Type paramType = param.DereferencedParameterType; + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + { + output.Append("var "); + output.Append(param.Name); + output.Append(" = "); + if (paramType != typeof(object)) + { + output.Append('('); + AppendCsharpTypeFullName(paramType, output); + output.Append(')'); + } + AppendHandleStoreTypeName(paramType, output); + output.Append(".Get("); + output.Append(param.Name); + output.AppendLine("Handle);"); + output.Append("\t\t\t\t"); + } } // Save return value as local variable - if (!returnType.Equals(typeof(void))) + if (returnType != typeof(void)) { - output.Append("var obj = "); - }; + output.Append("var returnValue = "); + } } static void AppendCsharpFunctionCallSubject( @@ -2065,7 +12252,7 @@ static void AppendCsharpFunctionCallSubject( { if (isStatic) { - AppendCsharpTypeName( + AppendCsharpTypeFullName( enclosingType, output); } @@ -2073,87 +12260,302 @@ static void AppendCsharpFunctionCallSubject( { output.Append("thiz"); } - output.Append('.'); } static void AppendCsharpFunctionCallParameters( - bool isStatic, ParameterInfo[] parameters, StringBuilder output) { - output.Append('('); for (int i = 0; i < parameters.Length; ++i) { - ParameterInfo parameter = parameters[i]; - if (parameter.ParameterType.IsValueType) + ParameterInfo param = parameters[i]; + if (param.IsOut) { - output.Append(parameter.Name); + output.Append("out "); } - else + else if (param.IsRef) { - if (!parameter.ParameterType.Equals(typeof(object))) - { - output.Append('('); - output.Append(parameter.ParameterType); - output.Append(')'); - } - output.Append("ObjectStore.Get("); - output.Append(parameter.Name); - output.Append("Handle)"); + output.Append("ref "); } + output.Append(param.Name); if (i != parameters.Length - 1) { output.Append(", "); } } - output.Append(')'); + } + + static void AppendStructStoreReplace( + Type enclosingType, + string handleVariable, + string structVariable, + StringBuilder output) + { + output.AppendLine(); + output.Append("\t\t\t\t"); + AppendHandleStoreTypeName( + enclosingType, + output); + output.Append(".Replace("); + output.Append(handleVariable); + output.Append(", ref "); + output.Append(structVariable); + output.Append(");"); } static void AppendCsharpFunctionReturn( + ParameterInfo[] parameters, Type returnType, + TypeKind returnTypeKind, + Type[] exceptionTypes, + bool forceReturnReturnValue, StringBuilder output) { - if (!returnType.Equals(typeof(void))) + // Store reference out and ref params and overwrite handles + foreach (ParameterInfo param in parameters) + { + if ((param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + && (param.IsOut || param.IsRef)) + { + output.AppendLine(); + output.Append("\t\t\t\tint "); + output.Append(param.Name); + output.Append("HandleNew = "); + AppendHandleStoreTypeName( + param.DereferencedParameterType, + output); + output.Append('.'); + if (param.Kind == TypeKind.ManagedStruct) + { + output.Append("Store"); + } + else + { + output.Append("GetHandle"); + } + output.Append('('); + output.Append(param.Name); + output.AppendLine(");"); + output.Append("\t\t\t\t"); + output.Append(param.Name); + output.Append("Handle = "); + output.Append(param.Name); + output.Append("HandleNew;"); + } + } + + // Return + if (returnType != typeof(void)) { - output.Append("\n\t\t\t"); - if (returnType.IsValueType) + output.AppendLine(); + output.Append("\t\t\t\treturn "); + if ( + forceReturnReturnValue + || returnTypeKind == TypeKind.Enum + || returnTypeKind == TypeKind.FullStruct + || returnTypeKind == TypeKind.Primitive) { - output.Append("return obj;"); + output.Append("returnValue"); } else { - output.Append( - "int handle = ObjectStore.Store(obj);\n"); - output.Append("\t\t\treturn handle;"); + AppendHandleStoreTypeName( + returnType, + output); + output.Append('.'); + if (returnTypeKind == TypeKind.Class) + { + output.Append("GetHandle"); + } + else + { + output.Append("Store"); + } + output.Append("(returnValue)"); + } + output.Append(';'); + } + + // Returning ends the function + AppendCsharpFunctionEnd( + returnType, + exceptionTypes, + parameters, + output); + } + + static void AppendCsharpFunctionEnd( + Type returnType, + Type[] exceptionTypes, + ParameterInfo[] parameters, + StringBuilder output) + { + output.AppendLine();; + output.AppendLine("\t\t\t}"); + if (exceptionTypes == null + || Array.IndexOf( + exceptionTypes, + typeof(NullReferenceException)) < 0) + { + AppendCsharpCatchException( + typeof(NullReferenceException), + returnType, + parameters, + output); + } + if (exceptionTypes != null) + { + foreach (Type exceptionType in exceptionTypes) + { + AppendCsharpCatchException( + exceptionType, + returnType, + parameters, + output); } } - output.Append("\n\t\t}\n\t\t\n"); + AppendCsharpCatchException( + typeof(Exception), + returnType, + parameters, + output); + output.AppendLine("\t\t}"); + output.AppendLine("\t\t"); } - static void AppendParameterDeclaration( + static void AppendCsharpCatchException( + Type exceptionType, + Type returnType, ParameterInfo[] parameters, - string handleType, - Action appendTypeName, + StringBuilder output) + { + output.Append("\t\t\tcatch ("); + AppendCsharpTypeFullName( + exceptionType, + output); + output.AppendLine(" ex)"); + output.AppendLine("\t\t\t{"); + output.AppendLine("\t\t\t\tUnityEngine.Debug.LogException(ex);"); + output.Append("\t\t\t\tNativeScript.Bindings."); + AppendCsharpSetCsharpExceptionFunctionName( + exceptionType, + output); + output.AppendLine("(NativeScript.Bindings.ObjectStore.Store(ex));"); + foreach (ParameterInfo param in parameters) + { + if (param.IsOut) + { + output.Append("\t\t\t\t"); + output.Append(param.Name); + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + { + output.AppendLine("Handle = default(int);"); + } + else + { + output.Append(" = default("); + AppendCsharpTypeFullName( + param.DereferencedParameterType, + output); + output.AppendLine(");"); + } + } + } + if (returnType != typeof(void)) + { + output.Append("\t\t\t\treturn default("); + if (IsFullValueType(returnType)) + { + AppendCsharpTypeFullName( + returnType, + output); + } + else + { + output.Append("int"); + } + output.AppendLine(");"); + } + output.AppendLine("\t\t\t}"); + } + + static void AppendCsharpSetCsharpExceptionFunctionName( + Type exceptionType, StringBuilder output ) + { + output.Append("SetCsharpException"); + if (exceptionType != typeof(Exception)) + { + AppendNamespace( + exceptionType.Namespace, + string.Empty, + output); + AppendTypeNameWithoutGenericSuffix( + exceptionType.Name, + output); + } + } + + static void AppendCsharpBindingParameterDeclaration( + ParameterInfo[] parameters, + StringBuilder output) { for (int i = 0; i < parameters.Length; ++i) { - ParameterInfo parameter = parameters[i]; - if (handleType == null || parameter.ParameterType.IsValueType) + ParameterInfo param = parameters[i]; + + // out or ref qualifiers if necessary + switch (param.Kind) { - appendTypeName(parameter.ParameterType, output); + case TypeKind.FullStruct: + if (param.IsOut) + { + output.Append("out "); + } + else + { + output.Append("ref "); + } + break; + case TypeKind.ManagedStruct: + case TypeKind.Primitive: + case TypeKind.Enum: + case TypeKind.Class: + if (param.IsOut || param.IsRef) + { + output.Append("ref "); + } + break; } - else + + // Param type- int for handles + switch (param.Kind) { - output.Append(handleType); + case TypeKind.ManagedStruct: + case TypeKind.Class: + output.Append("int"); + break; + default: + AppendCsharpTypeFullName( + param.DereferencedParameterType, + output); + break; } + + // Param name output.Append(' '); - output.Append(parameter.Name); - if (handleType != null && !parameter.ParameterType.IsValueType) + output.Append(param.Name); + + // Handle suffix if necessary + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) { output.Append("Handle"); } + if (i != parameters.Length - 1) { output.Append(", "); @@ -2161,113 +12563,279 @@ StringBuilder output } } - static void AppendParameterCall( + static void AppendCppParameterDeclaration( ParameterInfo[] parameters, - string separator, + Type[] methodTypeParameters, + bool includeDefaults, StringBuilder output) { + bool hasVarArgs = parameters.Length > 0 && + parameters[parameters.Length-1].IsVarArg; for (int i = 0; i < parameters.Length; ++i) { - ParameterInfo parameter = parameters[i]; - output.Append(parameter.Name); - if (!parameter.ParameterType.IsValueType) + ParameterInfo param = parameters[i]; + Type paramType = param.DereferencedParameterType; + + int typeParamIndex = ArrayIndexOf( + methodTypeParameters, + paramType); + if (typeParamIndex >= 0) { - output.Append("Handle"); + output.Append("MT"); + output.Append(typeParamIndex); + } + else + { + AppendCppTypeFullName( + paramType, + output); + } + + // Pointer (*) or reference (&) suffix if necessary + if (param.IsOut || param.IsRef) + { + output.Append('*'); + } + else if ( + param.Kind == TypeKind.FullStruct || + param.Kind == TypeKind.ManagedStruct || + param.Kind == TypeKind.Class || + param.IsVirtual) + { + output.Append('&'); + } + + // Param name + output.Append(' '); + output.Append(param.Name); + + // Default if desired, present, and the method has no var args + if (includeDefaults && param.HasDefault && !hasVarArgs) + { + output.Append(" = "); + if (param.DereferencedParameterType == typeof(string)) + { + if (param.DefaultValue != null) + { + throw new Exception( + "Non-null string default parameters aren't supported"); + } + output.Append("Plugin::NullString"); + } + else if (param.DefaultValue is bool) + { + bool val = (bool)param.DefaultValue; + output.Append(val ? "true" : "false"); + } + else if (param.DefaultValue is char) + { + char val = (char)param.DefaultValue; + output.Append('\''); + output.Append(val); + output.Append('\''); + } + else if ((param.DefaultValue is sbyte) || + (param.DefaultValue is byte) || + (param.DefaultValue is short) || + (param.DefaultValue is ushort) || + (param.DefaultValue is int) || + (param.DefaultValue is uint) || + (param.DefaultValue is long) || + (param.DefaultValue is ulong)) + { + output.Append(param.DefaultValue); + } + else + { + Type type = param.DefaultValue.GetType(); + if (type.IsEnum) + { + AppendCppTypeFullName( + type, + output); + output.Append("::"); + output.Append(param.DefaultValue); + } + else + { + StringBuilder error = new StringBuilder(); + error.Append("Default parameter type ("); + AppendCsharpTypeFullName( + param.DefaultValue.GetType(), + error); + error.Append(") not supported"); + throw new Exception(error.ToString()); + } + } } + if (i != parameters.Length - 1) { - output.Append(','); - output.Append(separator); + output.Append(", "); } } } - - static void AppendCppInitBody( - string funcName, - string funcNameLower, + + static void AppendCppInitBodyFunctionPointerParameterRead( + string globalVariableName, + bool isStatic, + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + ParameterInfo[] parameters, + Type returnType, StringBuilder output) { - output.Append('\t'); - output.Append(funcName); - output.Append(" = "); - output.Append(funcNameLower); - output.Append(";\n"); + output.Append("\tPlugin::"); + output.Append(globalVariableName); + output.Append(" = *("); + AppendCppFunctionPointer( + string.Empty, // function name + isStatic, + enclosingTypeTypeName, + enclosingTypeKind, + parameters, + returnType, + 2, + output); + output.AppendLine(")curMemory;"); + output.Append("\tcurMemory += sizeof(Plugin::"); + output.Append(globalVariableName); + output.AppendLine(");"); } - static void AppendCppMethodDefinition( - Type enclosingType, + static void AppendCppMethodDefinitionBegin( + TypeName enclosingTypeTypeName, Type returnType, string methodName, - Type[] typeParameters, + Type[] enclosingTypeTypeParams, + Type[] methodTypeParams, ParameterInfo[] parameters, int indent, StringBuilder output) { - AppendIndent(indent, output); - if (typeParameters != null) + // Indent + AppendIndent( + indent, + output); + + // Template + if (methodTypeParams != null) { output.Append("template<> "); } + + // Return type if (returnType != null) { - AppendCppTypeName(returnType, output); + AppendCppTypeFullName( + returnType, + output); output.Append(' '); } - output.Append(enclosingType.Name); + + // Type name + AppendCppTypeFullName( + enclosingTypeTypeName, + output); + AppendCppTypeParameters( + enclosingTypeTypeParams, + output); output.Append("::"); - output.Append(methodName); - if (typeParameters != null) - { - output.Append("<"); - for (int i = 0; i < typeParameters.Length; ++i) - { - Type typeParam = typeParameters[i]; - AppendCppTypeName(typeParam, output); - if (i != typeParameters.Length - 1) - { - output.Append(", "); - } - } - output.Append(">"); - } + + // Method name + AppendTypeNameWithoutGenericSuffix( + methodName, + output); + + // Template parameters + AppendCppTypeParameters( + methodTypeParams, + output); + + // Parameters output.Append('('); - AppendParameterDeclaration( + AppendCppParameterDeclaration( parameters, - null, - AppendCppTypeName, + null, // don't substitute method type params + false, output); - output.Append(")\n"); + output.AppendLine(")"); } static void AppendCppMethodReturn( Type returnType, - StringBuilder output - ) + TypeKind returnTypeKind, + int indent, + StringBuilder output) { - if (returnType != null && !returnType.Equals(typeof(void))) + if (returnType != null && returnType != typeof(void)) { + AppendIndent(indent, output); output.Append("return "); - if (!returnType.IsValueType) + switch (returnTypeKind) { - AppendCppTypeName(returnType, output); - output.Append('('); + case TypeKind.Enum: + case TypeKind.FullStruct: + case TypeKind.Primitive: + output.Append("returnValue"); + break; + default: + AppendCppTypeFullName( + returnType, + output); + output.Append("(Plugin::InternalUse::Only, returnValue)"); + break; } + output.AppendLine(";"); } } static void AppendCppPluginFunctionCall( bool isStatic, + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, + Type[] enclosingTypeParams, Type returnType, string funcName, ParameterInfo[] parameters, + int indent, StringBuilder output) { + // Gather handles for out and ref parameters + foreach (ParameterInfo param in parameters) + { + if ((param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + && (param.IsOut || param.IsRef)) + { + AppendIndent(indent, output); + output.Append("int32_t "); + output.Append(param.Name); + output.Append("Handle = "); + output.Append(param.Name); + output.AppendLine("->Handle;"); + } + } + + // Call the function + AppendIndent(indent, output); + if (returnType != null && returnType != typeof(void)) + { + output.Append("auto returnValue = "); + } output.Append("Plugin::"); output.Append(funcName); output.Append("("); if (!isStatic) { - output.Append("Handle"); + if (enclosingTypeKind == TypeKind.FullStruct) + { + output.Append("this"); + } + else + { + output.Append("Handle"); + } if (parameters.Length > 0) { output.Append(", "); @@ -2275,49 +12843,94 @@ static void AppendCppPluginFunctionCall( } for (int i = 0; i < parameters.Length; ++i) { - Type paramType = parameters[i].ParameterType; - output.Append(parameters[i].Name); - if (!paramType.IsValueType) + ParameterInfo param = parameters[i]; + switch (param.Kind) { - output.Append(".Handle"); + case TypeKind.FullStruct: + case TypeKind.Enum: + output.Append(param.Name); + break; + case TypeKind.Primitive: + if (param.IsOut || param.IsRef) + { + output.Append("&"); + output.Append(param.Name); + output.Append("->Value"); + } + else + { + output.Append(param.Name); + } + break; + default: + if (param.IsOut || param.IsRef) + { + output.Append('&'); + output.Append(param.Name); + } + else + { + output.Append(param.Name); + output.Append('.'); + } + output.Append("Handle"); + break; } if (i != parameters.Length - 1) { output.Append(", "); } } - output.Append(")"); - if (returnType != null - && !returnType.Equals(typeof(void)) - && !returnType.IsValueType) + output.AppendLine(");"); + + AppendCppUnhandledExceptionHandling( + indent, + output); + + // Set out and ref parameters + foreach (ParameterInfo param in parameters) { - output.Append(')'); + if ((param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + && (param.IsOut || param.IsRef)) + { + AppendSetHandle( + enclosingTypeTypeName, + enclosingTypeKind, + enclosingTypeParams, + indent, + param.Name, + param.Name + "Handle", + output); + } } } - static void AppendCppInitParam( - string funcName, - bool isStatic, - ParameterInfo[] parameters, - Type returnType, - StringBuilder output - ) + static void AppendCppUnhandledExceptionHandling( + int indent, + StringBuilder output) { - output.Append('\t'); - AppendCppFunctionPointer( - funcName, - isStatic, - parameters, - returnType, - ',', - output - ); - output.Append('\n'); + AppendIndent(indent, output); + output.AppendLine("if (Plugin::unhandledCsharpException)"); + AppendIndent(indent, output); + output.AppendLine("{"); + AppendIndent(indent + 1, output); + output.AppendLine("System::Exception* ex = Plugin::unhandledCsharpException;"); + AppendIndent(indent + 1, output); + output.AppendLine("Plugin::unhandledCsharpException = nullptr;"); + AppendIndent(indent + 1, output); + output.AppendLine("ex->ThrowReferenceToThis();"); + AppendIndent(indent + 1, output); + output.AppendLine("delete ex;"); + AppendIndent(indent, output); + output.AppendLine("}"); } - + static void AppendCppFunctionPointerDefinition( string funcName, bool isStatic, + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, ParameterInfo[] parameters, Type returnType, StringBuilder output @@ -2327,237 +12940,531 @@ StringBuilder output AppendCppFunctionPointer( funcName, isStatic, + enclosingTypeTypeName, + enclosingTypeKind, parameters, returnType, - ';', + 1, output ); - output.Append('\n'); + output.Append(';'); + output.AppendLine();; } static void AppendCppFunctionPointer( string funcName, bool isStatic, + TypeName enclosingTypeTypeName, + TypeKind enclosingTypeKind, ParameterInfo[] parameters, Type returnType, - char separator, - StringBuilder output - ) + int numIndirectionLevels, + StringBuilder output) { // Return type - if (returnType.IsValueType) + if (returnType == typeof(bool)) + { + // C linkage requires us to use primitive types + output.Append("int32_t"); + } + else if (returnType == typeof(char)) + { + // C linkage requires us to use primitive types + output.Append("int16_t"); + } + else if (returnType.IsPrimitive) { - AppendCppTypeName(returnType, output); + AppendCppPrimitiveTypeName(returnType, output); + } + else if (IsFullValueType(returnType)) + { + AppendCppTypeFullName(returnType, output); } else { output.Append("int32_t"); } - output.Append(" (*"); + output.Append(" ("); + output.Append('*', numIndirectionLevels); output.Append(funcName); output.Append(")("); if (!isStatic) { - output.Append("int32_t thisHandle"); + switch (enclosingTypeKind) + { + case TypeKind.FullStruct: + case TypeKind.Primitive: + AppendCppTypeFullName( + enclosingTypeTypeName, + output); + output.Append("* thiz"); + break; + default: + output.Append("int32_t thisHandle"); + break; + } if (parameters.Length > 0) { output.Append(", "); } } - AppendParameterDeclaration( - parameters, - "int32_t", - AppendCppTypeName, - output); - output.Append(")"); - output.Append(separator); + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo param = parameters[i]; + switch (param.Kind) + { + case TypeKind.Primitive: + AppendCppPrimitiveTypeName( + param.DereferencedParameterType, + output); + if (param.IsOut || param.IsRef) + { + output.Append('*'); + } + break; + case TypeKind.Enum: + AppendCppTypeFullName( + param.DereferencedParameterType, + output); + if (param.IsOut || param.IsRef) + { + output.Append('*'); + } + break; + case TypeKind.FullStruct: + AppendCppTypeFullName( + param.DereferencedParameterType, + output); + if (param.IsOut || param.IsRef) + { + output.Append('*'); + } + else + { + output.Append('&'); + } + break; + case TypeKind.Class: + case TypeKind.ManagedStruct: + output.Append("int32_t"); + if (param.IsOut || param.IsRef) + { + output.Append('*'); + } + break; + } + output.Append(' '); + output.Append(param.Name); + if (param.Kind == TypeKind.Class + || param.Kind == TypeKind.ManagedStruct) + { + output.Append("Handle"); + } + if (i != parameters.Length - 1) + { + output.Append(", "); + } + } + output.Append(')'); } - static void AppendCppMethodDeclaration( - string methodName, - bool isStatic, - Type returnType, - Type[] typeParameters, - ParameterInfo[] parameters, + static void AppendCppTemplateTypenames( + int numTypeParameters, + char prefix, StringBuilder output) { - if (typeParameters != null) + if (numTypeParameters > 0) { - output.Append("template "); } + } + + static void AppendCppMethodDeclaration( + string methodName, + bool enclosingTypeIsStatic, + bool methodIsVirtual, + bool methodIsStatic, + Type returnType, + Type[] methodTypeParameters, + ParameterInfo[] parameters, + StringBuilder output) + { + AppendCppTemplateTypenames( + methodTypeParameters == null ? 0 : methodTypeParameters.Length, + 'M', + output); - if (isStatic) + if (!enclosingTypeIsStatic && methodIsStatic) { output.Append("static "); } - // Return type - if (typeParameters != null) + if (methodIsVirtual) { - output.Append("T0 "); + output.Append("virtual "); } - else if (returnType != null) + + // Return type + if (returnType != null) { - AppendCppTypeName(returnType, output); + int typeParamIndex = ArrayIndexOf( + methodTypeParameters, + returnType); + if (typeParamIndex >= 0) + { + output.Append("MT"); + output.Append(typeParamIndex); + } + else + { + AppendCppTypeFullName( + returnType, + output); + } output.Append(' '); } - output.Append(methodName); - output.Append('('); + // Method name might be a constructor/type name, so remove suffix + // just in case + AppendTypeNameWithoutGenericSuffix( + methodName, + output); // Parameters - AppendParameterDeclaration( + output.Append('('); + AppendCppParameterDeclaration( parameters, - null, - AppendCppTypeName, + methodTypeParameters, + true, output); - output.Append(");\n"); + output.Append(')'); + + output.AppendLine(";"); } - static void AppendCsharpTypeName( + static void AppendCsharpTypeFullName( Type type, StringBuilder output) { - if (type.Equals(typeof(void))) + if (type == typeof(void)) { output.Append("void"); } - else if (type.Equals(typeof(bool))) + else if (type == typeof(bool)) { output.Append("bool"); } - else if (type.Equals(typeof(sbyte))) + else if (type == typeof(sbyte)) { output.Append("sbyte"); } - else if (type.Equals(typeof(byte))) + else if (type == typeof(byte)) { output.Append("byte"); } - else if (type.Equals(typeof(short))) + else if (type == typeof(short)) { output.Append("short"); } - else if (type.Equals(typeof(ushort))) + else if (type == typeof(ushort)) { output.Append("ushort"); } - else if (type.Equals(typeof(int))) + else if (type == typeof(int)) { output.Append("int"); } - else if (type.Equals(typeof(uint))) + else if (type == typeof(uint)) { output.Append("uint"); } - else if (type.Equals(typeof(long))) + else if (type == typeof(long)) { output.Append("long"); } - else if (type.Equals(typeof(ulong))) + else if (type == typeof(ulong)) { output.Append("ulong"); } - else if (type.Equals(typeof(string))) + else if (type == typeof(char)) + { + output.Append("char"); + } + else if (type == typeof(float)) + { + output.Append("float"); + } + else if (type == typeof(double)) + { + output.Append("double"); + } + else if (type == typeof(string)) { output.Append("string"); } + else if (type == typeof(object)) + { + output.Append("object"); + } + else if (type.IsArray) + { + AppendCsharpTypeFullName( + type.GetElementType(), + output); + output.Append('['); + output.Append(',', type.GetArrayRank()-1); + output.Append(']'); + } else { - output.Append(type.Namespace); + AppendCsharpTypeFullName(GetTypeName(type), output); + Type[] genTypes = type.GetGenericArguments(); + AppendCSharpTypeParameters( + genTypes, + output); + } + } + + static void AppendCsharpTypeFullName( + TypeName typeName, + StringBuilder output) + { + if (!string.IsNullOrEmpty(typeName.Namespace)) + { + output.Append(typeName.Namespace); output.Append('.'); - output.Append(type.Name); } + AppendTypeNameWithoutGenericSuffix(typeName.Name, output); } - static void AppendCppTypeName( + static void AppendCppTypeFullName( Type type, StringBuilder output) { - if (type.Equals(typeof(void))) + if (type == typeof(void)) { output.Append("void"); } - else if (type.Equals(typeof(bool))) + else if (type == typeof(bool)) { output.Append("System::Boolean"); } - else if (type.Equals(typeof(sbyte))) + else if (type == typeof(sbyte)) + { + output.Append("System::SByte"); + } + else if (type == typeof(byte)) + { + output.Append("System::Byte"); + } + else if (type == typeof(short)) + { + output.Append("System::Int16"); + } + else if (type == typeof(ushort)) + { + output.Append("System::UInt16"); + } + else if (type == typeof(int)) + { + output.Append("System::Int32"); + } + else if (type == typeof(uint)) + { + output.Append("System::UInt32"); + } + else if (type == typeof(long)) + { + output.Append("System::Int64"); + } + else if (type == typeof(ulong)) + { + output.Append("System::UInt64"); + } + else if (type == typeof(char)) + { + output.Append("System::Char"); + } + else if (type == typeof(float)) + { + output.Append("System::Single"); + } + else if (type == typeof(double)) + { + output.Append("System::Double"); + } + else if (type == typeof(string)) + { + output.Append("System::String"); + } + else if (type == typeof(IntPtr)) + { + output.Append("void*"); + } + else if (type.IsArray) + { + int rank = type.GetArrayRank(); + output.Append("System::Array"); + output.Append(rank); + output.Append('<'); + Type elementType = type.GetElementType(); + AppendCppTypeFullName( + elementType, + output); + output.Append('>'); + } + else if (IsDelegate(type)) + { + AppendCppTypeFullName( + GetTypeName(type), + output); + Type[] genTypes = type.GetGenericArguments(); + AppendCppTypeParameters( + genTypes, + output); + } + else + { + TypeName typeName = GetTypeName(type); + AppendCppTypeFullName(typeName, output); + Type[] genTypes = type.GetGenericArguments(); + AppendCppTypeParameters(genTypes, output); + } + } + + static void AppendCppTypeFullName( + TypeName typeName, + StringBuilder output) + { + AppendNamespace(typeName.Namespace, "::", output); + if (!string.IsNullOrEmpty(typeName.Namespace)) + { + output.Append("::"); + } + AppendCppTypeName(typeName, output); + } + + static void AppendCppTypeName( + TypeName typeName, + StringBuilder output) + { + AppendTypeNameWithoutGenericSuffix(typeName.Name, output); + if (typeName.NumTypeParams > 0) + { + output.Append('_'); + output.Append(typeName.NumTypeParams); + } + } + + static void AppendCppPrimitiveTypeName( + Type type, + StringBuilder output) + { + if (type == typeof(void)) + { + output.Append("void"); + } + else if (type == typeof(bool)) + { + output.Append("uint32_t"); // C# bool is 4 bytes + } + else if (type == typeof(sbyte)) { output.Append("int8_t"); } - else if (type.Equals(typeof(byte))) + else if (type == typeof(byte)) { output.Append("uint8_t"); } - else if (type.Equals(typeof(short))) + else if (type == typeof(short)) { output.Append("int16_t"); } - else if (type.Equals(typeof(ushort))) + else if (type == typeof(ushort)) { output.Append("uint16_t"); } - else if (type.Equals(typeof(int))) + else if (type == typeof(int)) { output.Append("int32_t"); } - else if (type.Equals(typeof(uint))) + else if (type == typeof(uint)) { output.Append("uint32_t"); } - else if (type.Equals(typeof(long))) + else if (type == typeof(long)) { output.Append("int64_t"); } - else if (type.Equals(typeof(ulong))) + else if (type == typeof(ulong)) { output.Append("uint64_t"); } - else if (type.Equals(typeof(string))) + else if (type == typeof(char)) { - output.Append("System::String"); + output.Append("uint16_t"); // C# char is 2 bytes + } + else if (type == typeof(float)) + { + output.Append("float"); + } + else if (type == typeof(double)) + { + output.Append("double"); + } + else if (type == typeof(IntPtr)) + { + output.Append("void*"); } else { - AppendCppTypeName( - type.Namespace, - type.Name, - output); + throw new Exception(type + " is not a C++ primitive"); } } - static void AppendCppTypeName( - string namespaceName, - string name, - StringBuilder output) - { - AppendNamespace(namespaceName, "::", output); - output.Append("::"); - output.Append(name); - } - - static void LogStringBuilder( - string title, - StringBuilder builder) + static void RemoveTrailingChars( + StringBuilders builders) { - Debug.LogFormat( - "{0}:\n\n{1}\n\n", - title, - builder); + RemoveTrailingChars(builders.CsharpDelegateTypes); + RemoveTrailingChars(builders.CsharpStoreInitCalls); + RemoveTrailingChars(builders.CsharpInitCall); + RemoveTrailingChars(builders.CsharpBaseTypes); + RemoveTrailingChars(builders.CsharpFunctions); + RemoveTrailingChars(builders.CsharpCppDelegates); + RemoveTrailingChars(builders.CsharpCsharpDelegates); + RemoveTrailingChars(builders.CsharpImports); + RemoveTrailingChars(builders.CsharpGetDelegateCalls); + RemoveTrailingChars(builders.CsharpDestroyFunctionEnumerators); + RemoveTrailingChars(builders.CsharpDestroyQueueCases); + RemoveTrailingChars(builders.CppFunctionPointers); + RemoveTrailingChars(builders.CppTypeDeclarations); + RemoveTrailingChars(builders.CppTemplateDeclarations); + RemoveTrailingChars(builders.CppTemplateSpecializationDeclarations); + RemoveTrailingChars(builders.CppTypeDefinitions); + RemoveTrailingChars(builders.CppMethodDefinitions); + RemoveTrailingChars(builders.CppInitBodyParameterReads); + RemoveTrailingChars(builders.CppInitBodyArrays); + RemoveTrailingChars(builders.CppInitBodyFirstBoot); + RemoveTrailingChars(builders.CppGlobalStateAndFunctions); + RemoveTrailingChars(builders.CppUnboxingMethodDeclarations); + RemoveTrailingChars(builders.CppStringDefaultParams); + RemoveTrailingChars(builders.CppMacros); } + // Remove trailing chars (e.g. commas) for last elements static void RemoveTrailingChars( StringBuilder builder) { @@ -2566,38 +13473,167 @@ static void RemoveTrailingChars( for (i = len - 1; i >= 0; --i) { char cur = builder[i]; - switch (cur) + if (!char.IsWhiteSpace(cur) && cur != ',') { - case '\n': - case '\t': - case ',': - break; - default: - goto after; + break; } } - after: + if (i < len - 1) { builder.Remove(i + 1, len - i - 1); } } + static void InjectBuilders( + StringBuilders builders) + { + // Inject into source files + string csharpContents = File.ReadAllText(CsharpPath); + string cppHeaderContents = File.ReadAllText(CppHeaderPath); + string cppSourceContents = File.ReadAllText(CppSourcePath); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN DELEGATE TYPES*/", + "\t\t/*END DELEGATE TYPES*/", + builders.CsharpDelegateTypes.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN STORE INIT CALLS*/", + "\t\t\t/*END STORE INIT CALLS*/", + builders.CsharpStoreInitCalls.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN INIT CALL*/", + "\t\t\t/*END INIT CALL*/", + builders.CsharpInitCall.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN BASE TYPES*/", + "/*END BASE TYPES*/", + builders.CsharpBaseTypes.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN FUNCTIONS*/", + "\t\t/*END FUNCTIONS*/", + builders.CsharpFunctions.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN CPP DELEGATES*/", + "\t\t/*END CPP DELEGATES*/", + builders.CsharpCppDelegates.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN CSHARP DELEGATES*/", + "\t\t/*END CSHARP DELEGATES*/", + builders.CsharpCsharpDelegates.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN IMPORTS*/", + "\t\t/*END IMPORTS*/", + builders.CsharpImports.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN GETDELEGATE CALLS*/", + "\t\t\t/*END GETDELEGATE CALLS*/", + builders.CsharpGetDelegateCalls.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN DESTROY FUNCTION ENUMERATORS*/", + "\t\t\t/*END DESTROY FUNCTION ENUMERATORS*/", + builders.CsharpDestroyFunctionEnumerators.ToString()); + csharpContents = InjectIntoString( + csharpContents, + "/*BEGIN DESTROY QUEUE CASES*/", + "\t\t\t\t\t\t/*END DESTROY QUEUE CASES*/", + builders.CsharpDestroyQueueCases.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN FUNCTION POINTERS*/", + "\t/*END FUNCTION POINTERS*/", + builders.CppFunctionPointers.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN TYPE DECLARATIONS*/", + "/*END TYPE DECLARATIONS*/", + builders.CppTypeDeclarations.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN TEMPLATE DECLARATIONS*/", + "/*END TEMPLATE DECLARATIONS*/", + builders.CppTemplateDeclarations.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN TEMPLATE SPECIALIZATION DECLARATIONS*/", + "/*END TEMPLATE SPECIALIZATION DECLARATIONS*/", + builders.CppTemplateSpecializationDeclarations.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN TYPE DEFINITIONS*/", + "/*END TYPE DEFINITIONS*/", + builders.CppTypeDefinitions.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN METHOD DEFINITIONS*/", + "/*END METHOD DEFINITIONS*/", + builders.CppMethodDefinitions.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN INIT BODY PARAMETER READS*/", + "\t/*END INIT BODY PARAMETER READS*/", + builders.CppInitBodyParameterReads.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN INIT BODY ARRAYS*/", + "\t/*END INIT BODY ARRAYS*/", + builders.CppInitBodyArrays.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN INIT BODY FIRST BOOT*/", + "\t\t/*END INIT BODY FIRST BOOT*/", + builders.CppInitBodyFirstBoot.ToString()); + cppSourceContents = InjectIntoString( + cppSourceContents, + "/*BEGIN GLOBAL STATE AND FUNCTIONS*/", + "\t/*END GLOBAL STATE AND FUNCTIONS*/", + builders.CppGlobalStateAndFunctions.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN UNBOXING METHOD DECLARATIONS*/", + "\t\t/*END UNBOXING METHOD DECLARATIONS*/", + builders.CppUnboxingMethodDeclarations.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN STRING DEFAULT PARAMETERS*/", + "\t/*END STRING DEFAULT PARAMETERS*/", + builders.CppStringDefaultParams.ToString()); + cppHeaderContents = InjectIntoString( + cppHeaderContents, + "/*BEGIN MACROS*/", + "/*END MACROS*/", + builders.CppMacros.ToString()); + + File.WriteAllText(CsharpPath, csharpContents); + File.WriteAllText(CppHeaderPath, cppHeaderContents); + File.WriteAllText(CppSourcePath, cppSourceContents); + } + static string InjectIntoString( string contents, string beginMarker, string endMarker, string text) { - for (int startIndex = 0; true; ) + int startIndex = 0; + while(true) { - int beginIndex = contents.IndexOf(beginMarker, startIndex); + int beginIndex = contents.IndexOf(beginMarker, startIndex, StringComparison.OrdinalIgnoreCase); if (beginIndex < 0) { return contents; } int afterBeginIndex = beginIndex + beginMarker.Length; - int endIndex = contents.IndexOf(endMarker, afterBeginIndex); + int endIndex = contents.IndexOf(endMarker, afterBeginIndex, StringComparison.OrdinalIgnoreCase); if (endIndex < 0) { throw new Exception( @@ -2610,9 +13646,9 @@ static string InjectIntoString( } string begin = contents.Substring(0, afterBeginIndex); string end = contents.Substring(endIndex); - contents = begin + text + end; + contents = begin + Environment.NewLine + text + Environment.NewLine + end; startIndex = beginIndex + 1; } } } -} \ No newline at end of file +} diff --git a/Unity/Assets/NativeScript/ObjectStore.cs b/Unity/Assets/NativeScript/ObjectStore.cs deleted file mode 100644 index 2b41d9d..0000000 --- a/Unity/Assets/NativeScript/ObjectStore.cs +++ /dev/null @@ -1,138 +0,0 @@ -namespace NativeScript -{ - /// - /// Stores objects and allows access to them via an int. - /// This class is thread-safe. - /// - /// - /// - /// JacksonDunstan, http://JacksonDunstan.com/articles/3908 - /// - /// - /// - /// MIT - /// - public static class ObjectStore - { - // Stored objects. The first is always null. - private static object[] objects; - - // Stack of available handles - private static int[] handles; - - // Index of the next available handle - private static int nextHandleIndex; - - /// - /// Initialize the object storage and reset the handles - /// - /// - /// - /// Maximum number of objects to store. Must be positive. - /// - public static void Init(int maxObjects) - { - // Initialize the objects as all null plus room for the - // first to always be null. - objects = new object[maxObjects + 1]; - - // Initialize the handles stack as 1, 2, 3, ... - handles = new int[maxObjects]; - for ( - int i = 0, handle = maxObjects; - i < maxObjects; - ++i, --handle) - { - handles[i] = handle; - } - nextHandleIndex = maxObjects - 1; - } - - /// - /// Store an object - /// - /// - /// - /// Object to store. This can be null. - /// - /// - /// - /// An handle to the stored object that can be used with - /// and . If - /// has not yet been called, a - /// will be thrown. - /// - public static int Store(object obj) - { - // Null is always zero - if (object.ReferenceEquals(obj, null)) - { - return 0; - } - - lock (objects) - { - // Pop a handle off the stack - int handle = handles[nextHandleIndex]; - nextHandleIndex--; - - // Store the object - objects[handle] = obj; - - // Return the handle - return handle; - } - } - - /// - /// Get the object for a given handle - /// - /// - /// - /// Handle of the object to get. If this is less than zero - /// or greater than the maximum number of objects passed to - /// , this function will throw an - /// . If this - /// is zero, not a handle returned by , - /// a handle returned by a call to with - /// a null parameter, or a handle passed to - /// and not subsequently returned by - /// , this function will return null. If - /// has not yet been called, a - /// will be thrown. - /// - public static object Get(int handle) - { - return objects[handle]; - } - - /// - /// Remove a stored object - /// - /// - /// - /// Handle of the object to Remove. If this is less than - /// zero or greater than the maximum number of objects - /// passed to , this function will throw - /// an . The - /// handle may be be reused. If has not - /// yet been called, a - /// will be thrown. - /// - public static void Remove(int handle) - { - if (handle != 0) - { - lock (objects) - { - // Forget the object - objects[handle] = null; - - // Push the handle onto the stack - nextHandleIndex++; - handles[nextHandleIndex] = handle; - } - } - } - } -} \ No newline at end of file diff --git a/Unity/Assets/NativeScriptConstants.cs b/Unity/Assets/NativeScriptConstants.cs index 91c3171..54e6923 100644 --- a/Unity/Assets/NativeScriptConstants.cs +++ b/Unity/Assets/NativeScriptConstants.cs @@ -10,29 +10,8 @@ /// public static class NativeScriptConstants { - /// - /// Name of the plugin used by [DllImport] when running outside the editor - /// - public const string PluginName = "NativeScript"; - - /// - /// Path to load the plugin from when running inside the editor - /// -#if UNITY_EDITOR_OSX - public const string PluginPath = "/Plugins/Editor/NativeScript.bundle/Contents/MacOS/NativeScript"; -#elif UNITY_EDITOR_LINUX - public const string PluginPath = "/Plugins/Editor/libNativeScript.so"; -#elif UNITY_EDITOR_WIN - public const string PluginPath = "/Plugins/Editor/NativeScript.dll"; -#endif - - /// - /// Maximum number of simultaneous managed objects that the C++ plugin uses - /// - public const int MaxManagedObjects = 1024; - /// /// Path within the Unity project to the exposed types JSON file /// - public const string ExposedTypesJsonPath = "NativeScriptTypes.json"; + public const string JSON_CONFIG_PATH = "NativeScriptTypes.json"; } \ No newline at end of file diff --git a/Unity/Assets/NativeScriptTypes.json b/Unity/Assets/NativeScriptTypes.json index 2f80abf..c507547 100644 --- a/Unity/Assets/NativeScriptTypes.json +++ b/Unity/Assets/NativeScriptTypes.json @@ -1,138 +1,344 @@ { "Assemblies": [ + ], + "Types": [ + { + "Name": " System.IFormattable" + }, + { + "Name": " System.IConvertible" + }, { - "Path": "/Applications/Unity/Unity.app/Contents/Mono/lib/mono/unity/System.dll", - "Types": [ + "Name": " System.IComparable" + }, + { + "Name": "System.IEquatable`1", + "GenericParams": [ { - "Name": "System.Diagnostics.Stopwatch", - "Constructors": [ - { - "Types": [] - } - ], - "Methods": [ - { - "Name": "Start", - "ParamTypes": [] - }, - { - "Name": "Reset", - "ParamTypes": [] - } - ], - "Properties": [ "ElapsedMilliseconds" ], - "Fields": [] + "Types": [ + "System.Boolean" + ] + }, + { + "Types": [ + "System.Char" + ] + }, + { + "Types": [ + "System.SByte" + ] + }, + { + "Types": [ + "System.Byte" + ] + }, + { + "Types": [ + "System.Int16" + ] + }, + { + "Types": [ + "System.UInt16" + ] + }, + { + "Types": [ + "System.Int32" + ] + }, + { + "Types": [ + "System.UInt32" + ] + }, + { + "Types": [ + "System.Int64" + ] + }, + { + "Types": [ + "System.UInt64" + ] + }, + { + "Types": [ + "System.Single" + ] + }, + { + "Types": [ + "System.Double" + ] + }, + { + "Types": [ + "System.Decimal" + ] + }, + { + "Types": [ + "UnityEngine.Vector3" + ] } ] }, { - "Path": "/Applications/Unity/Unity.app/Contents/Managed/UnityEngine.dll", - "Types": [ + "Name": "System.IComparable`1", + "GenericParams": [ { - "Name": "UnityEngine.Object", - "Constructors": [], - "Methods": [], - "Properties": [ "name" ], - "Fields": [] + "Types": [ + "System.Boolean" + ] }, { - "Name": "UnityEngine.GameObject", - "Constructors": [ - { - "Types": [] - }, - { - "Types": [ "System.String" ] - } - ], - "Methods": [ - { - "Name": "Find", - "ReturnType": "UnityEngine.GameObject", - "ParamTypes": [ "System.String" ] - }, - { - "Name": "AddComponent", - "ReturnType": "T", - "ParamTypes": [], - "GenericTypes": [ - { - "Name": "T", - "Type": "MyGame.MonoBehaviours.TestScript" - } - ] - } - ], - "Properties": [ "transform" ], - "Fields": [] + "Types": [ + "System.Char" + ] }, { - "Name": "UnityEngine.Component", - "Constructors": [], - "Methods": [], - "Properties": [ "transform" ], - "Fields": [] + "Types": [ + "System.SByte" + ] }, { - "Name": "UnityEngine.Transform", - "Constructors": [], - "Methods": [], - "Properties": [ "position" ], - "Fields": [] + "Types": [ + "System.Byte" + ] }, { - "Name": "UnityEngine.Debug", - "Constructors": [], - "Methods": [ - { - "Name": "Log", - "ParamTypes": [ "System.Object" ] - } - ], - "Properties": [], - "Fields": [] + "Types": [ + "System.Int16" + ] + }, + { + "Types": [ + "System.UInt16" + ] + }, + { + "Types": [ + "System.Int32" + ] + }, + { + "Types": [ + "System.UInt32" + ] + }, + { + "Types": [ + "System.Int64" + ] }, { - "Name": "UnityEngine.Assertions.Assert", - "Constructors": [], - "Methods": [], - "Properties": [], - "Fields": [ "raiseExceptions" ] + "Types": [ + "System.UInt64" + ] }, { - "Name": "UnityEngine.Collision", - "Constructors": [], - "Methods": [], - "Properties": [], - "Fields": [] + "Types": [ + "System.Single" + ] }, { - "Name": "UnityEngine.Behaviour", - "Constructors": [], - "Methods": [], - "Properties": [], - "Fields": [] + "Types": [ + "System.Double" + ] }, { - "Name": "UnityEngine.MonoBehaviour", - "Constructors": [], - "Methods": [], - "Properties": [], - "Fields": [] + "Types": [ + "System.Decimal" + ] } ] - } - ], - "MonoBehaviours": [ - { - "Name": "TestScript", - "Namespace": "MyGame.MonoBehaviours", - "Messages": [ - "Awake", - "OnAnimatorIK", - "OnCollisionEnter", - "Update" + }, + { + "Name": " System.Runtime.Serialization.IDeserializationCallback" + }, + { + "Name": "System.Decimal", + "Constructors": [ + { + "ParamTypes": [ + "System.Double" + ] + }, + { + "ParamTypes": [ + "System.UInt64" + ] + } + ] + }, + { + "Name": "UnityEngine.Vector3", + "Constructors": [ + { + "ParamTypes": [ + "System.Single", + "System.Single", + "System.Single" + ] + } + ], + "Methods": [ + { + "Name": "x+y", + "ParamTypes": [ + "UnityEngine.Vector3", + "UnityEngine.Vector3" + ] + } + ] + }, + { + "Name": "UnityEngine.Object", + "Properties": [ + { + "Name": "name", + "Get": {}, + "Set": {} + } + ] + }, + { + "Name": "UnityEngine.Component", + "Properties": [ + { + "Name": "transform", + "Get": {} + } + ] + }, + { + "Name": "UnityEngine.Transform", + "Properties": [ + { + "Name": "position", + "Get": {}, + "Set": { + "Exceptions": [ + "System.NullReferenceException" + ] + } + } + ] + }, + { + "Name": "System.Collections.IEnumerator", + "Methods": [ + { + "Name": "MoveNext", + "ParamTypes": [] + } + ], + "Properties": [ + { + "Name": "Current", + "Get": {}, + "Set": {} + } + ] + }, + { + "Name": "System.Runtime.Serialization.ISerializable" + }, + { + "Name": "System.Runtime.InteropServices._Exception" + }, + { + "Name": "UnityEngine.GameObject", + "Constructors": [ + ], + "Methods": [ + { + "Name": "AddComponent", + "ParamTypes": [], + "GenericParams": [ + { + "Types": [ + "MyGame.BaseBallScript" + ] + } + ] + }, + { + "Name": "CreatePrimitive", + "ParamTypes": [ + "UnityEngine.PrimitiveType" + ] + } + ] + }, + { + "Name": "UnityEngine.Debug", + "Methods": [ + { + "Name": "Log", + "ParamTypes": [ + "System.Object" + ] + } + ] + }, + { + "Name": "UnityEngine.Behaviour" + }, + { + "Name": "UnityEngine.MonoBehaviour", + "Properties": [ + { + "Name": "transform", + "Get": {}, + "Set": {} + } + ] + }, + { + "Name": "System.Exception", + "Constructors": [ + { + "ParamTypes": [ + "System.String" + ] + } + ] + }, + { + "Name": "System.SystemException" + }, + { + "Name": "System.NullReferenceException" + }, + { + "Name": "UnityEngine.PrimitiveType" + }, + { + "Name": "UnityEngine.Time", + "Properties": [ + { + "Name": "deltaTime", + "Get": {}, + "Set": {} + } + ] + }, + { + "Name": "MyGame.AbstractBaseBallScript", + "BaseTypes": [ + { + "BaseName": "MyGame.BaseBallScript", + "DerivedName": "MyGame.BallScript" + } ] } + ], + "Arrays": [ + ], + "Delegates": [ ] } \ No newline at end of file diff --git a/Unity/CppSource/Game.cpp.meta b/Unity/CppSource/Game.cpp.meta deleted file mode 100644 index bf03a81..0000000 --- a/Unity/CppSource/Game.cpp.meta +++ /dev/null @@ -1,27 +0,0 @@ -fileFormatVersion: 2 -guid: 5189acf91e865474290ba468798fb338 -timeCreated: 1501907744 -licenseType: Free -PluginImporter: - serializedVersion: 2 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - isOverridable: 0 - platformData: - data: - first: - Any: - second: - enabled: 1 - settings: {} - data: - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - userData: - assetBundleName: - assetBundleVariant: diff --git a/Unity/CppSource/Game/Game.cpp b/Unity/CppSource/Game/Game.cpp deleted file mode 100644 index f4c1ad4..0000000 --- a/Unity/CppSource/Game/Game.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/// -/// Game-specific code for the native plugin -/// -/// -/// Jackson Dunstan, 2017, http://JacksonDunstan.com -/// -/// -/// MIT -/// - -#include "Bindings.h" - -using namespace System; -using namespace UnityEngine; - -void PrintPlatformDefines(); - -// Called when the plugin is initialized -void PluginMain() -{ - PrintPlatformDefines(); - Debug::Log(String("Game booted up")); - GameObject go(String("GameObject with a TestScript")); - go.AddComponent(); -} - -void MyGame::MonoBehaviours::TestScript::Awake() -{ - Debug::Log(String("C++ TestScript Awake")); -} - -void MyGame::MonoBehaviours::TestScript::OnAnimatorIK(int32_t param0) -{ - Debug::Log(String("C++ TestScript OnAnimatorIK")); -} - -void MyGame::MonoBehaviours::TestScript::OnCollisionEnter(UnityEngine::Collision param0) -{ - Debug::Log(String("C++ TestScript OnCollisionEnter")); -} - -void MyGame::MonoBehaviours::TestScript::Update() -{ - static int32_t numCreated = 0; - if (numCreated < 10) - { - GameObject go; - Transform transform = go.GetTransform(); - float comp = (float)numCreated; - Vector3 position(comp, comp, comp); - transform.SetPosition(position); - numCreated++; - if (numCreated == 10) - { - Debug::Log(String("Done spawning game objects")); - } - } -} - -void PrintPlatformDefines() -{ -#if defined(UNITY_EDITOR) - Debug::Log(String("UNITY_EDITOR")); -#endif -#if defined(UNITY_STANDALONE) - Debug::Log(String("UNITY_STANDALONE")); -#endif -#if defined(UNITY_IOS) - Debug::Log(String("UNITY_IOS")); -#endif -#if defined(UNITY_ANDROID) - Debug::Log(String("UNITY_ANDROID")); -#endif -#if defined(UNITY_EDITOR_WIN) - Debug::Log(String("UNITY_EDITOR_WIN")); -#endif -#if defined(UNITY_EDITOR_OSX) - Debug::Log(String("UNITY_EDITOR_OSX")); -#endif -#if defined(UNITY_EDITOR_LINUX) - Debug::Log(String("UNITY_EDITOR_LINUX")); -#endif -#if defined(UNITY_STANDALONE_OSX) - Debug::Log(String("UNITY_STANDALONE_OSX")); -#endif -#if defined(UNITY_STANDALONE_WIN) - Debug::Log(String("UNITY_STANDALONE_WIN")); -#endif -#if defined(UNITY_STANDALONE_LINUX) - Debug::Log(String("UNITY_STANDALONE_LINUX")); -#endif -} diff --git a/Unity/CppSource/NativeScript/Bindings.cpp b/Unity/CppSource/NativeScript/Bindings.cpp deleted file mode 100644 index 1ba55f0..0000000 --- a/Unity/CppSource/NativeScript/Bindings.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/// -/// Internals of the bindings between native and .NET code. -/// Game code shouldn't go here. -/// -/// -/// Jackson Dunstan, 2017, http://JacksonDunstan.com -/// -/// -/// MIT -/// - -// Type definitions -#include "Bindings.h" - -// For assert() -#include - -// For int32_t, etc. -#include - -// For malloc(), etc. -#include - -// For std::forward -#include - -// Macro to put before functions that need to be exposed to C# -#ifdef _WIN32 - #define DLLEXPORT extern "C" __declspec(dllexport) -#else - #define DLLEXPORT extern "C" -#endif - -//////////////////////////////////////////////////////////////// -// C# functions for C++ to call -//////////////////////////////////////////////////////////////// - -namespace Plugin -{ - void (*ReleaseObject)(int32_t handle); - - int32_t (*StringNew)(const char* chars); - - /*BEGIN FUNCTION POINTERS*/ - int32_t (*StopwatchConstructor)(); - int64_t (*StopwatchPropertyGetElapsedMilliseconds)(int32_t thisHandle); - void (*StopwatchMethodStart)(int32_t thisHandle); - void (*StopwatchMethodReset)(int32_t thisHandle); - int32_t (*ObjectPropertyGetName)(int32_t thisHandle); - void (*ObjectPropertySetName)(int32_t thisHandle, int32_t valueHandle); - int32_t (*GameObjectConstructor)(); - int32_t (*GameObjectConstructorSystemString)(int32_t nameHandle); - int32_t (*GameObjectPropertyGetTransform)(int32_t thisHandle); - int32_t (*GameObjectMethodFindSystemString)(int32_t nameHandle); - int32_t (*GameObjectMethodAddComponentMyGameMonoBehavioursTestScript)(int32_t thisHandle); - int32_t (*ComponentPropertyGetTransform)(int32_t thisHandle); - UnityEngine::Vector3 (*TransformPropertyGetPosition)(int32_t thisHandle); - void (*TransformPropertySetPosition)(int32_t thisHandle, UnityEngine::Vector3 value); - void (*DebugMethodLogSystemObject)(int32_t messageHandle); - System::Boolean (*AssertFieldGetRaiseExceptions)(); - void (*AssertFieldSetRaiseExceptions)(System::Boolean value); - /*END FUNCTION POINTERS*/ -} - -//////////////////////////////////////////////////////////////// -// Reference counting of managed objects -//////////////////////////////////////////////////////////////// - -namespace Plugin -{ - int32_t managedObjectsRefCountLen; - int32_t* managedObjectRefCounts; - - void ReferenceManagedObject(int32_t handle) - { - assert(handle >= 0 && handle < managedObjectsRefCountLen); - if (handle != 0) - { - managedObjectRefCounts[handle]++; - } - } - - void DereferenceManagedObject(int32_t handle) - { - assert(handle >= 0 && handle < managedObjectsRefCountLen); - if (handle != 0) - { - int32_t numRemain = --managedObjectRefCounts[handle]; - if (numRemain == 0) - { - ReleaseObject(handle); - } - } - } -} - -//////////////////////////////////////////////////////////////// -// Mirrors of C# types. These wrap the C# functions to present -// a similiar API as in C#. -//////////////////////////////////////////////////////////////// - -namespace System -{ - Object::Object(int32_t handle) - { - Handle = handle; - Plugin::ReferenceManagedObject(handle); - } - - Object::Object(const Object& other) - { - Handle = other.Handle; - Plugin::ReferenceManagedObject(Handle); - } - - Object::Object(Object&& other) - { - Handle = other.Handle; - other.Handle = 0; - } - - #define SYSTEM_OBJECT_LIFECYCLE_DEFINITION(ClassName, BaseClassName) \ - ClassName::ClassName(int32_t handle) \ - : BaseClassName(handle) \ - { \ - } \ - \ - ClassName::ClassName(const ClassName& other) \ - : BaseClassName(other) \ - { \ - } \ - \ - ClassName::ClassName(ClassName&& other) \ - : BaseClassName(std::forward(other)) \ - { \ - } \ - \ - ClassName::~ClassName() \ - { \ - Plugin::DereferenceManagedObject(Handle); \ - } \ - \ - ClassName& ClassName::operator=(const ClassName& other) \ - { \ - Plugin::DereferenceManagedObject(Handle); \ - Handle = other.Handle; \ - Plugin::ReferenceManagedObject(Handle); \ - return *this; \ - } \ - \ - ClassName& ClassName::operator=(ClassName&& other) \ - { \ - Plugin::DereferenceManagedObject(Handle); \ - Handle = other.Handle; \ - other.Handle = 0; \ - return *this; \ - } - - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(String, System::Object) - - String::String(const char* chars) - : String(Plugin::StringNew(chars)) - { - } -} - -/*BEGIN METHOD DEFINITIONS*/ -namespace System -{ - namespace Diagnostics - { - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Stopwatch, System::Object) - - Stopwatch::Stopwatch() - : Stopwatch(Stopwatch(Plugin::StopwatchConstructor())) - { - } - - int64_t Stopwatch::GetElapsedMilliseconds() - { - return Plugin::StopwatchPropertyGetElapsedMilliseconds(Handle); - } - - void Stopwatch::Start() - { - Plugin::StopwatchMethodStart(Handle); - } - - void Stopwatch::Reset() - { - Plugin::StopwatchMethodReset(Handle); - } - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Object, System::Object) - - System::String Object::GetName() - { - return System::String(Plugin::ObjectPropertyGetName(Handle)); - } - - void Object::SetName(System::String value) - { - Plugin::ObjectPropertySetName(Handle, value.Handle); - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(GameObject, UnityEngine::Object) - - GameObject::GameObject() - : GameObject(GameObject(Plugin::GameObjectConstructor())) - { - } - - GameObject::GameObject(System::String name) - : GameObject(GameObject(Plugin::GameObjectConstructorSystemString(name.Handle))) - { - } - - UnityEngine::Transform GameObject::GetTransform() - { - return UnityEngine::Transform(Plugin::GameObjectPropertyGetTransform(Handle)); - } - - UnityEngine::GameObject GameObject::Find(System::String name) - { - return UnityEngine::GameObject(Plugin::GameObjectMethodFindSystemString(name.Handle)); - } - - template<> MyGame::MonoBehaviours::TestScript GameObject::AddComponent() - { - return MyGame::MonoBehaviours::TestScript(Plugin::GameObjectMethodAddComponentMyGameMonoBehavioursTestScript(Handle)); - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Component, UnityEngine::Object) - - UnityEngine::Transform Component::GetTransform() - { - return UnityEngine::Transform(Plugin::ComponentPropertyGetTransform(Handle)); - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Transform, UnityEngine::Component) - - UnityEngine::Vector3 Transform::GetPosition() - { - return Plugin::TransformPropertyGetPosition(Handle); - } - - void Transform::SetPosition(UnityEngine::Vector3 value) - { - Plugin::TransformPropertySetPosition(Handle, value); - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Debug, System::Object) - - void Debug::Log(System::Object message) - { - Plugin::DebugMethodLogSystemObject(message.Handle); - } -} - -namespace UnityEngine -{ - namespace Assertions - { - System::Boolean Assert::GetRaiseExceptions() - { - return Plugin::AssertFieldGetRaiseExceptions(); - } - - void Assert::SetRaiseExceptions(System::Boolean value) - { - Plugin::AssertFieldSetRaiseExceptions(value); - } - } -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Collision, System::Object) -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(Behaviour, UnityEngine::Component) -} - -namespace UnityEngine -{ - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(MonoBehaviour, UnityEngine::Behaviour) -} - -namespace MyGame -{ - namespace MonoBehaviours - { - SYSTEM_OBJECT_LIFECYCLE_DEFINITION(TestScript, UnityEngine::MonoBehaviour) - } -} -/*END METHOD DEFINITIONS*/ - -//////////////////////////////////////////////////////////////// -// App-specific functions for this file to call -//////////////////////////////////////////////////////////////// - -// Called when the plugin is initialized -extern void PluginMain(); - -//////////////////////////////////////////////////////////////// -// C++ functions for C# to call -//////////////////////////////////////////////////////////////// - -// Init the plugin -DLLEXPORT void Init( - int32_t maxManagedObjects, - void (*releaseObject)(int32_t handle), - int32_t (*stringNew)(const char* chars), - /*BEGIN INIT PARAMS*/ - int32_t (*stopwatchConstructor)(), - int64_t (*stopwatchPropertyGetElapsedMilliseconds)(int32_t thisHandle), - void (*stopwatchMethodStart)(int32_t thisHandle), - void (*stopwatchMethodReset)(int32_t thisHandle), - int32_t (*objectPropertyGetName)(int32_t thisHandle), - void (*objectPropertySetName)(int32_t thisHandle, int32_t valueHandle), - int32_t (*gameObjectConstructor)(), - int32_t (*gameObjectConstructorSystemString)(int32_t nameHandle), - int32_t (*gameObjectPropertyGetTransform)(int32_t thisHandle), - int32_t (*gameObjectMethodFindSystemString)(int32_t nameHandle), - int32_t (*gameObjectMethodAddComponentMyGameMonoBehavioursTestScript)(int32_t thisHandle), - int32_t (*componentPropertyGetTransform)(int32_t thisHandle), - UnityEngine::Vector3 (*transformPropertyGetPosition)(int32_t thisHandle), - void (*transformPropertySetPosition)(int32_t thisHandle, UnityEngine::Vector3 value), - void (*debugMethodLogSystemObject)(int32_t messageHandle), - System::Boolean (*assertFieldGetRaiseExceptions)(), - void (*assertFieldSetRaiseExceptions)(System::Boolean value) - /*END INIT PARAMS*/) -{ - using namespace Plugin; - - // Init managed object ref counting - managedObjectsRefCountLen = maxManagedObjects; - managedObjectRefCounts = (int32_t*)calloc( - maxManagedObjects, - sizeof(int32_t)); - - // Init pointers to C# functions - StringNew = stringNew; - ReleaseObject = releaseObject; - /*BEGIN INIT BODY*/ - StopwatchConstructor = stopwatchConstructor; - StopwatchPropertyGetElapsedMilliseconds = stopwatchPropertyGetElapsedMilliseconds; - StopwatchMethodStart = stopwatchMethodStart; - StopwatchMethodReset = stopwatchMethodReset; - ObjectPropertyGetName = objectPropertyGetName; - ObjectPropertySetName = objectPropertySetName; - GameObjectConstructor = gameObjectConstructor; - GameObjectConstructorSystemString = gameObjectConstructorSystemString; - GameObjectPropertyGetTransform = gameObjectPropertyGetTransform; - GameObjectMethodFindSystemString = gameObjectMethodFindSystemString; - GameObjectMethodAddComponentMyGameMonoBehavioursTestScript = gameObjectMethodAddComponentMyGameMonoBehavioursTestScript; - ComponentPropertyGetTransform = componentPropertyGetTransform; - TransformPropertyGetPosition = transformPropertyGetPosition; - TransformPropertySetPosition = transformPropertySetPosition; - DebugMethodLogSystemObject = debugMethodLogSystemObject; - AssertFieldGetRaiseExceptions = assertFieldGetRaiseExceptions; - AssertFieldSetRaiseExceptions = assertFieldSetRaiseExceptions; - /*END INIT BODY*/ - - PluginMain(); -} - -/*BEGIN MONOBEHAVIOUR MESSAGES*/ -DLLEXPORT void TestScriptAwake(int32_t thisHandle) -{ - MyGame::MonoBehaviours::TestScript thiz(thisHandle); - thiz.Awake(); -} - -DLLEXPORT void TestScriptOnAnimatorIK(int32_t thisHandle, int32_t param0) -{ - MyGame::MonoBehaviours::TestScript thiz(thisHandle); - thiz.OnAnimatorIK(param0); -} - -DLLEXPORT void TestScriptOnCollisionEnter(int32_t thisHandle, int32_t param0Handle) -{ - MyGame::MonoBehaviours::TestScript thiz(thisHandle); - UnityEngine::Collision param0(param0Handle); - thiz.OnCollisionEnter(param0); -} - -DLLEXPORT void TestScriptUpdate(int32_t thisHandle) -{ - MyGame::MonoBehaviours::TestScript thiz(thisHandle); - thiz.Update(); -} -/*END MONOBEHAVIOUR MESSAGES*/ diff --git a/Unity/CppSource/NativeScript/Bindings.h b/Unity/CppSource/NativeScript/Bindings.h deleted file mode 100644 index e02e014..0000000 --- a/Unity/CppSource/NativeScript/Bindings.h +++ /dev/null @@ -1,291 +0,0 @@ -/// -/// Declaration of the various .NET types exposed to C++ -/// -/// -/// Jackson Dunstan, 2017, http://JacksonDunstan.com -/// -/// -/// MIT -/// - -#pragma once - -// For int32_t, etc. -#include - -//////////////////////////////////////////////////////////////// -// C# struct types -//////////////////////////////////////////////////////////////// - -namespace System -{ - // .NET booleans are four bytes long - typedef int32_t Boolean; -} - -namespace UnityEngine -{ - struct Vector3 - { - float x; - float y; - float z; - - Vector3() - : x(0.0f) - , y(0.0f) - , z(0.0f) - { - } - - Vector3( - float x, - float y, - float z) - : x(x) - , y(y) - , z(z) - { - } - - Vector3 operator+(const Vector3& other) - { - return { - x + other.x, - y + other.y, - z + other.z }; - } - - Vector3& operator=(const Vector3& other) - { - x = other.x; - y = other.y; - z = other.z; - return *this; - } - - Vector3& operator+=(const Vector3& other) - { - x += other.x; - y += other.y; - z += other.z; - return *this; - } - }; -} - -//////////////////////////////////////////////////////////////// -// C# type declarations -//////////////////////////////////////////////////////////////// - -namespace System -{ - struct Object - { - int32_t Handle; - Object(int32_t handle); - Object(const Object& other); - Object(Object&& other); - }; - -#define SYSTEM_OBJECT_LIFECYCLE_DECLARATION(ClassName, BaseClassName) \ - ClassName(int32_t handle); \ - ClassName(const ClassName& other); \ - ClassName(ClassName&& other); \ - ~ClassName(); \ - ClassName& operator=(const ClassName& other); \ - ClassName& operator=(ClassName&& other); - - struct String : Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(String, Object); - String(const char* chars); - }; -} - -/*BEGIN TYPE DECLARATIONS*/ -namespace System -{ - namespace Diagnostics - { - struct Stopwatch; - } -} - -namespace UnityEngine -{ - struct Object; -} - -namespace UnityEngine -{ - struct GameObject; -} - -namespace UnityEngine -{ - struct Component; -} - -namespace UnityEngine -{ - struct Transform; -} - -namespace UnityEngine -{ - struct Debug; -} - -namespace UnityEngine -{ - namespace Assertions - { - namespace Assert - { - } - } -} - -namespace UnityEngine -{ - struct Collision; -} - -namespace UnityEngine -{ - struct Behaviour; -} - -namespace UnityEngine -{ - struct MonoBehaviour; -} - -namespace MyGame -{ - namespace MonoBehaviours - { - struct TestScript; - } -} -/*END TYPE DECLARATIONS*/ - -/*BEGIN TYPE DEFINITIONS*/ -namespace System -{ - namespace Diagnostics - { - struct Stopwatch : System::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Stopwatch, System::Object) - Stopwatch(); - int64_t GetElapsedMilliseconds(); - void Start(); - void Reset(); - }; - } -} - -namespace UnityEngine -{ - struct Object : System::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Object, System::Object) - System::String GetName(); - void SetName(System::String value); - }; -} - -namespace UnityEngine -{ - struct GameObject : UnityEngine::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(GameObject, UnityEngine::Object) - GameObject(); - GameObject(System::String name); - UnityEngine::Transform GetTransform(); - static UnityEngine::GameObject Find(System::String name); - template T0 AddComponent(); - }; -} - -namespace UnityEngine -{ - struct Component : UnityEngine::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Component, UnityEngine::Object) - UnityEngine::Transform GetTransform(); - }; -} - -namespace UnityEngine -{ - struct Transform : UnityEngine::Component - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Transform, UnityEngine::Component) - UnityEngine::Vector3 GetPosition(); - void SetPosition(UnityEngine::Vector3 value); - }; -} - -namespace UnityEngine -{ - struct Debug : System::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Debug, System::Object) - static void Log(System::Object message); - }; -} - -namespace UnityEngine -{ - namespace Assertions - { - namespace Assert - { - static System::Boolean GetRaiseExceptions(); - static void SetRaiseExceptions(System::Boolean value); - } - } -} - -namespace UnityEngine -{ - struct Collision : System::Object - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Collision, System::Object) - }; -} - -namespace UnityEngine -{ - struct Behaviour : UnityEngine::Component - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(Behaviour, UnityEngine::Component) - }; -} - -namespace UnityEngine -{ - struct MonoBehaviour : UnityEngine::Behaviour - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(MonoBehaviour, UnityEngine::Behaviour) - }; -} - -namespace MyGame -{ - namespace MonoBehaviours - { - struct TestScript : UnityEngine::MonoBehaviour - { - SYSTEM_OBJECT_LIFECYCLE_DECLARATION(TestScript, UnityEngine::MonoBehaviour) - void Awake(); - void OnAnimatorIK(int32_t param0); - void OnCollisionEnter(UnityEngine::Collision param0); - void Update(); - }; - } -} -/*END TYPE DEFINITIONS*/ diff --git a/Unity/Packages/manifest.json b/Unity/Packages/manifest.json new file mode 100644 index 0000000..bc19e66 --- /dev/null +++ b/Unity/Packages/manifest.json @@ -0,0 +1,51 @@ +{ + "dependencies": { + "com.unity.2d.sprite": "1.0.0", + "com.unity.2d.tilemap": "1.0.0", + "com.unity.ads": "2.0.8", + "com.unity.analytics": "3.3.2", + "com.unity.collab-proxy": "1.2.16", + "com.unity.ext.nunit": "1.0.0", + "com.unity.ide.rider": "1.0.8", + "com.unity.ide.vscode": "1.0.7", + "com.unity.multiplayer-hlapi": "1.0.2", + "com.unity.package-manager-ui": "2.2.0", + "com.unity.purchasing": "2.0.6", + "com.unity.test-framework": "1.0.13", + "com.unity.textmeshpro": "2.0.1", + "com.unity.timeline": "1.1.0", + "com.unity.ugui": "1.0.0", + "com.unity.xr.legacyinputhelpers": "2.0.2", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/Unity/ProjectSettings/AudioManager.asset b/Unity/ProjectSettings/AudioManager.asset index 47d3cd3..da61125 100644 Binary files a/Unity/ProjectSettings/AudioManager.asset and b/Unity/ProjectSettings/AudioManager.asset differ diff --git a/Unity/ProjectSettings/ClusterInputManager.asset b/Unity/ProjectSettings/ClusterInputManager.asset index aaa5770..e7886b2 100644 Binary files a/Unity/ProjectSettings/ClusterInputManager.asset and b/Unity/ProjectSettings/ClusterInputManager.asset differ diff --git a/Unity/ProjectSettings/DynamicsManager.asset b/Unity/ProjectSettings/DynamicsManager.asset index 22d9747..0be3d78 100644 Binary files a/Unity/ProjectSettings/DynamicsManager.asset and b/Unity/ProjectSettings/DynamicsManager.asset differ diff --git a/Unity/ProjectSettings/EditorBuildSettings.asset b/Unity/ProjectSettings/EditorBuildSettings.asset index 343a10c..c813dae 100644 Binary files a/Unity/ProjectSettings/EditorBuildSettings.asset and b/Unity/ProjectSettings/EditorBuildSettings.asset differ diff --git a/Unity/ProjectSettings/EditorSettings.asset b/Unity/ProjectSettings/EditorSettings.asset index 9ad0db5..4b908a6 100644 Binary files a/Unity/ProjectSettings/EditorSettings.asset and b/Unity/ProjectSettings/EditorSettings.asset differ diff --git a/Unity/ProjectSettings/GraphicsSettings.asset b/Unity/ProjectSettings/GraphicsSettings.asset index 5403e07..646b92e 100644 Binary files a/Unity/ProjectSettings/GraphicsSettings.asset and b/Unity/ProjectSettings/GraphicsSettings.asset differ diff --git a/Unity/ProjectSettings/InputManager.asset b/Unity/ProjectSettings/InputManager.asset index 8af48d3..9e606dc 100644 Binary files a/Unity/ProjectSettings/InputManager.asset and b/Unity/ProjectSettings/InputManager.asset differ diff --git a/Unity/ProjectSettings/NavMeshAreas.asset b/Unity/ProjectSettings/NavMeshAreas.asset index a2aa728..6dd520f 100644 Binary files a/Unity/ProjectSettings/NavMeshAreas.asset and b/Unity/ProjectSettings/NavMeshAreas.asset differ diff --git a/Unity/ProjectSettings/NetworkManager.asset b/Unity/ProjectSettings/NetworkManager.asset index 735131d..5dc6a83 100644 Binary files a/Unity/ProjectSettings/NetworkManager.asset and b/Unity/ProjectSettings/NetworkManager.asset differ diff --git a/Unity/ProjectSettings/Physics2DSettings.asset b/Unity/ProjectSettings/Physics2DSettings.asset index 055659b..132ee6b 100644 Binary files a/Unity/ProjectSettings/Physics2DSettings.asset and b/Unity/ProjectSettings/Physics2DSettings.asset differ diff --git a/Unity/ProjectSettings/PresetManager.asset b/Unity/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..636a595 --- /dev/null +++ b/Unity/ProjectSettings/PresetManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: [] diff --git a/Unity/ProjectSettings/ProjectSettings.asset b/Unity/ProjectSettings/ProjectSettings.asset index 5893f9d..8602e2b 100644 Binary files a/Unity/ProjectSettings/ProjectSettings.asset and b/Unity/ProjectSettings/ProjectSettings.asset differ diff --git a/Unity/ProjectSettings/ProjectVersion.txt b/Unity/ProjectSettings/ProjectVersion.txt index ca1aa05..7e64146 100644 --- a/Unity/ProjectSettings/ProjectVersion.txt +++ b/Unity/ProjectSettings/ProjectVersion.txt @@ -1 +1,2 @@ -m_EditorVersion: 2017.1.0f3 +m_EditorVersion: 2019.2.0f1 +m_EditorVersionWithRevision: 2019.2.0f1 (20c1667945cf) diff --git a/Unity/ProjectSettings/QualitySettings.asset b/Unity/ProjectSettings/QualitySettings.asset index ebd1413..2df1db4 100644 Binary files a/Unity/ProjectSettings/QualitySettings.asset and b/Unity/ProjectSettings/QualitySettings.asset differ diff --git a/Unity/ProjectSettings/TagManager.asset b/Unity/ProjectSettings/TagManager.asset index f73f240..1c92a78 100644 Binary files a/Unity/ProjectSettings/TagManager.asset and b/Unity/ProjectSettings/TagManager.asset differ diff --git a/Unity/ProjectSettings/TimeManager.asset b/Unity/ProjectSettings/TimeManager.asset index 0bb43e7..558a017 100644 Binary files a/Unity/ProjectSettings/TimeManager.asset and b/Unity/ProjectSettings/TimeManager.asset differ diff --git a/Unity/ProjectSettings/UnityAdsSettings.asset b/Unity/ProjectSettings/UnityAdsSettings.asset deleted file mode 100644 index e6070fc..0000000 Binary files a/Unity/ProjectSettings/UnityAdsSettings.asset and /dev/null differ diff --git a/Unity/ProjectSettings/UnityConnectSettings.asset b/Unity/ProjectSettings/UnityConnectSettings.asset index ff80668..c3ae9a0 100644 Binary files a/Unity/ProjectSettings/UnityConnectSettings.asset and b/Unity/ProjectSettings/UnityConnectSettings.asset differ diff --git a/Unity/ProjectSettings/VFXManager.asset b/Unity/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..6e0eaca --- /dev/null +++ b/Unity/ProjectSettings/VFXManager.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/Unity/ProjectSettings/XRSettings.asset b/Unity/ProjectSettings/XRSettings.asset new file mode 100644 index 0000000..482590c --- /dev/null +++ b/Unity/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file