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