├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── build-bindings.hxml ├── cli.hxml ├── extraParams.hxml ├── haxelib.json ├── run.n ├── src ├── HxGodot.hx ├── godot │ ├── Types.hx │ ├── Wrapped.hx │ ├── core │ │ ├── GDConstants.hx │ │ └── GDMath.hx │ ├── debug │ │ └── HxGodotDebugInterface.hx │ ├── macros │ │ ├── ArgumentMacros.hx │ │ ├── ClassGenExtraMacros.hx │ │ ├── ClassGenMacros.hx │ │ ├── DocTools.hx │ │ ├── FunctionMacros.hx │ │ ├── Macros.hx │ │ ├── PostInitMacros.hx │ │ ├── TypeMacros.hx │ │ └── VariantMacros.hx │ └── variant │ │ ├── Color.hx │ │ ├── IBuiltIn.hx │ │ ├── Plane.hx │ │ ├── Point2.hx │ │ ├── Point2i.hx │ │ ├── Quaternion.hx │ │ ├── Rect2._hx │ │ ├── Rect2i._hx │ │ ├── TypedSignal.hx │ │ ├── Variant.hx │ │ ├── Vector2.hx │ │ ├── Vector2i.hx │ │ ├── Vector3.hx │ │ ├── Vector3i.hx │ │ ├── Vector4.hx │ │ └── Vector4i.hx ├── godot_cpp │ ├── core │ │ ├── defs.hpp │ │ └── error_macros.hpp │ ├── extension_api.json │ ├── gdextension_interface.h │ ├── godot.cpp │ ├── godot.hpp │ └── variant │ │ └── variant_size.hpp ├── hxcpp_ext │ ├── Dynamic2.cpp │ ├── Dynamic2.h │ └── hxgodot_api.cpp ├── hxgodot_extension.cpp ├── hxgodot_extension.h ├── import.hx └── utils │ ├── RootedObject.cpp │ └── RootedObject.hpp └── tools ├── run ├── RunMain.hx ├── compile.hxml └── hxformat.json └── template ├── .vscode └── settings.json ├── SConstruct ├── bin └── .gdignore ├── build.hxml ├── default_env.tres ├── example.gdextension ├── icon.png ├── icon.png.import ├── icons ├── haxe-logo-glyph.svg └── haxe-logo-glyph.svg.import ├── main.tscn ├── project.godot ├── src ├── .gdignore └── example │ ├── HxExample.hx │ ├── HxOther.hx │ └── testPackage │ └── HxOtherInPackage.hx └── test.gd /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c eol=lf 2 | *.cpp eol=lf 3 | *.gd eol=lf 4 | *.tscn eol=lf 5 | *.cfg eol=lf 6 | *.godot eol=lf 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot auto generated files 2 | *.gen.* 3 | .import/ 4 | .godot/ 5 | /gen/ 6 | 7 | # Misc 8 | logs/* 9 | *.log 10 | 11 | # Binaries 12 | *.o 13 | *.os 14 | *.so 15 | *.obj 16 | *.bc 17 | *.pyc 18 | *.dblite 19 | *.pdb 20 | *.lib 21 | *.config 22 | *.creator 23 | *.creator.user 24 | *.files 25 | *.includes 26 | *.idb 27 | 28 | # Gprof output 29 | gmon.out 30 | 31 | # Vim temp files 32 | *.swo 33 | *.swp 34 | 35 | # Qt project files 36 | *.config 37 | *.creator 38 | *.creator.* 39 | *.files 40 | *.includes 41 | *.cflags 42 | *.cxxflags 43 | 44 | # Eclipse CDT files 45 | .cproject 46 | .settings/ 47 | 48 | # Geany/geany-plugins files 49 | *.geany 50 | .geanyprj 51 | 52 | # Misc 53 | .DS_Store 54 | logs/ 55 | 56 | # for projects that use SCons for building: http://http://www.scons.org/ 57 | .sconf_temp 58 | .sconsign.dblite 59 | *.pyc 60 | 61 | # Visual C++ cache files 62 | ipch/ 63 | *.aps 64 | *.ncb 65 | *.opensdf 66 | *.sdf 67 | *.cachefile 68 | *.VC.db 69 | *.VC.opendb 70 | *.VC.VC.opendb 71 | enc_temp_folder/ 72 | 73 | # Visual Studio profiler 74 | *.psess 75 | *.vsp 76 | *.vspx 77 | 78 | # CodeLite project files 79 | *.project 80 | *.workspace 81 | .codelite/ 82 | 83 | # Windows Azure Build Output 84 | csx/ 85 | *.build.csdef 86 | 87 | # Windows Store app package directory 88 | AppPackages/ 89 | 90 | # Others 91 | sql/ 92 | *.Cache 93 | ClientBin/ 94 | [Ss]tyle[Cc]op.* 95 | ~$* 96 | *~ 97 | *.dbmdl 98 | *.dbproj.schemaview 99 | *.pfx 100 | *.publishsettings 101 | node_modules/ 102 | __pycache__/ 103 | 104 | # KDE 105 | .directory 106 | 107 | #Kdevelop project files 108 | *.kdev4 109 | 110 | # xCode 111 | xcuserdata 112 | 113 | # RIA/Silverlight projects 114 | Generated_Code/ 115 | 116 | # Backup & report files from converting an old project file to a newer 117 | # Visual Studio version. Backup files are not needed, because we have git ;-) 118 | _UpgradeReport_Files/ 119 | Backup*/ 120 | UpgradeLog*.XML 121 | UpgradeLog*.htm 122 | 123 | # SQL Server files 124 | App_Data/*.mdf 125 | App_Data/*.ldf 126 | 127 | # Business Intelligence projects 128 | *.rdl.data 129 | *.bim.layout 130 | *.bim_*.settings 131 | 132 | # Microsoft Fakes 133 | FakesAssemblies/ 134 | 135 | # ========================= 136 | # Windows detritus 137 | # ========================= 138 | 139 | # Windows image file caches 140 | Thumbs.db 141 | ehthumbs.db 142 | 143 | # Folder config file 144 | Desktop.ini 145 | 146 | # Recycle Bin used on file shares 147 | $RECYCLE.BIN/ 148 | logo.h 149 | *.autosave 150 | 151 | # https://github.com/github/gitignore/blob/master/Global/Tags.gitignore 152 | # Ignore tags created by etags, ctags, gtags (GNU global) and cscope 153 | TAGS 154 | !TAGS/ 155 | tags 156 | *.tags 157 | !tags/ 158 | gtags.files 159 | GTAGS 160 | GRTAGS 161 | GPATH 162 | cscope.files 163 | cscope.out 164 | cscope.in.out 165 | cscope.po.out 166 | godot.creator.* 167 | 168 | # Visual Studio 2017 and Visual Studio Code workspace folder 169 | /.vs 170 | /.vscode 171 | 172 | # Visual Studio Code workspace file 173 | *.code-workspace 174 | 175 | # Scons progress indicator 176 | .scons_node_count 177 | 178 | # ccls cache (https://github.com/MaskRay/ccls) 179 | .ccls-cache/ 180 | 181 | # compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html) 182 | compile_commands.json 183 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Michael Bickel 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!IMPORTANT] 2 | > This project is no longer maintained! 3 | > This was an interesting experiment and journey which was in the end not able to live up to the vision I had in mind. 4 | > In the end it was hard to justify the time and complexity required in relation to the factual outcome of a semi-working solution. 5 | > Thanks! 6 | 7 | --- 8 | ![logo.png](https://hxgodot.github.io/logo2.png) 9 | 10 | # HxGodot - A Haxe GDExtension for Godot 4 11 | 12 | HxGodot combines Haxe's hxcpp target with Godot 4's GDExtension mechanism to supercharge the way you build games with Godot. Nodes are written in Haxe, bundled as a GDExtension and behave like any other Node in your scenes(attach scripts, signals, etc). 13 | 14 | > **Warning** There might be crashes, pieces of the API not working or straight up missing. That being said, we appreciate you testing HxGodot in smaller projects. Feel free to get in touch in should you face issues or bugs. 15 | 16 | 17 | ## Getting started 18 | ### Prerequisites & Toolchain: 19 | 20 | HxGodot builds as a GdExtension DLL and therefore required the same build environment as Godot itself. Please refer to the official [Godot Documentation here](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html#building-for-target-platforms) 21 | 22 | In summary: 23 | - A Commandline shell of your choice. We assume a \*nix-based shell for all commands presented here. 24 | - A C++ compiler, python and scons for your [target platform](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html#building-for-target-platforms) 25 | - [Haxe 4.3.1+](https://haxe.org/download/) Install Haxe and setup Haxe's package manager via `haxelib setup` 26 | - hxcpp 4.3.1+ Install hxcpp by running `haxelib install hxcpp` 27 | - [CompileTime library](https://lib.haxe.org/p/compiletime) Install it by running `haxelib install compiletime` 28 | - Godot 4.2.1+ 29 | 30 | ### First time setup 31 | 32 | When you are first starting out HxGodot is able to generate a simple example project for you. Let's go into a shell and do that: 33 | 34 | 1. Install hxgodot via `haxelib`: 35 | ```bash 36 | haxelib git hxgodot https://github.com/HxGodot/hxgodot.git 37 | ``` 38 | 39 | 2. Create yourself a folder somewhere for the sample project we are about to generate and enter it: 40 | ```bash 41 | mkdir && cd 42 | ``` 43 | 44 | 3. Now run the included cli-tool and and follow the instructions: 45 | ```bash 46 | haxelib run hxgodot init 47 | ``` 48 | 49 | ![image](https://github.com/HxGodot/hxgodot/assets/5015415/463fdc92-836e-47b3-892c-cde177c44bb1) 50 | 51 | Let's take a closer look at the folder's content, that we just generated for you: 52 | ![image](https://github.com/HxGodot/hxgodot/assets/5015415/f8d5c3d6-60a5-45f1-ba33-6e667daff39e) 53 | 54 | - `bin`: Will contain the compiled gdextension binaries later 55 | - `bindings`: Will contain the generated Haxe bindings for Godot4's classes. Also holds a `log.txt` which contains reports about things that were ignored or could not be handled. Useful if you miss a function in Godot's API, here you will usually find the reason why. 56 | - `build.hxml`: this contains the build-instructions for Haxe when building the extension. Here you can add extra compiler defines for debugging or specify which Haxe code modules you want to include in your extension or which third party Haxe libraries to include. See the included comments. 57 | - `example.gdextension`: This is the extension-file Godot4 will use to load the correct binaries for your CPU architecture. 58 | - `project.godot`: Main Godot Project File. This file is the entry-point for Godot and includes a section to include loading our `example.gdextension` file 59 | - `SConstruct`: This is the SCONS build file. This what runs the build pipeline and assembles the binary of your choice. 60 | - `src`: This folder contains the sample's Haxe code. It holds basic examples of a few Godot nodes written in Haxe and runs a few tests & interactions. 61 | >If you add more folders with Haxe-code to `src`, make sure you take a look at `build.hxml`. You need to let HxGodot know about which subfolders in `src` to include. 62 | 63 | 64 | 4. Build the extension according to your platform's flavor: 65 | ```bash 66 | scons platform= target= arch= 67 | ``` 68 | 69 | Examples: 70 | - for Apple Silicon: `scons platform=macos arch=arm64` 71 | 72 | 5. Open the sample-project in Godot4. Please be aware, that you might need to restart the editor after the first start for everything to setup correctly: 73 | 74 | ![image](https://github.com/HxGodot/hxgodot/assets/5015415/91dc4eee-2045-4984-b43a-ed828b045843) 75 | Here you will find the scenetree with the custom Haxe nodes that are contained in the extension. 76 | 77 | 6. You can now study the included Haxe code and play around with it. Just repeat Step 4 and restart Godot. 78 | Feel free to modify this project or use it as a base for a more complex project. 79 | 80 | 81 | Speaking of a more complex project, you can also checkout our full sample game here: https://github.com/HxGodot/squash-the-creeps-3d-hxgodot 82 | 83 | ## Updating the HxGodot in an existing project 84 | 85 | In cases where hxgodot was updated you dont need to recreate your existing project. In such cases you can follow the following steps: 86 | 87 | 1. Update hxgodot via git 88 | ```bash 89 | haxelib git hxgodot https://github.com/HxGodot/hxgodot.git 90 | ``` 91 | 92 | 2. Update your projects `SConstruct` file. This can be necessary when there have been changes/updates in the build pipeline 93 | ```bash 94 | haxelib run hxgodot copy_buildfiles 95 | ``` 96 | 97 | 3. Generate a new set of bindings (usually updates come with improvements) 98 | ```bash 99 | haxelib run hxgodot generate_bindings 100 | ``` 101 | 102 | 4. Rebuild your project's extension 103 | ```bash 104 | scons platform= target= 105 | ``` 106 | 107 | ## About Godot versions and binding generation 108 | 109 | HxGodot ships with an `extension_api.json` file that was generated by an official Godot 4.2.1 build. In cases where you build the engine yourself or wanna HxGodot try a different version, you want to generate custom HxGodot bindings. You can do that by running: 110 | 111 | ```shell 112 | --dump-extension-api-with-docs 113 | ``` 114 | 115 | This will generate your `extension_api.json` in the folder you ran the command in. In your project you now need to regenerate the bindings: 116 | 117 | ```shell 118 | haxelib run hxgodot generate_bindings --extension-api-json= 119 | ``` 120 | 121 | Now you can build HxGodot and test your project. 122 | 123 | ## Common pitfalls 124 | ### Assigning properties 125 | You may attempt to update certain member properties in the following way and notice that the position wont get applied to the node. 126 | 127 | ```haxe 128 | class HxCoolNode extends Node2D { 129 | override function _ready() { 130 | this.position.x = 100.0; // this wont apply the value to the position 131 | } 132 | } 133 | ``` 134 | 135 | This is actually normal. The `position` Vector2 is accessed and copied from Godot and you can do calculations with it. But in order to apply it you need to assign the property again or use the setter function like this: 136 | 137 | ```haxe 138 | class HxCoolNode extends Node2D { 139 | override function _ready() { 140 | var pos = this.position; 141 | pos.x = 100.0; 142 | this.position = pos; 143 | // or 144 | this.set_position(pos); // that would also work 145 | // or 146 | this.position = new Vector2(100.0, this.position.y); // while not optimal, this also works 147 | // or 148 | this.position = [100.0, this.position.y]; // while not optimal, this also works since Vector2 is an array under the hood 149 | } 150 | } 151 | ``` 152 | 153 | ### Dangerous GDArrays 154 | Dont work with GDArrays naively! They contain [Variants](https://hxgodot.github.io/docs/godot/variant/Variant.html) and by default they can convert into types prematurely and cause a crash. 155 | 156 | ```haxe 157 | // triangles_gd holds an array of Int64 158 | var triangles_gd:GDArray = surface_data[cast MeshArrayType.ARRAY_INDEX]; 159 | var index:Int = triangles_gd[tidx]; // UNDEFINED BEHAVIOR, DONT DO THIS! The Variant returned from the GDArray sees the `Int` and casts itself to `Int` too early, writing its `Int64` into a the pointer of an `Int`, effectively causing a stack-corruption!!! 160 | 161 | // Instead explicitly force the Variant to cast into the original type first and cast into the wanted type secondly 162 | var index:Int = ((triangles_gd[tidx]:cpp.Int64):Int); // Good! Unpack Int64 and cast to Int 163 | ``` 164 | 165 | ## Debugging 166 | - Windows: Startup your VisualStudio and setup it up to debug launch your compile Godot 4.x executable with the test-project defined on the cmdline. 167 | 168 | You should be able to step through the code on both sides(godot & hxgodot) and see what's going on. 169 | 170 | 171 | ## Good to know 172 | - Godot exposes around 850 classes in the extension API. Haxe's compiler will automatically only compile classes that your code actually imports / uses into the extension. 173 | 174 | -------------------------------------------------------------------------------- /build-bindings.hxml: -------------------------------------------------------------------------------- 1 | --macro godot.macros.ClassGenMacros.api() 2 | -cp src 3 | #-D HXCPP_M64 -------------------------------------------------------------------------------- /cli.hxml: -------------------------------------------------------------------------------- 1 | -neko ./run.n 2 | --class-path tools/run/ 3 | -main RunMain 4 | -D neko_v1 5 | -------------------------------------------------------------------------------- /extraParams.hxml: -------------------------------------------------------------------------------- 1 | --macro include('godot.variant', true) 2 | -cp src 3 | -dce std -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hxgodot", 3 | "url" : "https://github.com/dazKind/hxgodot-cpp", 4 | "license": "MIT", 5 | "tags": ["godot", "cpp"], 6 | "description": "", 7 | "version": "1.0.0-beta", 8 | "classPath": "src/", 9 | "releasenote": "Initial Alpha release. Use with caution", 10 | "contributors": ["dazKind"], 11 | "dependencies": { 12 | "compiletime": "", 13 | "hxcpp": "" 14 | } 15 | } -------------------------------------------------------------------------------- /run.n: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HxGodot/hxgodot/0b5ca05e0189725724b0c9b03d748d5c2424a079/run.n -------------------------------------------------------------------------------- /src/HxGodot.hx: -------------------------------------------------------------------------------- 1 | import cpp.link.StaticRegexp; 2 | import cpp.link.StaticStd; 3 | import cpp.link.StaticZlib; 4 | 5 | import godot.Types; 6 | import godot.variant.Variant; 7 | import haxe.rtti.Meta; 8 | 9 | 10 | @:buildXml(" 11 | 12 | 13 | 14 | 15 | 16 | 17 | ") 18 | @:headerCode(" 19 | void hxgodot_set_finalizer(Dynamic obj, void*inFunction, bool builtin); 20 | void hxgodot_clear_finalizer(Dynamic obj);") 21 | class HxGodot { 22 | @:noCompletion 23 | private static var builtins:List> = null; 24 | @:noCompletion 25 | private static var core:Array = []; 26 | @:noCompletion 27 | private static var servers:Array = []; 28 | @:noCompletion 29 | private static var scene:Array = []; 30 | @:noCompletion 31 | private static var editor:Array = []; 32 | 33 | // utilities 34 | static var gcCycle = 0.0; 35 | public static function runGc(_dt:Float) { 36 | var ran = false; 37 | if (gcCycle > 2.0) { 38 | trace("running GC"); 39 | cpp.NativeGc.run(true); 40 | gcCycle = 0; 41 | ran = true; 42 | } 43 | gcCycle += _dt; 44 | return ran; 45 | } 46 | 47 | @:native("::hxgodot_set_finalizer") 48 | extern static function __setFinalizer(inObject:T, inFinalizer:cpp.CallableVoid>, builtin:Bool):Void; 49 | 50 | inline public static function setFinalizer(inObject:T, inFinalizer:cpp.CallableVoid>):Void 51 | __setFinalizer(inObject, inFinalizer, false); 52 | 53 | inline public static function setBuiltinFinalizer(inObject:T, inFinalizer:cpp.CallableVoid>):Void 54 | __setFinalizer(inObject, inFinalizer, true); 55 | 56 | 57 | @:native("::hxgodot_clear_finalizer") 58 | extern static public function clearFinalizer(inObject:T):Void; 59 | 60 | public static function getExceptionStackString(_e:Dynamic) { 61 | var msg = [_e.value]; 62 | for (s in cast(_e.__nativeStack, Array)) { 63 | var tokens = s.split("::"); 64 | var cls = tokens[0]; 65 | var func = tokens[1]; 66 | var file = tokens[2]; 67 | var line = tokens[3]; 68 | msg.push('Called from $cls.$func ($file:$line)'); 69 | } 70 | return msg.join("\n"); 71 | } 72 | 73 | // main entry point 74 | @:noCompletion 75 | static function main() { 76 | // use https://github.com/jasononeil/compiletime to embed all found extensionclasses and use rtti to register them 77 | // TODO: the compile-time lib should prolly be replaced with something lightweight in the long run 78 | 79 | // sort all classes depending on their inheritance depth, this way everything registers in order 80 | var tmp = Lambda.array(CompileTime.getAllClasses(godot.Wrapped)); 81 | haxe.ds.ArraySort.sort(tmp, _sort); 82 | 83 | // bucket all classes according to their api level 84 | for (t in tmp) { 85 | var meta = Meta.getType(t); 86 | switch (meta.gdApiType[0]) { 87 | case GDApiType.CORE: core.push(t); 88 | case GDApiType.SERVERS: servers.push(t); 89 | case GDApiType.SCENE: scene.push(t); 90 | case GDApiType.EDITOR: editor.push(t); 91 | } 92 | } 93 | } 94 | 95 | @:noCompletion 96 | public static function init_level(_level:cpp.Int32) { 97 | switch (_level) { 98 | // case GDApiType.CORE: {} 99 | // case GDApiType.SERVERS: {} 100 | case GDApiType.SCENE:{ // this loads all the classes on scene level, must correspondent to set_minimum_library_initialization_level(..) 101 | // setup constructors 102 | __Variant.__initBindings(); 103 | 104 | builtins = CompileTime.getAllClasses(godot.variant.IBuiltIn); 105 | for (t in builtins) { 106 | if (Reflect.hasField(t, "__init_builtin_constructors")) // built-in class constructors and shit 107 | Reflect.callMethod(t, Reflect.field(t, "__init_builtin_constructors"), []); 108 | } 109 | for (t in builtins) { 110 | if (Reflect.hasField(t, "__init_builtin_bindings")) // built-in class bindings 111 | Reflect.callMethod(t, Reflect.field(t, "__init_builtin_bindings"), []); 112 | } 113 | 114 | // now override the trace function for error handling and GDUtils prints 115 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { 116 | if (infos.customParams != null) { 117 | // TODO: Sucks, but lets do this for now 118 | var stack = haxe.CallStack.toString(haxe.CallStack.callStack()); 119 | var lines = stack.split("\n"); 120 | lines.reverse(); 121 | lines.pop(); 122 | lines.unshift(Std.string(v)); 123 | GodotNativeInterface.print_error(lines.join('\n'), infos.className+":"+infos.methodName, infos.fileName, infos.lineNumber, true); 124 | } else { 125 | //GodotNativeInterface.print_warning(Std.string(v), infos.className+":"+infos.methodName, infos.fileName, infos.lineNumber); 126 | var msg = infos.fileName+":"+infos.lineNumber+": "+ Std.string(v); 127 | GDUtils.print((msg:godot.variant.GDString)); 128 | } 129 | } 130 | 131 | // init core classes 132 | _printBanner(); 133 | _init(core); 134 | _init(servers); 135 | _init(scene); 136 | } 137 | case GDApiType.EDITOR: { 138 | _init(editor); 139 | 140 | // // #if scriptable 141 | // //cpp.cppia.Host.runFile("bin/hxgodot.cppia"); 142 | // // #end 143 | } 144 | } 145 | } 146 | 147 | @:noCompletion 148 | public static function shutdown_level(_level:cpp.Int32) { 149 | // Note: sort all classes depending on their inheritance depth, this way everything unregisters in order 150 | switch (_level) { 151 | case GDApiType.EDITOR: { 152 | haxe.ds.ArraySort.sort(editor, _reverse_sort); 153 | _deinit(editor); 154 | } 155 | case GDApiType.SCENE: { 156 | haxe.ds.ArraySort.sort(scene, _reverse_sort); 157 | _deinit(scene); 158 | 159 | haxe.ds.ArraySort.sort(servers, _reverse_sort); 160 | _deinit(servers); 161 | 162 | haxe.ds.ArraySort.sort(core, _reverse_sort); 163 | _deinit(core); 164 | builtins = null; 165 | } 166 | // case GDApiType.SERVERS: {} 167 | // case GDApiType.CORE: {} 168 | } 169 | } 170 | 171 | @:noCompletion 172 | inline private static function _printBanner() { // // print a fancy banner message 173 | var initCount = core.length + servers.length + scene.length; 174 | var bannerMsg = new StringBuf(); 175 | bannerMsg.add('\n[b][color=FFA500]Hx[/color][color=6495ED]Godot[/color] (${GDUtils.HXGODOT_VERSION})[/b]\n'); 176 | bannerMsg.add('[builtins: [color=6495ED]${builtins.length}[/color] / core,servers,scene: [color=6495ED]${initCount}[/color] / editor: [color=6495ED]${editor.length}[/color]]\n'); 177 | #if scriptable 178 | bannerMsg.add('(CPPIA host-mode enabled)\n'); 179 | #end 180 | GDUtils.print_rich(bannerMsg.toString()); 181 | } 182 | 183 | @:noCompletion 184 | inline private static function _init(_tmp:Array) { 185 | for (t in _tmp) { 186 | if (Reflect.hasField(t, "__init_engine_bindings")) // engine class bindings 187 | Reflect.callMethod(t, Reflect.field(t, "__init_engine_bindings"), []); 188 | 189 | if (Reflect.hasField(t, "__init_constant_bindings")) // class constants bindings 190 | Reflect.callMethod(t, Reflect.field(t, "__init_constant_bindings"), []); 191 | 192 | if (Reflect.hasField(t, "__registerClass")) // extension class bindings 193 | Reflect.callMethod(t, Reflect.field(t, "__registerClass"), []); 194 | 195 | if (Reflect.hasField(t, "__static_init")) // extension static initialization 196 | Reflect.callMethod(t, Reflect.field(t, "__static_init"), []); 197 | 198 | if (Reflect.hasField(t, "__registerSingleton")) // extension singleton initialization 199 | Reflect.callMethod(t, Reflect.field(t, "__registerSingleton"), []); 200 | } 201 | } 202 | 203 | @:noCompletion 204 | inline private static function _deinit(_tmp:Array) { 205 | // now null / release all the godot stuff we have in our classes 206 | for (t in _tmp) { 207 | if (Reflect.hasField(t, "__unregisterSingleton")) // extension singleton initialization 208 | Reflect.callMethod(t, Reflect.field(t, "__unregisterSingleton"), []); 209 | 210 | if (Reflect.hasField(t, "__static_deinit")) 211 | Reflect.callMethod(t, Reflect.field(t, "__static_deinit"), []); 212 | 213 | if (Reflect.hasField(t, "__registerClass")) { 214 | var cname:godot.variant.StringName = Reflect.field(t, "__class_name"); 215 | godot.Types.GodotNativeInterface.classdb_unregister_extension_class( 216 | untyped __cpp__("godot::internal::library"), 217 | cname.native_ptr() 218 | ); 219 | } 220 | 221 | if (Reflect.hasField(t, "__deinit_constant_bindings")) 222 | Reflect.callMethod(t, Reflect.field(t, "__deinit_constant_bindings"), []); 223 | } 224 | } 225 | 226 | @:noCompletion 227 | private static function _sort(_a:Dynamic, _b:Dynamic) { 228 | var a:Int = Reflect.field(_a, "__inheritance_depth"); 229 | var b:Int = Reflect.field(_b, "__inheritance_depth"); 230 | if (a > b) return 1; 231 | else if (a < b) return -1; 232 | return 0; 233 | } 234 | 235 | @:noCompletion 236 | private static function _reverse_sort(_a:Dynamic, _b:Dynamic) { 237 | var a:Int = Reflect.field(_a, "__inheritance_depth"); 238 | var b:Int = Reflect.field(_b, "__inheritance_depth"); 239 | if (a < b) return 1; 240 | else if (a > b) return -1; 241 | return 0; 242 | } 243 | } -------------------------------------------------------------------------------- /src/godot/Wrapped.hx: -------------------------------------------------------------------------------- 1 | package godot; 2 | 3 | import godot.Types; 4 | 5 | #if !macro 6 | @:autoBuild(godot.macros.Macros.build()) 7 | #end 8 | @:headerCode('#include ') 9 | class Wrapped { 10 | @:noCompletion 11 | public static var classTags = new Map>(); 12 | 13 | public function new() { 14 | this.__postInit(); 15 | } 16 | 17 | @:noCompletion 18 | var __root:VoidPtr = null; 19 | @:noCompletion 20 | var __owner:VoidPtr = null; // pointer to the godot-side parent class we need to keep around 21 | @:noCompletion 22 | var __ownerParent:Wrapped = null; 23 | @:noCompletion 24 | var __isDying:Bool = false; 25 | 26 | public var specialRelease = false; 27 | public var proxy = false; 28 | 29 | inline public function isValid():Bool 30 | return !__isDying; 31 | 32 | @:noCompletion 33 | public function native_ptr():GDExtensionObjectPtr { 34 | var res = __ownerParent != null ? __ownerParent.native_ptr() : __owner; 35 | return res; 36 | } 37 | 38 | @:noCompletion 39 | inline public function setOwner(_owner:VoidPtr) 40 | __owner = _owner; 41 | 42 | @:noCompletion 43 | inline public function setOwnerParent(_owner:Wrapped) 44 | __ownerParent = _owner; 45 | 46 | @:noCompletion 47 | inline public function setOwnerAndRoot(_owner:VoidPtr) { 48 | __owner = _owner; 49 | createRoot(); 50 | } 51 | 52 | @:noCompletion 53 | inline public function setOwnerParentAndRoot(_owner:Wrapped) { 54 | __ownerParent = _owner; 55 | createRoot(); 56 | } 57 | 58 | @:noCompletion 59 | inline public function hasOwnerParent() 60 | return __ownerParent != null; 61 | 62 | @:noCompletion 63 | public function createRoot() { 64 | if (__root == null) 65 | __root = untyped __cpp__('(void*)new cpp::utils::RootedObject({0}.mPtr)', this); 66 | } 67 | 68 | @:noCompletion 69 | public function deleteRoot() { 70 | if (__root != null) { 71 | untyped __cpp__('delete ((cpp::utils::RootedObject*){0})', __root.ptr); 72 | __root = null; 73 | } 74 | } 75 | 76 | @:noCompletion 77 | public function strongRef() { 78 | if (__root != null) 79 | untyped __cpp__('((cpp::utils::RootedObject*){0})->makeStrong()', __root.ptr); 80 | } 81 | 82 | @:noCompletion 83 | public function weakRef() { 84 | if (__root != null) 85 | untyped __cpp__('((cpp::utils::RootedObject*){0})->makeWeak()', __root.ptr); 86 | } 87 | 88 | @:noCompletion 89 | public function isWeak():Bool { 90 | return untyped __cpp__('((cpp::utils::RootedObject*){0})->isWeak()', __root.ptr); 91 | } 92 | 93 | public function as(_cls:Class, ?_report:Bool = true):T { 94 | var ret:T = null; 95 | 96 | var name:godot.variant.StringName = Reflect.field(_cls, "__class_name"); 97 | 98 | if (name.hash() == this.getClassName().hash()) // early out if the classnames match! 99 | return cast this; 100 | 101 | var tag = Reflect.field(_cls, "__class_tag"); 102 | var obj = GodotNativeInterface.object_cast_to(this.native_ptr(), tag); 103 | 104 | if (obj != null) { 105 | ret = cast Type.createEmptyInstance(classTags.get(name)); 106 | ret.setOwnerParentAndRoot(this); 107 | ret.proxy = true; 108 | ret.__validateInstance(false); 109 | } else if (_report) 110 | trace('CANNOT CONVERT ${this} TO $name', true); 111 | 112 | return ret; 113 | } 114 | 115 | @:noCompletion 116 | public function __validateInstance(_incRef:Bool) {} // override 117 | 118 | @:noCompletion 119 | public function __acceptReturn(_decRef:Bool) {} // override 120 | 121 | @:noCompletion 122 | function __postInit() {} // override 123 | 124 | function getClassName():godot.variant.StringName { return null; } // override 125 | } -------------------------------------------------------------------------------- /src/godot/core/GDConstants.hx: -------------------------------------------------------------------------------- 1 | package godot.core; 2 | 3 | import godot.Types; 4 | import godot.variant.Color; 5 | 6 | typedef NamedColor = { 7 | var name:String; 8 | var color:Color; 9 | }; 10 | 11 | class GDConstants { 12 | inline public static var CMP_EPSILON = 0.00001; 13 | inline public static var CMP_EPSILON2 = (CMP_EPSILON * CMP_EPSILON); 14 | 15 | inline public static var CMP_NORMALIZE_TOLERANCE = 0.000001; 16 | inline public static var CMP_POINT_IN_PLANE_EPSILON = 0.00001; 17 | 18 | inline public static var Math_SQRT12 = 0.7071067811865475244008443621048490; 19 | inline public static var Math_SQRT2 = 1.4142135623730950488016887242; 20 | inline public static var Math_LN2 = 0.6931471805599453094172321215; 21 | inline public static var Math_TAU = 6.2831853071795864769252867666; 22 | inline public static var Math_PI = 3.1415926535897932384626433833; 23 | inline public static var Math_E = 2.7182818284590452353602874714; 24 | 25 | inline public static var UNIT_EPSILON = 0.001; 26 | 27 | inline public static var SIDE_LEFT = 0; 28 | inline public static var SIDE_TOP = 1; 29 | inline public static var SIDE_RIGHT = 2; 30 | inline public static var SIDE_BOTTOM = 3; 31 | 32 | inline public static var CORNER_TOP_LEFT = 0; 33 | inline public static var CORNER_TOP_RIGHT = 1; 34 | inline public static var CORNER_BOTTOM_RIGHT = 2; 35 | inline public static var CORNER_BOTTOM_LEFT = 3; 36 | 37 | inline public static var EULER_ORDER_XYZ = 0; 38 | inline public static var EULER_ORDER_XZY = 1; 39 | inline public static var EULER_ORDER_YXZ = 2; 40 | inline public static var EULER_ORDER_YZX = 3; 41 | inline public static var EULER_ORDER_ZXY = 4; 42 | inline public static var EULER_ORDER_ZYX = 5; 43 | 44 | inline public static var CLOCKWISE = 0; 45 | inline public static var COUNTERCLOCKWISE = 1; 46 | 47 | inline public static function MIN(m_a:GDExtensionFloat, m_b:GDExtensionFloat):GDExtensionFloat { 48 | return m_a < m_b ? m_a : m_b; 49 | } 50 | 51 | inline public static function MAX(m_a:GDExtensionFloat, m_b:GDExtensionFloat):GDExtensionFloat { 52 | return m_a > m_b ? m_a : m_b; 53 | } 54 | 55 | inline public static function SIGN(m_v:GDExtensionFloat):GDExtensionFloat { 56 | return m_v == 0 ? 0.0 : (m_v < 0 ? -1.0 : 1.0); 57 | } 58 | 59 | inline public static function CLAMP(m_a:GDExtensionFloat, m_min:GDExtensionFloat, m_max:GDExtensionFloat):GDExtensionFloat { 60 | return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a); 61 | } 62 | 63 | inline public static function ERR_PRINT(msg:String) { 64 | trace("ERR_FAIL_V_MSG: msg="+msg); 65 | } 66 | 67 | inline public static function ERR_FAIL_V_MSG(typ:Dynamic, msg:String) { 68 | trace("ERR_FAIL_V_MSG: typ="+Type.getClassName(Type.getClass(typ))+" msg="+msg); 69 | } 70 | 71 | inline public static function ERR_FAIL_COND_MSG(cond:Bool, msg:String) { 72 | if (cond) 73 | trace("ERR_FAIL_COND_MSG: msg="+msg); 74 | } 75 | 76 | inline public static function ERR_FAIL_COND_V_MSG(cond:Bool, typ:Dynamic, msg:String) { 77 | if (cond) 78 | trace("ERR_FAIL_COND_V_MSG: typ="+Type.getClassName(Type.getClass(typ))+" msg="+msg); 79 | } 80 | 81 | inline public static function ERR_FAIL_INDEX_V(idx:Int, count:Int, typ:Dynamic) { 82 | if (idx>count) trace("ERR_FAIL_INDEX_V: idx="+idx+" > count="+count+" typ="+Type.getClassName(Type.getClass(typ))); 83 | } 84 | 85 | inline public static function DP(v:Float, decPlaces:Int) { 86 | return Math.round( v * Math.pow(10,decPlaces)) / Math.pow(10,decPlaces); 87 | } 88 | 89 | inline public static function ABS(m_v:Dynamic) { 90 | return m_v < 0 ? -m_v : m_v; 91 | } 92 | 93 | inline public static function signbit(v:Float) { 94 | return v < 0; 95 | } 96 | 97 | public static var named_colors:Array = [ 98 | { name:"ALICE_BLUE", color: Color.ALICE_BLUE }, 99 | { name:"ANTIQUE_WHITE", color: Color.ANTIQUE_WHITE }, 100 | { name:"AQUA", color: Color.AQUA }, 101 | { name:"AQUAMARINE", color: Color.AQUAMARINE }, 102 | { name:"AZURE", color: Color.AZURE }, 103 | { name:"BEIGE", color: Color.BEIGE }, 104 | { name:"BISQUE", color: Color.BISQUE }, 105 | { name:"BLACK", color: Color.BLACK }, 106 | { name:"BLANCHED_ALMOND", color: Color.BLANCHED_ALMOND }, 107 | { name:"BLUE", color: Color.BLUE }, 108 | { name:"BLUE_VIOLET", color: Color.BLUE_VIOLET }, 109 | { name:"BROWN", color: Color.BROWN }, 110 | { name:"BURLYWOOD", color: Color.BURLYWOOD }, 111 | { name:"CADET_BLUE", color: Color.CADET_BLUE }, 112 | { name:"CHARTREUSE", color: Color.CHARTREUSE }, 113 | { name:"CHOCOLATE", color: Color.CHOCOLATE }, 114 | { name:"CORAL", color: Color.CORAL }, 115 | { name:"CORNFLOWER_BLUE", color: Color.CORNFLOWER_BLUE }, 116 | { name:"CORNSILK", color: Color.CORNSILK }, 117 | { name:"CRIMSON", color: Color.CRIMSON }, 118 | { name:"CYAN", color: Color.CYAN }, 119 | { name:"DARK_BLUE", color: Color.DARK_BLUE }, 120 | { name:"DARK_CYAN", color: Color.DARK_CYAN }, 121 | { name:"DARK_GOLDENROD", color: Color.DARK_GOLDENROD }, 122 | { name:"DARK_GRAY", color: Color.DARK_GRAY }, 123 | { name:"DARK_GREEN", color: Color.DARK_GREEN }, 124 | { name:"DARK_KHAKI", color: Color.DARK_KHAKI }, 125 | { name:"DARK_MAGENTA", color: Color.DARK_MAGENTA }, 126 | { name:"DARK_OLIVE_GREEN", color: Color.DARK_OLIVE_GREEN }, 127 | { name:"DARK_ORANGE", color: Color.DARK_ORANGE }, 128 | { name:"DARK_ORCHID", color: Color.DARK_ORCHID }, 129 | { name:"DARK_RED", color: Color.DARK_RED }, 130 | { name:"DARK_SALMON", color: Color.DARK_SALMON }, 131 | { name:"DARK_SEA_GREEN", color: Color.DARK_SEA_GREEN }, 132 | { name:"DARK_SLATE_BLUE", color: Color.DARK_SLATE_BLUE }, 133 | { name:"DARK_SLATE_GRAY", color: Color.DARK_SLATE_GRAY }, 134 | { name:"DARK_TURQUOISE", color: Color.DARK_TURQUOISE }, 135 | { name:"DARK_VIOLET", color: Color.DARK_VIOLET }, 136 | { name:"DEEP_PINK", color: Color.DEEP_PINK }, 137 | { name:"DEEP_SKY_BLUE", color: Color.DEEP_SKY_BLUE }, 138 | { name:"DIM_GRAY", color: Color.DIM_GRAY }, 139 | { name:"DODGER_BLUE", color: Color.DODGER_BLUE }, 140 | { name:"FIREBRICK", color: Color.FIREBRICK }, 141 | { name:"FLORAL_WHITE", color: Color.FLORAL_WHITE }, 142 | { name:"FOREST_GREEN", color: Color.FOREST_GREEN }, 143 | { name:"FUCHSIA", color: Color.FUCHSIA }, 144 | { name:"GAINSBORO", color: Color.GAINSBORO }, 145 | { name:"GHOST_WHITE", color: Color.GHOST_WHITE }, 146 | { name:"GOLD", color: Color.GOLD }, 147 | { name:"GOLDENROD", color: Color.GOLDENROD }, 148 | { name:"GRAY", color: Color.GRAY }, 149 | { name:"GREEN", color: Color.GREEN }, 150 | { name:"GREEN_YELLOW", color: Color.GREEN_YELLOW }, 151 | { name:"HONEYDEW", color: Color.HONEYDEW }, 152 | { name:"HOT_PINK", color: Color.HOT_PINK }, 153 | { name:"INDIAN_RED", color: Color.INDIAN_RED }, 154 | { name:"INDIGO", color: Color.INDIGO }, 155 | { name:"IVORY", color: Color.IVORY }, 156 | { name:"KHAKI", color: Color.KHAKI }, 157 | { name:"LAVENDER", color: Color.LAVENDER }, 158 | { name:"LAVENDER_BLUSH", color: Color.LAVENDER_BLUSH }, 159 | { name:"LAWN_GREEN", color: Color.LAWN_GREEN }, 160 | { name:"LEMON_CHIFFON", color: Color.LEMON_CHIFFON }, 161 | { name:"LIGHT_BLUE", color: Color.LIGHT_BLUE }, 162 | { name:"LIGHT_CORAL", color: Color.LIGHT_CORAL }, 163 | { name:"LIGHT_CYAN", color: Color.LIGHT_CYAN }, 164 | { name:"LIGHT_GOLDENROD", color: Color.LIGHT_GOLDENROD }, 165 | { name:"LIGHT_GRAY", color: Color.LIGHT_GRAY }, 166 | { name:"LIGHT_GREEN", color: Color.LIGHT_GREEN }, 167 | { name:"LIGHT_PINK", color: Color.LIGHT_PINK }, 168 | { name:"LIGHT_SALMON", color: Color.LIGHT_SALMON }, 169 | { name:"LIGHT_SEA_GREEN", color: Color.LIGHT_SEA_GREEN }, 170 | { name:"LIGHT_SKY_BLUE", color: Color.LIGHT_SKY_BLUE }, 171 | { name:"LIGHT_SLATE_GRAY", color: Color.LIGHT_SLATE_GRAY }, 172 | { name:"LIGHT_STEEL_BLUE", color: Color.LIGHT_STEEL_BLUE }, 173 | { name:"LIGHT_YELLOW", color: Color.LIGHT_YELLOW }, 174 | { name:"LIME", color: Color.LIME }, 175 | { name:"LIME_GREEN", color: Color.LIME_GREEN }, 176 | { name:"LINEN", color: Color.LINEN }, 177 | { name:"MAGENTA", color: Color.MAGENTA }, 178 | { name:"MAROON", color: Color.MAROON }, 179 | { name:"MEDIUM_AQUAMARINE", color: Color.MEDIUM_AQUAMARINE }, 180 | { name:"MEDIUM_BLUE", color: Color.MEDIUM_BLUE }, 181 | { name:"MEDIUM_ORCHID", color: Color.MEDIUM_ORCHID }, 182 | { name:"MEDIUM_PURPLE", color: Color.MEDIUM_PURPLE }, 183 | { name:"MEDIUM_SEA_GREEN", color: Color.MEDIUM_SEA_GREEN }, 184 | { name:"MEDIUM_SLATE_BLUE", color: Color.MEDIUM_SLATE_BLUE }, 185 | { name:"MEDIUM_SPRING_GREEN", color: Color.MEDIUM_SPRING_GREEN }, 186 | { name:"MEDIUM_TURQUOISE", color: Color.MEDIUM_TURQUOISE }, 187 | { name:"MEDIUM_VIOLET_RED", color: Color.MEDIUM_VIOLET_RED }, 188 | { name:"MIDNIGHT_BLUE", color: Color.MIDNIGHT_BLUE }, 189 | { name:"MINT_CREAM", color: Color.MINT_CREAM }, 190 | { name:"MISTY_ROSE", color: Color.MISTY_ROSE }, 191 | { name:"MOCCASIN", color: Color.MOCCASIN }, 192 | { name:"NAVAJO_WHITE", color: Color.NAVAJO_WHITE }, 193 | { name:"NAVY_BLUE", color: Color.NAVY_BLUE }, 194 | { name:"OLD_LACE", color: Color.OLD_LACE }, 195 | { name:"OLIVE", color: Color.OLIVE }, 196 | { name:"OLIVE_DRAB", color: Color.OLIVE_DRAB }, 197 | { name:"ORANGE", color: Color.ORANGE }, 198 | { name:"ORANGE_RED", color: Color.ORANGE_RED }, 199 | { name:"ORCHID", color: Color.ORCHID }, 200 | { name:"PALE_GOLDENROD", color: Color.PALE_GOLDENROD }, 201 | { name:"PALE_GREEN", color: Color.PALE_GREEN }, 202 | { name:"PALE_TURQUOISE", color: Color.PALE_TURQUOISE }, 203 | { name:"PALE_VIOLET_RED", color: Color.PALE_VIOLET_RED }, 204 | { name:"PAPAYA_WHIP", color: Color.PAPAYA_WHIP }, 205 | { name:"PEACH_PUFF", color: Color.PEACH_PUFF }, 206 | { name:"PERU", color: Color.PERU }, 207 | { name:"PINK", color: Color.PINK }, 208 | { name:"PLUM", color: Color.PLUM }, 209 | { name:"POWDER_BLUE", color: Color.POWDER_BLUE }, 210 | { name:"PURPLE", color: Color.PURPLE }, 211 | { name:"REBECCA_PURPLE", color: Color.REBECCA_PURPLE }, 212 | { name:"RED", color: Color.RED }, 213 | { name:"ROSY_BROWN", color: Color.ROSY_BROWN }, 214 | { name:"ROYAL_BLUE", color: Color.ROYAL_BLUE }, 215 | { name:"SADDLE_BROWN", color: Color.SADDLE_BROWN }, 216 | { name:"SALMON", color: Color.SALMON }, 217 | { name:"SANDY_BROWN", color: Color.SANDY_BROWN }, 218 | { name:"SEA_GREEN", color: Color.SEA_GREEN }, 219 | { name:"SEASHELL", color: Color.SEASHELL }, 220 | { name:"SIENNA", color: Color.SIENNA }, 221 | { name:"SILVER", color: Color.SILVER }, 222 | { name:"SKY_BLUE", color: Color.SKY_BLUE }, 223 | { name:"SLATE_BLUE", color: Color.SLATE_BLUE }, 224 | { name:"SLATE_GRAY", color: Color.SLATE_GRAY }, 225 | { name:"SNOW", color: Color.SNOW }, 226 | { name:"SPRING_GREEN", color: Color.SPRING_GREEN }, 227 | { name:"STEEL_BLUE", color: Color.STEEL_BLUE }, 228 | { name:"TAN", color: Color.TAN }, 229 | { name:"TEAL", color: Color.TEAL }, 230 | { name:"THISTLE", color: Color.THISTLE }, 231 | { name:"TOMATO", color: Color.TOMATO }, 232 | { name:"TRANSPARENT", color: Color.TRANSPARENT }, 233 | { name:"TURQUOISE", color: Color.TURQUOISE }, 234 | { name:"VIOLET", color: Color.VIOLET }, 235 | { name:"WEB_GRAY", color: Color.WEB_GRAY }, 236 | { name:"WEB_GREEN", color: Color.WEB_GREEN }, 237 | { name:"WEB_MAROON", color: Color.WEB_MAROON }, 238 | { name:"WEB_PURPLE", color: Color.WEB_PURPLE }, 239 | { name:"WHEAT", color: Color.WHEAT }, 240 | { name:"WHITE", color: Color.WHITE }, 241 | { name:"WHITE_SMOKE", color: Color.WHITE_SMOKE }, 242 | { name:"YELLOW", color: Color.YELLOW }, 243 | { name:"YELLOW_GREEN", color: Color.YELLOW_GREEN } 244 | ]; 245 | 246 | } 247 | -------------------------------------------------------------------------------- /src/godot/core/GDMath.hx: -------------------------------------------------------------------------------- 1 | package godot.core; 2 | 3 | import godot.Types; 4 | 5 | class GDMath { 6 | inline public static function fmod(a:GDExtensionFloat, b:GDExtensionFloat):GDExtensionFloat { return a % b; } 7 | 8 | // Ported from header 9 | 10 | inline public static function fposmod(p_x:GDExtensionFloat, p_y:GDExtensionFloat):GDExtensionFloat { 11 | var value = fmod(p_x, p_y); 12 | if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { 13 | value += p_y; 14 | } 15 | value += 0.0; 16 | return value; 17 | } 18 | 19 | inline public static function fposmodp(p_x:GDExtensionFloat, p_y:GDExtensionFloat):GDExtensionFloat { 20 | var value = fmod(p_x, p_y); 21 | if (value < 0) { 22 | value += p_y; 23 | } 24 | value += 0.0; 25 | return value; 26 | } 27 | 28 | inline public static function posmod(p_x:Int, p_y:Int):Int { 29 | var value = p_x % p_y; 30 | if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { 31 | value += p_y; 32 | } 33 | return value; 34 | } 35 | 36 | inline public static function deg_to_rad(p_y:GDExtensionFloat):GDExtensionFloat { return p_y * (Math.PI / 180.0); } 37 | 38 | inline public static function rad_to_deg(p_y:GDExtensionFloat):GDExtensionFloat { return p_y * (180.0 / Math.PI); } 39 | 40 | inline public static function lerp(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_weight:GDExtensionFloat):GDExtensionFloat { return p_from + (p_to - p_from) * p_weight; } 41 | 42 | inline public static function cubic_interpolate(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_pre:GDExtensionFloat, p_post:GDExtensionFloat, p_weight:GDExtensionFloat):GDExtensionFloat { 43 | return 0.5 * 44 | ((p_from * 2.0) + 45 | (-p_pre + p_to) * p_weight + 46 | (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + 47 | (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); 48 | } 49 | 50 | inline public static function cubic_interpolate_angle(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_pre:GDExtensionFloat, p_post:GDExtensionFloat, p_weight:GDExtensionFloat):GDExtensionFloat { 51 | var from_rot = fmod(p_from, Math_TAU); 52 | 53 | var pre_diff = fmod(p_pre - from_rot, Math_TAU); 54 | var pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; 55 | 56 | var to_diff = fmod(p_to - from_rot, Math_TAU); 57 | var to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; 58 | 59 | var post_diff = fmod(p_post - to_rot, Math_TAU); 60 | var post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; 61 | 62 | return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); 63 | } 64 | 65 | inline public static function cubic_interpolate_in_time(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_pre:GDExtensionFloat, p_post:GDExtensionFloat, p_weight:GDExtensionFloat, 66 | p_to_t:GDExtensionFloat, p_pre_t:GDExtensionFloat, p_post_t:GDExtensionFloat):GDExtensionFloat { 67 | /* Barry-Goldman method */ 68 | var t = lerp(0.0, p_to_t, p_weight); 69 | var a1 = lerp(p_pre, p_from, p_pre_t == 0 ? 0.0 : (t - p_pre_t) / -p_pre_t); 70 | var a2 = lerp(p_from, p_to, p_to_t == 0 ? 0.5 : t / p_to_t); 71 | var a3 = lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0 : (t - p_to_t) / (p_post_t - p_to_t)); 72 | var b1 = lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0 : (t - p_pre_t) / (p_to_t - p_pre_t)); 73 | var b2 = lerp(a2, a3, p_post_t == 0 ? 1.0 : t / p_post_t); 74 | return lerp(b1, b2, p_to_t == 0 ? 0.5 : t / p_to_t); 75 | } 76 | 77 | inline public static function cubic_interpolate_angle_in_time(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_pre:GDExtensionFloat, p_post:GDExtensionFloat, p_weight:GDExtensionFloat, 78 | p_to_t:GDExtensionFloat, p_pre_t:GDExtensionFloat, p_post_t:GDExtensionFloat):GDExtensionFloat { 79 | var from_rot = fmod(p_from, Math_TAU); 80 | 81 | var pre_diff = fmod(p_pre - from_rot, Math_TAU); 82 | var pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; 83 | 84 | var to_diff = fmod(p_to - from_rot, Math_TAU); 85 | var to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; 86 | 87 | var post_diff = fmod(p_post - to_rot, Math_TAU); 88 | var post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; 89 | 90 | return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); 91 | } 92 | 93 | inline public static function bezier_interpolate(p_start:GDExtensionFloat, p_control_1:GDExtensionFloat, p_control_2:GDExtensionFloat, p_end:GDExtensionFloat, p_t:GDExtensionFloat):GDExtensionFloat { 94 | /* Formula from Wikipedia article on Bezier curves. */ 95 | var omt = (1.0 - p_t); 96 | var omt2 = omt * omt; 97 | var omt3 = omt2 * omt; 98 | var t2 = p_t * p_t; 99 | var t3 = t2 * p_t; 100 | 101 | return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; 102 | } 103 | 104 | inline public static function bezier_derivative(p_start:GDExtensionFloat, p_control_1:GDExtensionFloat, p_control_2:GDExtensionFloat, p_end:GDExtensionFloat, p_t:GDExtensionFloat):GDExtensionFloat { 105 | /* Formula from Wikipedia article on Bezier curves. */ 106 | var omt = (1.0 - p_t); 107 | var omt2 = omt * omt; 108 | var t2 = p_t * p_t; 109 | 110 | var d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; 111 | return d; 112 | } 113 | 114 | inline public static function lerp_angle(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_weight:GDExtensionFloat):GDExtensionFloat { 115 | var difference = fmod(p_to - p_from, Math_TAU); 116 | var distance = fmod(2.0 * difference, Math_TAU) - difference; 117 | return p_from + distance * p_weight; 118 | } 119 | 120 | inline public static function inverse_lerp(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_value:GDExtensionFloat):GDExtensionFloat { 121 | return (p_value - p_from) / (p_to - p_from); 122 | } 123 | 124 | inline public static function remap(p_value:GDExtensionFloat, p_istart:GDExtensionFloat, p_istop:GDExtensionFloat, p_ostart:GDExtensionFloat, p_ostop:GDExtensionFloat):GDExtensionFloat { 125 | return lerp(p_ostart, p_ostop, inverse_lerp(p_istart, p_istop, p_value)); 126 | } 127 | 128 | inline public static function smoothstep(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_s:GDExtensionFloat):GDExtensionFloat { 129 | if (is_equal_approx(p_from, p_to)) { 130 | return p_from; 131 | } 132 | var s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); 133 | return s * s * (3.0 - 2.0 * s); 134 | } 135 | 136 | inline public static function move_toward(p_from:GDExtensionFloat, p_to:GDExtensionFloat, p_delta:GDExtensionFloat):GDExtensionFloat { 137 | return Math.abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; 138 | } 139 | 140 | inline public static function linear_to_db(p_linear:GDExtensionFloat):GDExtensionFloat { 141 | return Math.log(p_linear) * 8.6858896380650365530225783783321; 142 | } 143 | 144 | inline public static function db_to_linear(p_db:GDExtensionFloat):GDExtensionFloat { 145 | return Math.exp(p_db * 0.11512925464970228420089957273422); 146 | } 147 | 148 | inline public static function wrapi(value:Int, min:Int, max:Int):Int { 149 | var range = max - min; 150 | return range == 0 ? min : min + ((((value - min) % range) + range) % range); 151 | } 152 | 153 | inline public static function wrapf(value:GDExtensionFloat, min:GDExtensionFloat, max:GDExtensionFloat):GDExtensionFloat { 154 | var range = max - min; 155 | var result = is_zero_approx(range) ? min : value - (range * Math.floor((value - min) / range)); 156 | if (is_equal_approx(result, max)) { 157 | return min; 158 | } 159 | return result; 160 | } 161 | 162 | inline public static function fract(value:GDExtensionFloat):GDExtensionFloat { 163 | return value - Math.floor(value); 164 | } 165 | 166 | inline public static function pingpong(value:GDExtensionFloat, length:GDExtensionFloat):GDExtensionFloat { 167 | return (length != 0.0) ? Math.abs(fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0; 168 | } 169 | 170 | inline public static function is_equal_approx(a, b, tolerance = 0.0):Bool { 171 | // Check for exact equality first, required to handle "infinity" values. 172 | if (a == b) { 173 | return true; 174 | } 175 | if (tolerance==0.0) { 176 | tolerance = CMP_EPSILON * Math.abs(a); 177 | if (tolerance < CMP_EPSILON) { 178 | tolerance = CMP_EPSILON; 179 | } 180 | } 181 | 182 | // Then check for approximate equality. 183 | return Math.abs(a - b) < tolerance; 184 | } 185 | 186 | inline public static function is_zero_approx(s):Bool { 187 | return Math.abs(s) < CMP_EPSILON; 188 | } 189 | 190 | 191 | inline public static function is_finite(s):Bool { 192 | return s != Math.POSITIVE_INFINITY && s != Math.NEGATIVE_INFINITY; 193 | } 194 | 195 | // Ported from CPP 196 | 197 | inline public static function snapped(p_value:GDExtensionFloat, p_step:GDExtensionFloat):GDExtensionFloat { 198 | if (p_step != 0) { 199 | p_value = Math.floor(p_value / p_step + 0.5) * p_step; 200 | } 201 | return p_value; 202 | } 203 | 204 | 205 | } -------------------------------------------------------------------------------- /src/godot/debug/HxGodotDebugInterface.hx: -------------------------------------------------------------------------------- 1 | package godot.debug; 2 | 3 | import godot.*; 4 | import godot.variant.*; 5 | 6 | class HxGodotDebugInterface extends Node { 7 | var monitors = [ 8 | "Haxe/MEM_INFO_USAGE" => "get_mem_info_usage", 9 | "Haxe/MEM_INFO_RESERVED" => "get_mem_info_reserved", 10 | "Haxe/MEM_INFO_CURRENT" => "get_mem_info_current", 11 | "Haxe/MEM_INFO_LARGE" => "get_mem_info_large", 12 | ]; 13 | 14 | override function _ready() { 15 | for (k in monitors.keys()) { 16 | var v = monitors.get(k); 17 | if (!Performance.singleton().has_custom_monitor(k)) 18 | Performance.singleton().add_custom_monitor( 19 | k, 20 | Callable.fromObjectMethod(this, v), 21 | new GDArray() 22 | ); 23 | } 24 | } 25 | 26 | override function _exit_tree():Void { 27 | for (k in monitors.keys()) { 28 | var v = monitors.get(k); 29 | if (Performance.singleton().has_custom_monitor(k)) 30 | Performance.singleton().remove_custom_monitor(k); 31 | } 32 | } 33 | 34 | @:export 35 | public function get_mem_info_usage():Float 36 | return cpp.vm.Gc.memInfo(cpp.vm.Gc.MEM_INFO_USAGE); 37 | 38 | @:export 39 | public function get_mem_info_reserved():Float 40 | return cpp.vm.Gc.memInfo(cpp.vm.Gc.MEM_INFO_RESERVED); 41 | 42 | @:export 43 | public function get_mem_info_current():Float 44 | return cpp.vm.Gc.memInfo(cpp.vm.Gc.MEM_INFO_CURRENT); 45 | 46 | @:export 47 | public function get_mem_info_large():Float 48 | return cpp.vm.Gc.memInfo(cpp.vm.Gc.MEM_INFO_LARGE); 49 | } -------------------------------------------------------------------------------- /src/godot/macros/ClassGenExtraMacros.hx: -------------------------------------------------------------------------------- 1 | package godot.macros; 2 | 3 | #if macro 4 | 5 | import haxe.macro.Context; 6 | import haxe.macro.Expr; 7 | import haxe.macro.MacroStringTools; 8 | import haxe.macro.TypeTools; 9 | import godot.macros.ArgumentMacros; 10 | 11 | using haxe.macro.ExprTools; 12 | using StringTools; 13 | 14 | class ClassGenExtraMacros { 15 | public static function getHaxeOperators(_type:String) { 16 | var ops = []; 17 | switch (_type) { 18 | case "GDString": { 19 | // TODO: these inlined string calls are a problem! 20 | var tmp = macro class { 21 | @:from inline public static function fromString(_v:String):GDString { 22 | var s = new GDString(); 23 | godot.Types.GodotNativeInterface.string_new_with_utf8_chars(s.native_ptr(), cast cpp.NativeString.c_str(_v)); 24 | return s; 25 | } 26 | 27 | @:to inline public function toString():String { 28 | var size = godot.Types.GodotNativeInterface.string_to_utf8_chars(untyped __cpp__('(GDExtensionStringPtr){0}', this.native_ptr()), null, 0); 29 | var chars:Array = cpp.NativeArray.create(size); 30 | var ptr = cpp.NativeArray.address(chars, 0); 31 | godot.Types.GodotNativeInterface.string_to_utf8_chars(untyped __cpp__('(GDExtensionStringPtr){0}', this.native_ptr()), ptr, size); 32 | return cpp.NativeString.fromPointerLen(ptr, size); 33 | } 34 | } 35 | ops = ops.concat(tmp.fields); 36 | } 37 | case "NodePath": { 38 | var tmp = macro class { 39 | @:from inline public static function fromString(_v:String):NodePath { 40 | return NodePath.fromGDString((_v:GDString)); 41 | } 42 | 43 | @:to inline public function toString():String { 44 | return (GDString.fromNodePath(this):String); 45 | } 46 | } 47 | ops = ops.concat(tmp.fields); 48 | } 49 | case "StringName": { 50 | var tmp = macro class { 51 | @:from inline public static function fromString(_v:String):StringName { 52 | return StringName.fromGDString((_v:GDString)); 53 | } 54 | 55 | @:to inline public function toString():String { 56 | return (GDString.fromStringName(this):String); 57 | } 58 | 59 | @:op(A == B) 60 | inline static public function operator_EQUAL_HXSTRING(_lhs:godot.variant.StringName, _rhs:String):Bool { 61 | return godot.variant.StringName.operator_EQUAL_StringName(_lhs, (_rhs:StringName)); 62 | } 63 | 64 | @:op(A != B) 65 | inline static public function operator_NOT_EQUAL_HXSTRING(_lhs:godot.variant.StringName, _rhs:String):Bool { 66 | return godot.variant.StringName.operator_NOT_EQUAL_StringName(_lhs, (_rhs:StringName)); 67 | } 68 | } 69 | 70 | ops = ops.concat(tmp.fields); 71 | } 72 | case "Callable": { 73 | var tmp = macro class { 74 | @:from inline public static function fromFunc(_v:T):Callable { 75 | //TODO: Figure this out 76 | //return StringName.fromGDString((_v:GDString)); 77 | trace(Type.typeof(_v)); 78 | return null; 79 | } 80 | 81 | @:to inline public function toFunc():Void->Void { 82 | //TODO: Figure this out 83 | //return (GDString.fromStringName(this):String); 84 | return null; 85 | } 86 | } 87 | ops = ops.concat(tmp.fields); 88 | } 89 | case "PackedByteArray": { 90 | var tmp = macro class { 91 | 92 | // Fast access to the unamanged array! 93 | inline public function data():haxe.io.BytesData { 94 | var len = this.size().toInt(); 95 | var ptr = godot.Types.GodotNativeInterface.packed_byte_array_operator_index(this.native_ptr(), 0); 96 | var arr = []; 97 | cpp.NativeArray.setUnmanagedData(arr, ptr, len); 98 | return arr; 99 | } 100 | 101 | @:from inline public static function fromBytes(_v:haxe.io.Bytes):godot.variant.PackedByteArray { 102 | var res = new godot.variant.PackedByteArray(); 103 | res.resize(_v.length); 104 | var ptr = godot.Types.GodotNativeInterface.packed_byte_array_operator_index(res.native_ptr(), 0); 105 | var src = cpp.NativeArray.getBase(_v.getData()).getBase(); 106 | cpp.Native.memcpy(ptr, src, _v.length); 107 | return res; 108 | } 109 | 110 | @:to inline public function toBytes():haxe.io.Bytes { 111 | var len = this.size().toInt(); 112 | var ptr = godot.Types.GodotNativeInterface.packed_byte_array_operator_index(this.native_ptr(), 0); 113 | var bytes = haxe.io.Bytes.alloc(len); 114 | cpp.Native.memcpy(cpp.NativeArray.getBase(bytes.getData()).getBase(), ptr, len); 115 | return bytes; 116 | } 117 | } 118 | ops = ops.concat(tmp.fields); 119 | } 120 | case "PackedFloat32Array": { 121 | var tmp = macro class { 122 | 123 | // Fast access to the unamanged array! 124 | inline public function data():Array { 125 | var len = this.size().toInt(); 126 | var ptr = godot.Types.GodotNativeInterface.packed_float32_array_operator_index(this.native_ptr(), 0); 127 | var arr = []; 128 | cpp.NativeArray.setUnmanagedData(arr, ptr, len); 129 | return arr; 130 | } 131 | 132 | @:from inline public static function fromFloat32Array(_v:haxe.io.Float32Array):godot.variant.PackedFloat32Array { 133 | var res = new godot.variant.PackedFloat32Array(); 134 | res.resize(_v.length); 135 | var ptr = godot.Types.GodotNativeInterface.packed_float32_array_operator_index(res.native_ptr(), 0); 136 | var src = cpp.NativeArray.getBase(_v.view.buffer.getData()).getBase(); 137 | cpp.Native.memcpy(ptr, src, _v.view.byteLength); 138 | return res; 139 | } 140 | 141 | @:to inline public function toFloat32Array():haxe.io.Float32Array { 142 | var bLen = this.size().toInt() * 4; 143 | var tmp = godot.Types.GodotNativeInterface.packed_float32_array_operator_index(this.native_ptr(), 0).ptr; 144 | var ptr:cpp.Star = untyped __cpp__('(uint8_t*){0}', tmp); 145 | var bytes = haxe.io.Bytes.alloc(bLen); 146 | cpp.Native.memcpy(cpp.NativeArray.getBase(bytes.getData()).getBase(), ptr, bLen); 147 | return haxe.io.Float32Array.fromBytes(bytes); 148 | } 149 | } 150 | ops = ops.concat(tmp.fields); 151 | } 152 | case "PackedInt32Array": { 153 | var tmp = macro class { 154 | 155 | // Fast access to the unamanged array! 156 | inline public function data():Array { 157 | var len = this.size().toInt(); 158 | var ptr = godot.Types.GodotNativeInterface.packed_int32_array_operator_index(this.native_ptr(), 0); 159 | var arr = []; 160 | cpp.NativeArray.setUnmanagedData(arr, ptr, len); 161 | return arr; 162 | } 163 | 164 | @:from inline public static function fromInt32Array(_v:haxe.io.Int32Array):godot.variant.PackedInt32Array { 165 | var res = new godot.variant.PackedInt32Array(); 166 | res.resize(_v.length); 167 | var ptr = godot.Types.GodotNativeInterface.packed_int32_array_operator_index(res.native_ptr(), 0); 168 | var src = cpp.NativeArray.getBase(_v.view.buffer.getData()).getBase(); 169 | cpp.Native.memcpy(ptr, src, _v.view.byteLength); 170 | return res; 171 | } 172 | 173 | @:to inline public function toInt32Array():haxe.io.Int32Array { 174 | var bLen = this.size().toInt() * 4; 175 | var tmp = godot.Types.GodotNativeInterface.packed_int32_array_operator_index(this.native_ptr(), 0).ptr; 176 | var ptr:cpp.Star = untyped __cpp__('(uint8_t*){0}', tmp); 177 | var bytes = haxe.io.Bytes.alloc(bLen); 178 | cpp.Native.memcpy(cpp.NativeArray.getBase(bytes.getData()).getBase(), ptr, bLen); 179 | return haxe.io.Int32Array.fromBytes(bytes); 180 | } 181 | } 182 | ops = ops.concat(tmp.fields); 183 | } 184 | default: 185 | } 186 | return ops; 187 | } 188 | } 189 | 190 | #end -------------------------------------------------------------------------------- /src/godot/macros/DocTools.hx: -------------------------------------------------------------------------------- 1 | package godot.macros; 2 | 3 | #if macro 4 | 5 | import godot.macros.TypeMacros; 6 | 7 | using StringTools; 8 | 9 | @:structInit 10 | private class BBStackLevel { 11 | public var id:String; 12 | public var params:Array; 13 | public var raw:String; 14 | public var content:String = ""; 15 | public var closed:Bool = false; 16 | public var unknown:Bool = false; 17 | var ldDump:BBStackLevel->String = null; 18 | 19 | public static function create(_id:String, _params:Array, _raw:String):BBStackLevel { 20 | var res:BBStackLevel = {id: _id, params: _params, raw: _raw}; 21 | 22 | switch (_id) { 23 | // 24 | case 'b': res.ldDump = (_sl) -> '**${_sl.content}**'; 25 | // 26 | case 'i': res.ldDump = (_sl) -> '*${_sl.content}*'; 27 | // 28 | case 'ul': res.ldDump = (_sl) -> '- ${_sl.content}'; 29 | // 30 | case 'ol': res.ldDump = (_sl) -> '- ${_sl.content}'; 31 | // 32 | case 'codeblocks': res.ldDump = (_sl) -> '

${_sl.content}

'; 33 | // 34 | case 'codeblock', 35 | 'csharp', 36 | 'gdscript': res.ldDump = (_sl) -> 37 | '```${_id}\n${_id=="gdscript" ? "#" : "//"}${_id}\n${_sl.content}```'.replace("\n\n", "\n"); 38 | // 39 | case 'code': res.ldDump = (_sl) -> '`${_sl.content}`'; 40 | // 41 | case 'url': res.ldDump = (_sl) -> { 42 | var url = _sl.params.length > 0 ? _sl.params[0] : _sl.content; 43 | url = url.replace("$DOCS_URL", "https://docs.godotengine.org/en/stable"); 44 | return '[${_sl.content}]($url)'; 45 | }; 46 | // 47 | case 'member', 48 | 'constant', 49 | 'param': { 50 | res.closed = true; 51 | res.ldDump = (_sl) -> { 52 | var tokens = _sl.params[0].split("."); 53 | tokens[0] = TypeMacros.getTypeName(tokens[0]); 54 | return '`${TypeMacros.getTypeName(tokens.join("."))}`'; 55 | }; 56 | } 57 | // 58 | case 'method': { 59 | res.closed = true; 60 | res.ldDump = (_sl) -> { 61 | var tokens = _sl.params[0].split("."); 62 | tokens[0] = TypeMacros.getTypeName(tokens[0]); 63 | if (tokens.length > 1) 64 | return '`${tokens.join(".")}`'; 65 | else 66 | return '${_sl.params[0]}'; 67 | }; 68 | } 69 | // 70 | case 'color': res.ldDump = (_sl) -> '${_sl.content}'; 71 | // 72 | default: { 73 | res.unknown = true; 74 | res.ldDump = (_sl) -> '${_sl.content}'; 75 | } 76 | } 77 | return res; 78 | } 79 | 80 | public function isCodeTag():Bool 81 | return id == 'code'; 82 | 83 | public function isCodeBlock():Bool { 84 | return switch(id) { 85 | case 'gdscript', 'csharp', 'codeblock': true; 86 | default: false; 87 | }; 88 | } 89 | 90 | public function dump(_parent:BBStackLevel):String { 91 | var isInsideCodeBlock = _parent != null ? _parent.isCodeBlock() : false; 92 | var isInsideCodeTag = _parent != null ? _parent.isCodeTag() : false; 93 | 94 | // make sure we dont accidently break the comment blocks: 95 | content = content.replace("*/", "* /"); 96 | 97 | if (unknown) { 98 | var tn = TypeMacros.getTypeName(id); 99 | if (id != tn) { 100 | return '`${tn}`'; 101 | } else { 102 | var res = '`${raw}`'; 103 | if (Std.isOfType(Std.parseInt(id.charAt(0)), Int)) { 104 | res = '[$raw]'; 105 | if (content.length > 0) 106 | res += '${content}[/${id}]'; 107 | res = '$res'; 108 | } 109 | else if (isInsideCodeTag) { 110 | res = '${raw}'; 111 | if (id.charAt(0) == id.charAt(0).toLowerCase()) { 112 | if (content.length > 0) 113 | res += '${content}'; 114 | res = '$res'; // [code][unnamed_project][/code] 115 | } else 116 | res = '`$res`'; // [code][Vector2][/code] 117 | } else if (isInsideCodeBlock) { 118 | res = '[$raw]'; 119 | if (content.length > 0) 120 | res += '${content}[/${id}]'; 121 | res = '$res'; 122 | } 123 | return res; 124 | } 125 | } else { 126 | return ldDump != null && !isInsideCodeBlock && !isInsideCodeTag ? ldDump(this) : '${content}'; 127 | } 128 | } 129 | } 130 | 131 | class DocTools { 132 | public static function convertBBCodeToMarkdown(_str:String):String { 133 | if (_str == null) 134 | return null; 135 | 136 | var stack:Array = [{id:'_root', params:[], raw: ''}]; 137 | var input = _str.replace("\n", "\n\n"); 138 | var output = new StringBuf(); 139 | var pos = null; 140 | var re_tags = ~/\[([^\]]+)\]/gm; 141 | 142 | while (re_tags.match(input)) { 143 | pos = re_tags.matchedPos(); 144 | stack[0].content += input.substr(0, pos.pos); 145 | var code = re_tags.matched(1); 146 | var tokens = code.indexOf('=') != -1 ? code.split("=") : code.split(" "); 147 | var id = tokens.shift(); 148 | var isTerminator = id.startsWith("/"); 149 | if (isTerminator && id.endsWith(stack[0].id)) { 150 | stack[0].closed = true; 151 | var tmp = stack.shift(); 152 | stack[0].content += tmp.dump(stack[0]); 153 | } else { 154 | var tag = BBStackLevel.create(id, tokens, '$code'); 155 | if (tag != null) { 156 | if (!stack[0].isCodeTag() && !stack[0].isCodeBlock() && !tag.closed && !tag.unknown) 157 | stack.unshift(tag); 158 | else 159 | stack[0].content += tag.dump(stack[0]); 160 | } 161 | } 162 | input = input.substr(pos.pos + pos.len); 163 | } 164 | 165 | stack[0].content += input.substr(0); 166 | output.add(stack[0].dump(null)); 167 | 168 | return output.toString(); 169 | } 170 | 171 | public static function test() { 172 | trace(convertBBCodeToMarkdown(test_string)); 173 | } 174 | 175 | static var test_string = " 176 | Returns the absolute value of a [Variant] parameter [param x] (i.e. non-negative value). Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i]. 177 | [codeblock] 178 | var a = abs(-1) 179 | # a is 1 180 | 181 | var b = abs(-1.2) 182 | # b is 1.2 183 | 184 | var c = abs(Vector2(-3.5, -4)) 185 | # c is (3.5, 4) 186 | 187 | var d = abs(Vector2i(-5, -6)) 188 | # d is (5, 6) 189 | 190 | var e = abs(Vector3(-7, 8.5, -3.8)) 191 | # e is (7, 8.5, 3.8) 192 | 193 | var f = abs(Vector3i(-7, -8, -9)) 194 | # f is (7, 8, 9) 195 | [/codeblock] 196 | [b]Note:[/b] For better type safety, use [method absf], [method absi], [method Vector2.abs], [method Vector2i.abs], [method Vector3.abs], [method Vector3i.abs], [method Vector4.abs], or [method Vector4i.abs]. 197 | 198 | Draws multiple disconnected lines with a uniform [param width] and segment-by-segment coloring. Each segment is defined by two consecutive points from [param points] array and a corresponding color from [param colors] array, i.e. i-th segment consists of [code]points[2 * i][/code], [code]points[2 * i + 1][/code] endpoints and has [code]colors[i][/code] color. When drawing large amounts of lines, this is faster than using individual [method draw_line] calls. To draw interconnected lines, use [method draw_polyline_colors] instead. 199 | If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code]. 200 | "; 201 | } 202 | 203 | #end -------------------------------------------------------------------------------- /src/godot/macros/TypeMacros.hx: -------------------------------------------------------------------------------- 1 | package godot.macros; 2 | 3 | #if macro 4 | 5 | import godot.Types; 6 | import haxe.macro.Expr; 7 | import haxe.macro.Context; 8 | import haxe.macro.TypeTools; 9 | import haxe.macro.ComplexTypeTools; 10 | 11 | using StringTools; 12 | 13 | class TypeMacros { 14 | 15 | public static var godotInheritancePairs = new Map(); 16 | 17 | public static function getTypeName(_t:String) { 18 | return switch(_t) { 19 | case "Nil": "Void"; 20 | case "bool": "Bool"; 21 | case "void": "cpp.Void"; 22 | case "int", "int64": "cpp.Int64"; 23 | case "int32_t", "int32": "cpp.Int32"; 24 | case "uint_t", "uint", "uint64": "cpp.UInt64"; 25 | case "uint32_t", "uint32": "cpp.UInt32"; 26 | case "uint16_t", "uint16": "cpp.UInt16"; 27 | case "uint8_t", "uint8": "cpp.UInt8"; 28 | case "int8_t", "int8": "cpp.Int8"; 29 | case "int16_t", "int16": "cpp.Int16"; 30 | case "real_t", "double", "float": "Float"; 31 | //case "double": "Float"; 32 | case "float32": "cpp.Float32"; 33 | // case "AABB": 34 | // case "Basis": 35 | // case "Callable": 36 | // case "Color": 37 | // case "Dictionary": 38 | // case "NodePath": 39 | // case "PackedByteArray": 40 | // case "PackedColorArray": 41 | // case "PackedFloat32Array": 42 | // case "PackedFloat64Array": 43 | // case "PackedInt32Array": 44 | // case "PackedInt64Array": 45 | // case "PackedStringArray": 46 | // case "PackedVector2Array": 47 | // case "PackedVector3Array": 48 | // case "Plane": 49 | // case "Quaternion": 50 | // case "Rect2": 51 | // case "Rect2i": 52 | // case "RID": 53 | // case "Signal": 54 | // case "StringName": 55 | // case "Transform2D": 56 | // case "Transform3D": 57 | // case "Vector2": 58 | // case "Vector2i": 59 | // case "Vector3": 60 | // case "Vector3i": 61 | case "const void*": "godot.Types.VoidPtr"; 62 | case "String": "GDString"; 63 | case "Array": "GDArray"; 64 | default: { 65 | var ret = _t; 66 | _t = _t.replace("const", "").trim(); 67 | 68 | if (_t.endsWith("*")) { 69 | var tmp = getTypeName(_t.substring(0, _t.length-1).trim()); 70 | var pack = getTypePackage(tmp).concat([tmp]); 71 | ret = 'cpp.Pointer<${pack.join(".")}>'; 72 | } 73 | 74 | ret = convertIfTypedArray(ret); 75 | 76 | ret; 77 | } 78 | }; 79 | } 80 | 81 | public static function getTypePackage(_type:String) { 82 | var res = []; 83 | var type = GDExtensionVariantType.fromString(_type); 84 | if (!TypeMacros.isTypeNative(_type)) { 85 | if ((type == GDExtensionVariantType.NIL || type == GDExtensionVariantType.OBJECT) && 86 | _type != "Variant") { 87 | if (!StringTools.startsWith(_type, "cpp")) 88 | res = ["godot"]; 89 | else 90 | res = []; 91 | } 92 | else 93 | res = ["godot", "variant"]; 94 | } 95 | return res; 96 | } 97 | 98 | public static function isTypeNative(_type:String) { 99 | return switch(_type) { 100 | case "Void", "Nil", "bool", "Bool", 101 | "int", "int64", "cpp.Int64", 102 | "int32_t", "int32", "cpp.Int32", 103 | "uint_t", "uint", "uint64", "cpp.UInt64", 104 | "uint32_t", "uint32", "cpp.UInt32", 105 | "uint16_t", "uint16", "cpp.UInt16", 106 | "uint8_t", "uint8", "cpp.UInt8", 107 | "int8_t", "int8", "cpp.Int8", 108 | "int16_t", "int16", "cpp.Int16", 109 | "real_t", "float", "double", 110 | "float_t", "double_t", "Float", 111 | "float32_t", "cpp.Float32", "cpp.Float64", 112 | "void", "const void*", "godot.Types.VoidPtr": true; 113 | 114 | default: false; 115 | } 116 | } 117 | 118 | public static function isTypeRefCounted(_type:haxe.macro.TypePath):Bool { 119 | var has = false; 120 | if (!isObjectType(_type.name) || isTypeNative(_type.name)) 121 | return has; 122 | 123 | var current = _type.name; 124 | while (current != null) { 125 | if (current == "RefCounted") { 126 | has = true; 127 | break; 128 | } 129 | current = godotInheritancePairs.get(current); 130 | } 131 | return has; 132 | } 133 | 134 | public static function isEnumOrBitfield(_type:String) { 135 | return StringTools.startsWith(_type, "enum::") || StringTools.startsWith(_type, "bitfield::"); 136 | } 137 | 138 | public static function getNativeTypeDefaultValue(_type:String):Dynamic { 139 | return switch(_type) { 140 | case "Bool": false; 141 | case "Float", "cpp.Float32", "cpp.Float64": 0.0; 142 | case "cpp.Int64", "cpp.Int32", "cpp.Int16", "cpp.Int8", 143 | "cpp.UInt64", "cpp.UInt32", "cpp.UInt16", "cpp.UInt8": 0; 144 | default: null; // make the compiler complain here! 145 | } 146 | } 147 | 148 | public static function convertIfTypedArray(_type:String):String { 149 | // convert the godot typedarray to GDArray 150 | if (_type != null && StringTools.startsWith(_type, "typedarray")) 151 | return "GDArray"; 152 | return _type; 153 | } 154 | 155 | public static function isTypeAllowed(_type:String):Bool { 156 | // this function is a development helper 157 | return switch (_type) { 158 | case //"Nil", 159 | //"bool", 160 | //"int", 161 | //"float", 162 | // "Color": false; 163 | // "Plane", 164 | // "Quaternion", 165 | // "Rect2", 166 | // "Rect2i", 167 | // "Vector2", 168 | // "Vector2i", 169 | // "Vector3i", 170 | // "Projection", 171 | 172 | //"PackedByteArray", 173 | //"PackedColorArray", 174 | //"PackedFloat32Array", 175 | //"PackedFloat64Array", 176 | //"PackedInt32Array", 177 | //"PackedInt64Array", 178 | //"PackedStringArray", 179 | //"PackedVector2Array", 180 | //"PackedVector3Array", 181 | 182 | "const uint8_t *" : false; // TODO 183 | //"AABB", 184 | //"Basis", 185 | //"Object", // wtf 186 | //"SceneTree", 187 | //"Transform2D", 188 | //"Transform3D", 189 | //"Vector3", 190 | default: { 191 | if (_type != null) { 192 | !StringTools.contains(_type, ","); 193 | } 194 | else 195 | true; 196 | } 197 | }; 198 | } 199 | 200 | public static function isObjectType(_t:String):Bool 201 | return switch(_t) { 202 | case 'Pointer', 'VoidPtr', 'Bool', 'GDExtensionBool', 'Int', 'Int64', 203 | 'GDExtensionInt', 'Float', 'GDExtensionFloat', 'GDString', 'Color', 204 | 'Quaternion', 'Vector4', 'Vector2', 'Vector3', 'Vector2i', 'Vector3i', 205 | 'Vector4i', "Rect2", "Rect2i", "AABB", "Plane", "Basis", "Callable", "Dictionary", 206 | "GDArray", "NodePath", "PackedByteArray", "PackedColorArray", 207 | "PackedFloat32Array", "PackedFloat64Array", "PackedInt32Array", 208 | "PackedInt64Array", "PackedStringArray", "PackedVector2Array", 209 | "PackedVector3Array", "Projection", "RID", "Signal", "StringName", 210 | "Transform2D", "Transform3D", "Variant": false; 211 | default: true; 212 | }; 213 | 214 | public static function isACustomBuiltIn(_type:String):Bool { 215 | // whitelist custom builtin implementations 216 | return switch (_type) { 217 | case 218 | //"AABB", 219 | //"Basis", 220 | "Color", 221 | "Plane", 222 | // "Rect2", 223 | // "Rect2i", 224 | "Quaternion", 225 | //"Transform2D", 226 | //"Transform3D", 227 | "Vector2", 228 | "Vector2i", 229 | "Vector3", 230 | "Vector3i", 231 | "Vector4", 232 | "Vector4i", 233 | 234 | // ATTENTION: the following ones need to be ignored. 235 | // we dont implement them but rather map them to haxe 236 | // automagically 237 | "Nil", 238 | "bool", 239 | "int", 240 | "float": true; 241 | default: false; 242 | } 243 | } 244 | 245 | public static function getOpName(_type:GDExtensionVariantOperator):String { 246 | return switch (_type) { 247 | case EQUAL: "EQUAL"; 248 | case NOT_EQUAL: "NOT_EQUAL"; 249 | case LESS: "LESS"; 250 | case LESS_EQUAL: "LESS_EQUAL"; 251 | case GREATER: "GREATER"; 252 | case GREATER_EQUAL: "GREATER_EQUAL"; 253 | case ADD: "ADD"; 254 | case SUBTRACT: "SUBTRACT"; 255 | case MULTIPLY: "MULTIPLY"; 256 | case DIVIDE: "DIVIDE"; 257 | //case NEGATE: "NEGATE"; 258 | //case POSITIVE: "POSITIVE"; 259 | case MODULE: "MODULE"; 260 | //case POWER: "POWER"; 261 | case SHIFT_LEFT: "SHIFT_LEFT"; 262 | case SHIFT_RIGHT: "SHIFT_RIGHT"; 263 | case BIT_AND: "BIT_AND"; 264 | case BIT_OR: "BIT_OR"; 265 | case BIT_XOR: "BIT_XOR"; 266 | //case BIT_NEGATE: "BIT_NEGATE"; 267 | case AND: "AND"; 268 | case OR: "OR"; 269 | case XOR: "XOR"; 270 | case NOT: "NOT"; 271 | //case IN: "IN"; 272 | default: null; 273 | //case MAX: "MAX"; 274 | } 275 | } 276 | 277 | public static function isOpTypeAllowed(_type:String):Bool { 278 | return switch(_type) { 279 | case "Nil": false; 280 | case "Vector4i", "Vector4": false; 281 | default: true; 282 | } 283 | } 284 | 285 | public static function getOpHaxe(_type:GDExtensionVariantOperator):String { 286 | return switch (_type) { 287 | case EQUAL: "=="; 288 | case NOT_EQUAL: "!="; 289 | case LESS: "<"; 290 | case LESS_EQUAL: "<="; 291 | case GREATER: ">"; 292 | case GREATER_EQUAL: ">="; 293 | case ADD: "+"; 294 | case SUBTRACT: "-"; 295 | case MULTIPLY: "*"; 296 | case DIVIDE: "/"; 297 | //case NEGATE: "NEGATE"; 298 | //case POSITIVE: "POSITIVE"; 299 | case MODULE: "%"; 300 | //case POWER: "POWER"; 301 | case SHIFT_LEFT: "<<"; 302 | case SHIFT_RIGHT: ">>"; 303 | case BIT_AND: "&"; 304 | case BIT_OR: "|"; 305 | case BIT_XOR: "^"; 306 | //case BIT_NEGATE: "BIT_NEGATE"; 307 | case AND: "&&"; 308 | case OR: "||"; 309 | //case XOR: "XOR"; 310 | case NOT: "!"; 311 | //case IN: "IN"; 312 | default: null; 313 | //case MAX: "MAX"; 314 | } 315 | } 316 | 317 | public static function fixCase(_str:String):String { 318 | /* 319 | if (_str.charAt(0) == "_") // ignore virtuals! 320 | return _str; 321 | else if (_str == "to_string") 322 | return _str; 323 | 324 | var res = ""; 325 | var tokens = _str.split("_"); 326 | if (tokens.length > 1) { 327 | res = tokens[0]; 328 | for (i in 1...tokens.length) { 329 | var t = tokens[i]; 330 | var first = t.charAt(0).toUpperCase(); 331 | var rest = t.substr(1); 332 | res += first + rest; 333 | } 334 | } else 335 | res = _str; 336 | return res; 337 | */ 338 | return _str; 339 | } 340 | } 341 | 342 | #end -------------------------------------------------------------------------------- /src/godot/variant/IBuiltIn.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | interface IBuiltIn {} -------------------------------------------------------------------------------- /src/godot/variant/Plane.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Plane = Array; 11 | 12 | @:forward 13 | abstract Plane(__Plane) from __Plane to __Plane { 14 | 15 | inline public function new(?_a:GDExtensionFloat=0, ?_b:GDExtensionFloat=0, ?_c:GDExtensionFloat=0, ?_d:GDExtensionFloat):Plane this = _alloc(_a, _b, _c, _d); 16 | 17 | inline private static function _alloc(_a:GDExtensionFloat, _b:GDExtensionFloat, _c:GDExtensionFloat, _d:GDExtensionFloat):__Plane 18 | return [_a, _b, _c, _d]; 19 | 20 | inline public function native_ptr():GDExtensionTypePtr { 21 | #if !macro 22 | return cast cpp.NativeArray.getBase(this).getBase(); 23 | #else 24 | return 0; 25 | #end 26 | } 27 | 28 | inline static public function fromPlane(from:Plane):Plane { 29 | return new Plane(from.a, from.b, from.c, from.d); 30 | } 31 | 32 | inline static public function fromNormal(normal:Vector3, d:GDExtensionFloat = 0.0):Plane { 33 | var p = new Plane(); 34 | p.normal = normal; 35 | p.d = d; 36 | return p; 37 | } 38 | 39 | inline static public function fromNormalPoint(normal:Vector3, point:Vector3):Plane { 40 | var p = new Plane(); 41 | p.normal = normal; 42 | p.d = normal.dot(point); 43 | return p; 44 | } 45 | 46 | inline static public function fromMultiPoint(point1:Vector3, point2:Vector3, point3:Vector3, dir:Int = CLOCKWISE):Plane { 47 | var p = new Plane(); 48 | if (dir == CLOCKWISE) { 49 | p.normal = (point1 - point3).cross(point1 - point2); 50 | } else { 51 | p.normal = (point1 - point2).cross(point1 - point3); 52 | } 53 | 54 | p.normal.normalize(); 55 | p.d = p.normal.dot(point1); 56 | return p; 57 | } 58 | 59 | public var a(get, set):GDExtensionFloat; 60 | inline function get_a() return this[0]; 61 | inline function set_a(_v:GDExtensionFloat) {this[0] = _v; return _v;} 62 | 63 | public var b(get, set):GDExtensionFloat; 64 | inline function get_b() return this[1]; 65 | inline function set_b(_v:GDExtensionFloat) {this[1] = _v; return _v;} 66 | 67 | public var c(get, set):GDExtensionFloat; 68 | inline function get_c() return this[2]; 69 | inline function set_c(_v:GDExtensionFloat) {this[2] = _v; return _v;} 70 | 71 | public var d(get, set):GDExtensionFloat; 72 | inline function get_d() return this[3]; 73 | inline function set_d(_v:GDExtensionFloat) {this[3] = _v; return _v;} 74 | 75 | public var normal(get, set):Vector3; 76 | inline function get_normal() return new Vector3(this[0], this[1], this[2]); 77 | inline function set_normal(_v:Vector3) {this[0] = _v.x; this[1] = _v.y; this[2] = _v.z; return _v;} 78 | 79 | @:arrayAccess 80 | inline public function get(_i:Int) return this[_i]; 81 | 82 | @:arrayAccess 83 | inline public function setAt(_i:Int, _v:GDExtensionFloat):Void 84 | this[_i] = _v; 85 | 86 | inline public function copy():Plane 87 | return new Plane(this[0], this[1], this[2], this[3]); 88 | 89 | public function project(p_point:Vector3):Vector3 { 90 | return p_point - normal * distance_to(p_point); 91 | } 92 | 93 | public function is_point_over(p_point:Vector3):Bool { 94 | return (normal.dot(p_point) > d); 95 | } 96 | 97 | public function distance_to(p_point:Vector3):Float { 98 | return (normal.dot(p_point) - d); 99 | } 100 | 101 | public function has_point(p_point:Vector3, p_tolerance:Float):Bool { 102 | var dist:Float = normal.dot(p_point) - d; 103 | dist = ABS(dist); 104 | return (dist <= p_tolerance); 105 | } 106 | 107 | public function normalize():Void { 108 | var l = normal.length(); 109 | if (l == 0) { 110 | a = b = c = d = 0; 111 | return; 112 | } 113 | a /= l; 114 | b /= l; 115 | c /= l; 116 | d /= l; 117 | } 118 | 119 | public function normalized():Plane { 120 | var p:Plane = copy(); 121 | p.normalize(); 122 | return p; 123 | } 124 | 125 | public function center():Vector3 { 126 | return normal * d; 127 | } 128 | 129 | public function get_any_perpendicular_normal():Vector3 { 130 | var p1:Vector3 = new Vector3(1, 0, 0); 131 | var p2:Vector3 = new Vector3(0, 1, 0); 132 | var p:Vector3; 133 | 134 | if (ABS(normal.dot(p1)) > 0.99) { // if too similar to p1 135 | p = p2; // use p2 136 | } else { 137 | p = p1; // use p1 138 | } 139 | 140 | p -= normal * normal.dot(p); 141 | p.normalize(); 142 | 143 | return p; 144 | } 145 | 146 | /* intersections */ 147 | 148 | function intersect_3_ptr(p_plane1:Plane, p_plane2:Plane, r_result:Vector3):Bool { 149 | var p_plane0:Plane = copy(); 150 | var normal0:Vector3 = p_plane0.normal; 151 | var normal1:Vector3 = p_plane1.normal; 152 | var normal2:Vector3 = p_plane2.normal; 153 | 154 | var denom:Float = normal0.cross(normal1).dot(normal2); 155 | 156 | if (GDMath.is_zero_approx(denom)) { 157 | return false; 158 | } 159 | 160 | if (r_result != null) { 161 | var r:Vector3 = ((normal1.cross(normal2) * p_plane0.d) + 162 | (normal2.cross(normal0) * p_plane1.d) + 163 | (normal0.cross(normal1) * p_plane2.d)) / 164 | denom; 165 | r_result.x = r.x; 166 | r_result.y = r.y; 167 | r_result.z = r.z; 168 | } 169 | 170 | return true; 171 | } 172 | 173 | function intersects_ray_ptr(p_from:Vector3, p_dir:Vector3, p_intersection:Vector3):Bool { 174 | var segment:Vector3 = p_dir; 175 | var den:Float = normal.dot(segment); 176 | 177 | //printf("den is %i\n",den); 178 | if (GDMath.is_zero_approx(den)) { 179 | return false; 180 | } 181 | 182 | var dist:Float = (normal.dot(p_from) - d) / den; 183 | //printf("dist is %i\n",dist); 184 | 185 | if (dist > CMP_EPSILON) { //this is a ray, before the emitting pos (p_from) doesn't exist 186 | 187 | return false; 188 | } 189 | 190 | dist = -dist; 191 | var r = p_from + segment * dist; 192 | p_intersection.x = r.x; 193 | p_intersection.y = r.y; 194 | p_intersection.z = r.z; 195 | 196 | return true; 197 | } 198 | 199 | function intersects_segment_ptr(p_begin:Vector3, p_end:Vector3, p_intersection:Vector3):Bool { 200 | var segment:Vector3 = p_begin - p_end; 201 | var den:Float = normal.dot(segment); 202 | 203 | //printf("den is %i\n",den); 204 | if (GDMath.is_zero_approx(den)) { 205 | return false; 206 | } 207 | 208 | var dist:Float = (normal.dot(p_begin) - d) / den; 209 | //printf("dist is %i\n",dist); 210 | 211 | if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) { 212 | return false; 213 | } 214 | 215 | dist = -dist; 216 | var r = p_begin + segment * dist; 217 | p_intersection.x = r.x; 218 | p_intersection.y = r.y; 219 | p_intersection.z = r.z; 220 | 221 | return true; 222 | } 223 | 224 | public function intersect_3(p_plane1:Plane, p_plane2:Plane):Variant { 225 | var inters:Vector3 = new Vector3(); 226 | if (intersect_3_ptr(p_plane1, p_plane2, inters)) { 227 | return inters; 228 | } else { 229 | return new Variant(); 230 | } 231 | } 232 | 233 | public function intersects_ray(p_from:Vector3, p_dir:Vector3):Variant { 234 | var inters:Vector3 = new Vector3(); 235 | if (intersects_ray_ptr(p_from, p_dir, inters)) { 236 | return inters; 237 | } else { 238 | return new Variant(); 239 | } 240 | } 241 | 242 | public function intersects_segment(p_begin:Vector3, p_end:Vector3):Variant { 243 | var inters:Vector3 = new Vector3(); 244 | if (intersects_segment_ptr(p_begin, p_end, inters)) { 245 | return inters; 246 | } else { 247 | return new Variant(); 248 | } 249 | } 250 | 251 | /* misc */ 252 | 253 | public function is_equal_approx_any_side(p_plane:Plane):Bool { 254 | return (normal.is_equal_approx(p_plane.normal) && GDMath.is_equal_approx(d, p_plane.d)) || (normal.is_equal_approx(-p_plane.normal) && GDMath.is_equal_approx(d, -p_plane.d)); 255 | } 256 | 257 | public function is_equal_approx(p_plane:Plane):Bool { 258 | return normal.is_equal_approx(p_plane.normal) && GDMath.is_equal_approx(d, p_plane.d); 259 | } 260 | 261 | public function is_finite():Bool { 262 | return normal.is_finite() && GDMath.is_finite(d); 263 | } 264 | 265 | @:to public function toString():String { 266 | return "[N: " + normal + ", D: " + d + "]"; 267 | } 268 | 269 | @:op(A == B) 270 | inline public static function eq(lhs:Plane, rhs:Plane):Bool { 271 | return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3]; 272 | } 273 | 274 | @:op(A != B) 275 | inline public static function neq(lhs:Plane, rhs:Plane):Bool { 276 | return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3]; 277 | } 278 | 279 | @:op(A * B) 280 | inline public static function mult(lhs:Plane, rhs:Plane):Plane { 281 | var res = new Plane(); 282 | res[0] = lhs[0] * rhs[0]; 283 | res[1] = lhs[1] * rhs[1]; 284 | res[2] = lhs[2] * rhs[2]; 285 | res[3] = lhs[3] * rhs[3]; 286 | return res; 287 | } 288 | 289 | @:op(A *= B) 290 | inline public static function multIn(lhs:Plane, rhs:Plane):Plane { 291 | lhs[0] *= rhs[0]; 292 | lhs[1] *= rhs[1]; 293 | lhs[2] *= rhs[2]; 294 | lhs[3] *= rhs[3]; 295 | return lhs; 296 | } 297 | 298 | @:op(A / B) 299 | inline public static function divide(lhs:Plane, rhs:Plane):Plane { 300 | var res = new Plane(); 301 | res[0] = lhs[0] / rhs[0]; 302 | res[1] = lhs[1] / rhs[1]; 303 | res[2] = lhs[2] / rhs[2]; 304 | res[3] = lhs[3] / rhs[3]; 305 | return res; 306 | } 307 | 308 | @:op(A /= B) 309 | inline public static function divideIn(lhs:Plane, rhs:Plane):Plane { 310 | lhs[0] /= rhs[0]; 311 | lhs[1] /= rhs[1]; 312 | lhs[2] /= rhs[2]; 313 | lhs[3] /= rhs[3]; 314 | return lhs; 315 | } 316 | 317 | @:op(A * B) 318 | inline public static function multScalar(lhs:Plane, scalar:GDExtensionFloat):Plane { 319 | var res = new Plane(); 320 | res[0] = lhs[0] * scalar; 321 | res[1] = lhs[1] * scalar; 322 | res[2] = lhs[2] * scalar; 323 | res[3] = lhs[3] * scalar; 324 | return res; 325 | } 326 | 327 | @:op(A *= B) 328 | inline public static function multInScalar(lhs:Plane, scalar:GDExtensionFloat):Plane { 329 | lhs[0] *= scalar; 330 | lhs[1] *= scalar; 331 | lhs[2] *= scalar; 332 | lhs[3] *= scalar; 333 | return lhs; 334 | } 335 | 336 | @:op(A / B) 337 | inline public static function divideScalar(lhs:Plane, scalar:GDExtensionFloat):Plane { 338 | var res = new Plane(); 339 | res[0] = lhs[0] / scalar; 340 | res[1] = lhs[1] / scalar; 341 | res[2] = lhs[2] / scalar; 342 | res[3] = lhs[3] / scalar; 343 | return res; 344 | } 345 | 346 | @:op(A /= B) 347 | inline public static function divideInScalar(lhs:Plane, scalar:GDExtensionFloat):Plane { 348 | lhs[0] /= scalar; 349 | lhs[1] /= scalar; 350 | lhs[2] /= scalar; 351 | lhs[3] /= scalar; 352 | return lhs; 353 | } 354 | 355 | @:op(A + B) 356 | inline public static function add(lhs:Plane, rhs:Plane):Plane { 357 | var res = new Plane(); 358 | res[0] = lhs[0] + rhs[0]; 359 | res[1] = lhs[1] + rhs[1]; 360 | res[2] = lhs[2] + rhs[2]; 361 | res[3] = lhs[3] + rhs[3]; 362 | return res; 363 | } 364 | 365 | @:op(A += B) 366 | inline public static function addIn(lhs:Plane, rhs:Plane):Plane { 367 | lhs[0] += rhs[0]; 368 | lhs[1] += rhs[1]; 369 | lhs[2] += rhs[2]; 370 | lhs[3] += rhs[3]; 371 | return lhs; 372 | } 373 | 374 | @:op(A - B) 375 | inline public static function subtract(lhs:Plane, rhs:Plane):Plane { 376 | var res = new Plane(); 377 | res[0] = lhs[0] - rhs[0]; 378 | res[1] = lhs[1] - rhs[1]; 379 | res[2] = lhs[2] - rhs[2]; 380 | res[3] = lhs[3] - rhs[3]; 381 | return res; 382 | } 383 | 384 | @:op(A -= B) 385 | inline public static function subtractIn(lhs:Plane, rhs:Plane):Plane { 386 | lhs[0] -= rhs[0]; 387 | lhs[1] -= rhs[1]; 388 | lhs[2] -= rhs[2]; 389 | lhs[3] -= rhs[3]; 390 | return lhs; 391 | } 392 | 393 | @:op(-A) 394 | inline public static function negate(lhs:Plane):Plane { 395 | var res = new Plane(); 396 | res[0] = -lhs[0]; 397 | res[1] = -lhs[1]; 398 | res[2] = -lhs[2]; 399 | res[3] = -lhs[3]; 400 | return res; 401 | } 402 | 403 | } -------------------------------------------------------------------------------- /src/godot/variant/Point2.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | typedef Point2 = godot.variant.Vector2; -------------------------------------------------------------------------------- /src/godot/variant/Point2i.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | typedef Point2i = godot.variant.Vector2i; -------------------------------------------------------------------------------- /src/godot/variant/Rect2i._hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.variant.Vector2; 5 | import godot.variant.Vector2i; 6 | 7 | #if cpp 8 | using cpp.NativeArray; 9 | #end 10 | 11 | typedef __Rect2i = Array; 12 | 13 | @:forward 14 | abstract Rect2i(__Rect2i) from __Rect2i to __Rect2i { 15 | inline public function new(?_p:Vector2i=null, ?_s:Vector2i=null):Rect2i this = _alloc(_p==null ? new Vector2i() : _p, _s==null ? new Vector2i() : _s); 16 | 17 | inline private static function _alloc(_p:Vector2i, _s:Vector2i):__Rect2i 18 | return [_p, _s, new Vector2i(_p.x + _s.x, _p.y + _s.y)]; 19 | 20 | inline public function native_ptr():GDExtensionTypePtr { 21 | #if !macro 22 | return cast cpp.NativeArray.getBase(this).getBase(); 23 | #else 24 | return 0; 25 | #end 26 | } 27 | 28 | inline public function fromRect2():Rect2i { 29 | return new Rect2i(position.copy(), size.copy()); 30 | } 31 | 32 | inline static public function fromInts(x:Int, y:Int, width:Int, height:Int):Rect2i { 33 | return new Rect2i(new Vector2i(x, y), new Vector2i(width, height)); 34 | } 35 | 36 | public var position(get, set):Vector2i; 37 | inline function get_position():Vector2i { return this[0]; } 38 | inline function set_position(p_pos:Vector2i):Vector2i { this[0] = p_pos; return p_pos; } 39 | 40 | public var size(get, set):Vector2i; 41 | inline function get_size():Vector2i { return this[1]; } 42 | inline function set_size(p_size:Vector2i):Vector2i { this[1] = p_size; return p_size; } 43 | 44 | public var end(get, set):Vector2i; 45 | inline function get_end():Vector2i { return position + size; } 46 | inline function set_end(p_end:Vector2i):Vector2i { size = p_end - position; return p_end; } 47 | 48 | @:arrayAccess 49 | inline public function get(_i:Int) return this[_i]; 50 | 51 | @:arrayAccess 52 | inline public function setAt(_i:Int, _v:Vector2i):Void 53 | this[_i] = _v; 54 | 55 | inline public function copy():Rect2i 56 | return new Rect2i(this[0], this[1]); 57 | 58 | 59 | public function get_area():Float { return size.x * size.y; } 60 | 61 | public function get_center():Vector2i { return position + (size / 2); } 62 | 63 | public function intersects(p_rect:Rect2i):Bool { 64 | #if MATH_CHECKS 65 | if ((size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { 66 | ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); 67 | } 68 | #end 69 | if (position.x >= (p_rect.position.x + p_rect.size.x)) { 70 | return false; 71 | } 72 | if ((position.x + size.x) <= p_rect.position.x) { 73 | return false; 74 | } 75 | if (position.y >= (p_rect.position.y + p_rect.size.y)) { 76 | return false; 77 | } 78 | if ((position.y + size.y) <= p_rect.position.y) { 79 | return false; 80 | } 81 | 82 | return true; 83 | } 84 | 85 | public function encloses(p_rect:Rect2i):Bool { 86 | #if MATH_CHECKS 87 | if ((size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { 88 | ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); 89 | } 90 | #end 91 | return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && 92 | ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) && 93 | ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y)); 94 | } 95 | 96 | public function has_area():Bool { 97 | return size.x > 0 && size.y > 0; 98 | } 99 | 100 | // Returns the instersection between two Rect2is or an empty Rect2i if there is no intersection 101 | public function intersection(p_rect:Rect2i):Rect2i { 102 | var new_rect:Rect2i = p_rect; 103 | 104 | if (!intersects(new_rect)) { 105 | return new Rect2i(); 106 | } 107 | 108 | new_rect.position.x = Std.int(MAX(p_rect.position.x, position.x)); 109 | new_rect.position.y = Std.int(MAX(p_rect.position.y, position.y)); 110 | 111 | var p_rect_end:Point2i = p_rect.position + p_rect.size; 112 | var end:Point2i = position + size; 113 | 114 | new_rect.size.x = Std.int(MIN(p_rect_end.x, end.x) - new_rect.position.x); 115 | new_rect.size.y = Std.int(MIN(p_rect_end.y, end.y) - new_rect.position.y); 116 | 117 | return new_rect; 118 | } 119 | 120 | public function merge(p_rect:Rect2i):Rect2i { ///< return a merged rect 121 | #if MATH_CHECKS 122 | if ((size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { 123 | ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); 124 | } 125 | #end 126 | var new_rect:Rect2i = new Rect2i(); 127 | 128 | new_rect.position.x = Std.int(MIN(p_rect.position.x, position.x)); 129 | new_rect.position.y = Std.int(MIN(p_rect.position.y, position.y)); 130 | 131 | new_rect.size.x = Std.int(MAX(p_rect.position.x + p_rect.size.x, position.x + size.x)); 132 | new_rect.size.y = Std.int(MAX(p_rect.position.y + p_rect.size.y, position.y + size.y)); 133 | 134 | new_rect.size = new_rect.size - new_rect.position; // Make relative again. 135 | 136 | return new_rect; 137 | } 138 | 139 | public function has_point(p_point:Point2i):Bool { 140 | #if MATH_CHECKS 141 | if ((size.x < 0 || size.y < 0)) { 142 | ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); 143 | } 144 | #end 145 | if (p_point.x < position.x) { 146 | return false; 147 | } 148 | if (p_point.y < position.y) { 149 | return false; 150 | } 151 | 152 | if (p_point.x >= (position.x + size.x)) { 153 | return false; 154 | } 155 | if (p_point.y >= (position.y + size.y)) { 156 | return false; 157 | } 158 | 159 | return true; 160 | } 161 | 162 | public function grow(p_amount:Int):Rect2i { 163 | var g:Rect2i = copy(); 164 | g.position.x -= p_amount; 165 | g.position.y -= p_amount; 166 | g.size.x += p_amount * 2; 167 | g.size.y += p_amount * 2; 168 | return g; 169 | } 170 | 171 | public function grow_side(p_side:Int, p_amount:Int):Rect2i { 172 | var g:Rect2i = copy(); 173 | g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0, 174 | (SIDE_TOP == p_side) ? p_amount : 0, 175 | (SIDE_RIGHT == p_side) ? p_amount : 0, 176 | (SIDE_BOTTOM == p_side) ? p_amount : 0); 177 | return g; 178 | } 179 | 180 | public function grow_individual(p_left:Int, p_top:Int, p_right:Int, p_bottom:Int):Rect2i { 181 | var g:Rect2i = copy(); 182 | g.position.x -= p_left; 183 | g.position.y -= p_top; 184 | g.size.x += p_left + p_right; 185 | g.size.y += p_top + p_bottom; 186 | 187 | return g; 188 | } 189 | 190 | public function expand(p_vector:Vector2i):Rect2i { 191 | var r:Rect2i = copy(); 192 | r.expand_to(p_vector); 193 | return r; 194 | } 195 | 196 | function expand_to(p_vector:Point2i):Void { 197 | #if MATH_CHECKS 198 | if ((size.x < 0 || size.y < 0)) { 199 | ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); 200 | } 201 | #end 202 | var begin:Point2i = position; 203 | var end:Point2i = position + size; 204 | 205 | if (p_vector.x < begin.x) { 206 | begin.x = p_vector.x; 207 | } 208 | if (p_vector.y < begin.y) { 209 | begin.y = p_vector.y; 210 | } 211 | 212 | if (p_vector.x > end.x) { 213 | end.x = p_vector.x; 214 | } 215 | if (p_vector.y > end.y) { 216 | end.y = p_vector.y; 217 | } 218 | 219 | position = begin; 220 | size = end - begin; 221 | } 222 | 223 | public function abs():Rect2i { 224 | return new Rect2i(new Point2i(position.x + Std.int(MIN(size.x, 0)), position.y + Std.int(MIN(size.y, 0))), size.abs()); 225 | } 226 | 227 | @:to public function toString():String { 228 | return "[P: " + position + ", S: " + size + "]"; 229 | } 230 | 231 | @:op(A == B) 232 | inline public static function eq(lhs:Rect2i, rhs:Rect2i):Bool { 233 | return lhs[0] == rhs[0] && lhs[1] == rhs[1]; 234 | } 235 | 236 | @:op(A != B) 237 | inline public static function neq(lhs:Rect2i, rhs:Rect2i):Bool { 238 | return lhs[0] != rhs[0] && lhs[1] != rhs[1]; 239 | } 240 | 241 | @:op(A * B) 242 | inline public static function mult(lhs:Rect2i, rhs:Rect2i):Rect2i { 243 | var res = new Rect2i(); 244 | res[0] = lhs[0] * rhs[0]; 245 | res[1] = lhs[1] * rhs[1]; 246 | return res; 247 | } 248 | 249 | @:op(A *= B) 250 | inline public static function multIn(lhs:Rect2i, rhs:Rect2i):Rect2i { 251 | lhs[0] *= rhs[0]; 252 | lhs[1] *= rhs[1]; 253 | return lhs; 254 | } 255 | 256 | @:op(A / B) 257 | inline public static function divide(lhs:Rect2i, rhs:Rect2i):Rect2i { 258 | var res = new Rect2i(); 259 | res[0] = lhs[0] / rhs[0]; 260 | res[1] = lhs[1] / rhs[1]; 261 | return res; 262 | } 263 | 264 | @:op(A /= B) 265 | inline public static function divideIn(lhs:Rect2i, rhs:Rect2i):Rect2i { 266 | lhs[0] /= rhs[0]; 267 | lhs[1] /= rhs[1]; 268 | return lhs; 269 | } 270 | 271 | @:op(A * B) 272 | inline public static function multScalar(lhs:Rect2i, scalar:GDExtensionFloat):Rect2i { 273 | var res = new Rect2i(); 274 | res[0] = lhs[0] * scalar; 275 | res[1] = lhs[1] * scalar; 276 | return res; 277 | } 278 | 279 | @:op(A *= B) 280 | inline public static function multInScalar(lhs:Rect2i, scalar:GDExtensionFloat):Rect2i { 281 | lhs[0] *= scalar; 282 | lhs[1] *= scalar; 283 | return lhs; 284 | } 285 | 286 | @:op(A / B) 287 | inline public static function divideScalar(lhs:Rect2i, scalar:GDExtensionFloat):Rect2i { 288 | var res = new Rect2i(); 289 | res[0] = lhs[0] / scalar; 290 | res[1] = lhs[1] / scalar; 291 | return res; 292 | } 293 | 294 | @:op(A /= B) 295 | inline public static function divideInScalar(lhs:Rect2i, scalar:GDExtensionFloat):Rect2i { 296 | lhs[0] /= scalar; 297 | lhs[1] /= scalar; 298 | return lhs; 299 | } 300 | 301 | @:op(A + B) 302 | inline public static function add(lhs:Rect2i, rhs:Rect2i):Rect2i { 303 | var res = new Rect2i(); 304 | res[0] = lhs[0] + rhs[0]; 305 | res[1] = lhs[1] + rhs[1]; 306 | return res; 307 | } 308 | 309 | @:op(A += B) 310 | inline public static function addIn(lhs:Rect2i, rhs:Rect2i):Rect2i { 311 | lhs[0] += rhs[0]; 312 | lhs[1] += rhs[1]; 313 | return lhs; 314 | } 315 | 316 | @:op(A - B) 317 | inline public static function subtract(lhs:Rect2i, rhs:Rect2i):Rect2i { 318 | var res = new Rect2i(); 319 | res[0] = lhs[0] - rhs[0]; 320 | res[1] = lhs[1] - rhs[1]; 321 | return res; 322 | } 323 | 324 | @:op(A -= B) 325 | inline public static function subtractIn(lhs:Rect2i, rhs:Rect2i):Rect2i { 326 | lhs[0] -= rhs[0]; 327 | lhs[1] -= rhs[1]; 328 | return lhs; 329 | } 330 | 331 | @:op(-A) 332 | inline public static function negate(lhs:Rect2i):Rect2i { 333 | var res = new Rect2i(); 334 | res[0] = -lhs[0]; 335 | res[1] = -lhs[1]; 336 | return res; 337 | } 338 | } -------------------------------------------------------------------------------- /src/godot/variant/TypedSignal.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.variant.Signal; 4 | 5 | @:forward @:transitive abstract TypedSignal(Signal) from Signal to Signal { 6 | inline public function new() { 7 | this = new Signal(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/godot/variant/Variant.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | 5 | @:allow(HxGodot) 6 | @:headerCode(" 7 | #include 8 | #include ") 9 | @:headerClassCode(' 10 | static constexpr size_t GODOT_CPP_VARIANT_SIZE = 24; 11 | uint8_t opaque[GODOT_CPP_VARIANT_SIZE] = {0}; 12 | _FORCE_INLINE_ ::GDExtensionVariantPtr _native_ptr() const { return const_cast(&opaque); } 13 | ') 14 | class __Variant { 15 | public static var from_type_constructor = new haxe.ds.Vector(GDExtensionVariantType.MAXIMUM); 16 | public static var to_type_constructor = new haxe.ds.Vector(GDExtensionVariantType.MAXIMUM); 17 | 18 | public function new() { 19 | //GodotNativeInterface.variant_new_nil(native_ptr()); // WTF!!!! 20 | } 21 | 22 | inline public function native_ptr():godot.Types.GDExtensionVariantPtr { 23 | return untyped __cpp__('{0}->_native_ptr()', this); 24 | } 25 | 26 | inline public function set_native_ptr(_ptr:godot.Types.GDExtensionVariantPtr):Void { 27 | untyped __cpp__('memcpy(&({0}->opaque[0]), {1}, 24)', this, _ptr); 28 | } 29 | 30 | public function getVariantType() { 31 | return GodotNativeInterface.variant_get_type(this.native_ptr()); 32 | } 33 | 34 | public static function destructVariant(_inst:Variant) { 35 | godot.Types.GodotNativeInterface.variant_destroy(_inst.native_ptr()); 36 | HxGodot.clearFinalizer(_inst); 37 | } 38 | 39 | static function __initBindings() { 40 | for (i in 1...GDExtensionVariantType.MAXIMUM) { 41 | from_type_constructor[i] = untyped __cpp__('(void *)godot::internal::gdextension_interface_get_variant_from_type_constructor((GDExtensionVariantType){0})', i); 42 | to_type_constructor[i] = untyped __cpp__('(void *)godot::internal::gdextension_interface_get_variant_to_type_constructor((GDExtensionVariantType){0})', i); 43 | } 44 | } 45 | 46 | public static function getGDExtensionVariantTypeString(_type:Int):String { 47 | return switch (_type) { 48 | case NIL: "Nil"; 49 | case BOOL: "bool"; 50 | case INT: "int"; 51 | case FLOAT: "float"; 52 | case AABB: "AABB"; 53 | case ARRAY: "GDArray"; 54 | case BASIS: "Basis"; 55 | case CALLABLE: "Callable"; 56 | case COLOR: "Color"; 57 | case DICTIONARY: "Dictionary"; 58 | case NODE_PATH: "NodePath"; 59 | case OBJECT: "Object"; 60 | case PACKED_BYTE_ARRAY: "PackedByteArray"; 61 | case PACKED_COLOR_ARRAY: "PackedColorArray"; 62 | case PACKED_FLOAT32_ARRAY: "PackedFloat32Array"; 63 | case PACKED_FLOAT64_ARRAY: "PackedFloat64Array"; 64 | case PACKED_INT32_ARRAY: "PackedInt32Array"; 65 | case PACKED_INT64_ARRAY: "PackedInt64Array"; 66 | case PACKED_STRING_ARRAY: "PackedStringArray"; 67 | case PACKED_VECTOR2_ARRAY: "PackedVector2Array"; 68 | case PACKED_VECTOR3_ARRAY: "PackedVector3Array"; 69 | case PLANE: "Plane"; 70 | case QUATERNION: "Quaternion"; 71 | case RECT2: "Rect2"; 72 | case RECT2I: "Rect2i"; 73 | case RID: "RID"; 74 | case SIGNAL: "Signal"; 75 | case STRING: "GDString"; 76 | case STRING_NAME: "StringName"; 77 | case TRANSFORM2D: "Transform2D"; 78 | case TRANSFORM3D: "Transform3D"; 79 | case VECTOR2: "Vector2"; 80 | case VECTOR2I: "Vector2i"; 81 | case VECTOR3: "Vector3"; 82 | case VECTOR3I: "Vector3i"; 83 | case VECTOR4: "Vector4"; 84 | case VECTOR4I: "Vector4i"; 85 | default: null; 86 | } 87 | } 88 | 89 | inline public static function _canConvert(_from:GDExtensionVariantType, _to:GDExtensionVariantType):Bool { 90 | return GodotNativeInterface.variant_can_convert_strict(_from, _to); 91 | } 92 | } 93 | 94 | @:forward 95 | @:build(godot.macros.VariantMacros.build()) 96 | abstract Variant(__Variant) from __Variant to __Variant { 97 | inline public function new() 98 | this = new __Variant(); 99 | 100 | inline private static function _buildVariant(_type:GDExtensionVariantType, _x:T):Variant { 101 | var res = new Variant(); 102 | var constructor = __Variant.from_type_constructor.get(_type); 103 | 104 | var value = _x; 105 | var tmp:VoidPtr = switch (_type) { // TODO: move this out of here and merge it with the ArgumentMacros for a central place to deal with the types 106 | case GDExtensionVariantType.VECTOR3: cast cpp.NativeArray.getBase(cast value).getBase(); 107 | default: cast cpp.RawPointer.addressOf(value); 108 | } 109 | 110 | untyped __cpp__(' 111 | ((GDExtensionVariantFromTypeConstructorFunc){0})({1}, {2}); 112 | ', 113 | (constructor:godot.Types.StarVoidPtr), 114 | res.native_ptr(), 115 | tmp 116 | ); 117 | HxGodot.setFinalizer(res, cpp.Callable.fromStaticFunction(__Variant.destructVariant)); 118 | return res; 119 | } 120 | 121 | @:noCompletion 122 | inline public static function _buildVariant2(_type:GDExtensionVariantType, _y:GDExtensionTypePtr):Variant { 123 | var res = new Variant(); 124 | var constructor = __Variant.from_type_constructor.get(_type); 125 | 126 | untyped __cpp__(' 127 | ((GDExtensionVariantFromTypeConstructorFunc){0})({1}, {2}); 128 | ', 129 | (constructor:godot.Types.StarVoidPtr), 130 | res.native_ptr(), 131 | _y 132 | ); 133 | HxGodot.setFinalizer(res, cpp.Callable.fromStaticFunction(__Variant.destructVariant)); 134 | return res; 135 | } 136 | 137 | @:noCompletion 138 | inline public static function _buildVariantObject(_type:GDExtensionVariantType, _y:GDExtensionTypePtr):Variant { 139 | var res = new Variant(); 140 | var constructor = __Variant.from_type_constructor.get(_type); 141 | untyped __cpp__(' 142 | ((GDExtensionVariantFromTypeConstructorFunc){0})({1}, {2}); 143 | ', 144 | (constructor:godot.Types.StarVoidPtr), 145 | res.native_ptr(), 146 | untyped __cpp__('&{0}', _y) 147 | ); 148 | HxGodot.setFinalizer(res, cpp.Callable.fromStaticFunction(__Variant.destructVariant)); 149 | return res; 150 | } 151 | } -------------------------------------------------------------------------------- /src/godot/variant/Vector2.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Vector2 = Array; 11 | 12 | private class __Vector2Defaults { 13 | public static final X:Vector2 = [1,0]; 14 | public static final Y:Vector2 = [0,1]; 15 | } 16 | 17 | @:forward 18 | abstract Vector2(__Vector2) from __Vector2 to __Vector2 { 19 | 20 | inline public static function RIGHT():Vector2 { 21 | return __Vector2Defaults.X; 22 | } 23 | 24 | inline public static function UP():Vector2 { 25 | return __Vector2Defaults.Y; 26 | } 27 | 28 | inline public function new(?_x:GDExtensionFloat=0, ?_y:GDExtensionFloat=0):Vector2 this = _alloc(_x, _y); 29 | 30 | inline private static function _alloc(_x:GDExtensionFloat, _y:GDExtensionFloat):__Vector2 31 | return [_x, _y]; 32 | 33 | inline public function native_ptr():GDExtensionTypePtr { 34 | #if !macro 35 | return cast cpp.NativeArray.getBase(this).getBase(); 36 | #else 37 | return 0; 38 | #end 39 | } 40 | 41 | public var x(get, set):GDExtensionFloat; 42 | inline function get_x() return this[0]; 43 | inline function set_x(_v:GDExtensionFloat) {this[0] = _v; return _v;} 44 | 45 | public var y(get, set):GDExtensionFloat; 46 | inline function get_y() return this[1]; 47 | inline function set_y(_v:GDExtensionFloat) {this[1] = _v; return _v;} 48 | 49 | @:arrayAccess 50 | inline public function get(_i:Int) return this[_i]; 51 | 52 | @:arrayAccess 53 | inline public function setAt(_i:Int, _v:GDExtensionFloat):Void 54 | this[_i] = _v; 55 | 56 | inline public function copy():Vector2 57 | return new Vector2(this[0], this[1]); 58 | 59 | public function min(p_vector2:Vector2):Vector2 { 60 | return new Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y)); 61 | } 62 | 63 | public function max(p_vector2:Vector2):Vector2 { 64 | return new Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y)); 65 | } 66 | 67 | public function abs():Vector2 { 68 | return new Vector2(Math.abs(x), Math.abs(y)); 69 | } 70 | 71 | public function orthogonal() { 72 | return new Vector2(y, -x); 73 | } 74 | 75 | public function aspect():Float { return x / y; } 76 | 77 | inline function plane_project(p_d:Float, p_vec:Vector2):Vector2 { 78 | return p_vec - copy() * (dot(p_vec) - p_d); 79 | } 80 | 81 | public function lerp(p_to:Vector2, p_weight:Float):Vector2 { 82 | var res:Vector2 = copy(); 83 | res.x = GDMath.lerp(res.x, p_to.x, p_weight); 84 | res.y = GDMath.lerp(res.y, p_to.y, p_weight); 85 | return res; 86 | } 87 | 88 | public function slerp(p_to:Vector2, p_weight:Float):Vector2 { 89 | var start_length_sq:Float = length_squared(); 90 | var end_length_sq:Float = p_to.length_squared(); 91 | if ((start_length_sq == 0.0 || end_length_sq == 0.0)) { 92 | // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. 93 | return lerp(p_to, p_weight); 94 | } 95 | var start_length:Float = Math.sqrt(start_length_sq); 96 | var result_length:Float = GDMath.lerp(start_length, Math.sqrt(end_length_sq), p_weight); 97 | var angle:Float = angle_to(p_to); 98 | return rotated(angle * p_weight) * (result_length / start_length); 99 | } 100 | 101 | public function cubic_interpolate(p_b:Vector2, p_pre_a:Vector2, p_post_b:Vector2, p_weight:Float):Vector2 { 102 | var res:Vector2 = copy(); 103 | res.x = GDMath.cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight); 104 | res.y = GDMath.cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight); 105 | return res; 106 | } 107 | 108 | public function cubic_interpolate_in_time(p_b:Vector2, p_pre_a:Vector2, p_post_b:Vector2, p_weight:Float, p_b_t:Float, p_pre_a_t:Float, p_post_b_t:Float):Vector2 { 109 | var res:Vector2 = copy(); 110 | res.x = GDMath.cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 111 | res.y = GDMath.cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 112 | return res; 113 | } 114 | 115 | public function bezier_interpolate(p_control_1:Vector2, p_control_2:Vector2, p_end:Vector2, p_t:Float):Vector2 { 116 | var res:Vector2 = copy(); 117 | res.x = GDMath.bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); 118 | res.y = GDMath.bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); 119 | return res; 120 | } 121 | 122 | public function bezier_derivative(p_control_1:Vector2, p_control_2:Vector2, p_end:Vector2, p_t:Float):Vector2 { 123 | var res:Vector2 = copy(); 124 | res.x = GDMath.bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); 125 | res.y = GDMath.bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); 126 | return res; 127 | } 128 | 129 | public function direction_to(p_to:Vector2):Vector2 { 130 | var ret:Vector2 = new Vector2(p_to.x - x, p_to.y - y); 131 | ret.normalize(); 132 | return ret; 133 | } 134 | 135 | public function angle():Float { 136 | return Math.atan2(y, x); 137 | } 138 | 139 | public function from_angle(p_angle:Float):Vector2 { 140 | return new Vector2(Math.cos(p_angle), Math.sin(p_angle)); 141 | } 142 | 143 | public function length():Float { 144 | return Math.sqrt(x * x + y * y); 145 | } 146 | 147 | public function length_squared():Float { 148 | return x * x + y * y; 149 | } 150 | 151 | public function normalize():Void { 152 | var l:Float = x * x + y * y; 153 | if (l != 0) { 154 | l = Math.sqrt(l); 155 | x /= l; 156 | y /= l; 157 | } 158 | } 159 | 160 | public function normalized():Vector2 { 161 | var v:Vector2 = copy(); 162 | v.normalize(); 163 | return v; 164 | } 165 | 166 | public function is_normalized():Bool { 167 | // use length_squared() instead of length() to apublic function sqrt():Void, makes it more stringent. 168 | return GDMath.is_equal_approx(length_squared(), 1, UNIT_EPSILON); 169 | } 170 | 171 | public function distance_to(p_vector2:Vector2):Float { 172 | return Math.sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y)); 173 | } 174 | 175 | public function distance_squared_to(p_vector2:Vector2):Float { 176 | return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y); 177 | } 178 | 179 | public function angle_to(p_vector2:Vector2):Float { 180 | return Math.atan2(cross(p_vector2), dot(p_vector2)); 181 | } 182 | 183 | public function angle_to_point(p_vector2:Vector2):Float { 184 | return (p_vector2 - this).angle(); 185 | } 186 | 187 | public function dot(p_other:Vector2):Float { 188 | return x * p_other.x + y * p_other.y; 189 | } 190 | 191 | public function cross(p_other:Vector2):Float { 192 | return x * p_other.y - y * p_other.x; 193 | } 194 | 195 | public function sign():Vector2 { 196 | return new Vector2(SIGN(x), SIGN(y)); 197 | } 198 | 199 | public function floor():Vector2 { 200 | return new Vector2(Math.floor(x), Math.floor(y)); 201 | } 202 | 203 | public function ceil():Vector2 { 204 | return new Vector2(Math.ceil(x), Math.ceil(y)); 205 | } 206 | 207 | public function round():Vector2 { 208 | return new Vector2(Math.round(x), Math.round(y)); 209 | } 210 | 211 | public function rotated(p_by:Float):Vector2 { 212 | var sine:Float = Math.sin(p_by); 213 | var cosi:Float = Math.cos(p_by); 214 | return new Vector2( 215 | x * cosi - y * sine, 216 | x * sine + y * cosi); 217 | } 218 | 219 | public function posmod(p_mod:Float):Vector2 { 220 | return new Vector2(GDMath.fposmod(x, p_mod), GDMath.fposmod(y, p_mod)); 221 | } 222 | 223 | public function posmodv(p_modv:Vector2):Vector2 { 224 | return new Vector2(GDMath.fposmod(x, p_modv.x), GDMath.fposmod(y, p_modv.y)); 225 | } 226 | 227 | public function project(p_to:Vector2):Vector2 { 228 | return p_to * (dot(p_to) / p_to.length_squared()); 229 | } 230 | 231 | public function clamp(p_min:Vector2, p_max:Vector2):Vector2 { 232 | return new Vector2( 233 | CLAMP(x, p_min.x, p_max.x), 234 | CLAMP(y, p_min.y, p_max.y)); 235 | } 236 | 237 | public function snapped(p_step:Vector2):Vector2 { 238 | return new Vector2( 239 | GDMath.snapped(x, p_step.x), 240 | GDMath.snapped(y, p_step.y)); 241 | } 242 | 243 | public function limit_length(p_len:Float):Vector2 { 244 | var l:Float = length(); 245 | var v:Vector2 = copy(); 246 | if (l > 0 && p_len < l) { 247 | v /= l; 248 | v *= p_len; 249 | } 250 | 251 | return v; 252 | } 253 | 254 | public function move_toward(p_to:Vector2, p_delta:Float):Vector2 { 255 | var v:Vector2 = this; 256 | var vd:Vector2 = p_to - v; 257 | var len:Float = vd.length(); 258 | return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; 259 | } 260 | 261 | // slide returns the component of the vector along the given plane, specified by its normal vector. 262 | public function slide(p_normal:Vector2):Vector2 { 263 | #if MATH_CHECKS 264 | ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 must be normalized."); 265 | #end 266 | return this - p_normal * dot(p_normal); 267 | } 268 | 269 | public function bounce(p_normal:Vector2):Vector2 { 270 | return -reflect(p_normal); 271 | } 272 | 273 | public function reflect(p_normal:Vector2):Vector2 { 274 | #if MATH_CHECKS 275 | ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 must be normalized."); 276 | #end 277 | return p_normal * 2.0 * dot(p_normal) - this; 278 | } 279 | 280 | public function is_equal_approx(p_v:Vector2):Bool { 281 | return GDMath.is_equal_approx(x, p_v.x) && GDMath.is_equal_approx(y, p_v.y); 282 | } 283 | 284 | public function is_zero_approx():Bool { 285 | return GDMath.is_zero_approx(x) && GDMath.is_zero_approx(y); 286 | } 287 | 288 | public function is_finite():Bool { 289 | return GDMath.is_finite(x) && GDMath.is_finite(y); 290 | } 291 | 292 | @:to public function toString() { 293 | return "(" + x + ", " + y + ")"; 294 | } 295 | 296 | @:op(A == B) 297 | inline public static function eq(lhs:Vector2, rhs:Vector2):Bool { 298 | return lhs[0] == rhs[0] && lhs[1] == rhs[1]; 299 | } 300 | 301 | @:op(A != B) 302 | inline public static function neq(lhs:Vector2, rhs:Vector2):Bool { 303 | return lhs[0] != rhs[0] || lhs[1] != rhs[1]; 304 | } 305 | 306 | @:op(A * B) 307 | inline public static function mult(lhs:Vector2, rhs:Vector2):Vector2 { 308 | var res = new Vector2(); 309 | res[0] = lhs[0] * rhs[0]; 310 | res[1] = lhs[1] * rhs[1]; 311 | return res; 312 | } 313 | 314 | @:op(A *= B) 315 | inline public static function multIn(lhs:Vector2, rhs:Vector2):Vector2 { 316 | lhs[0] *= rhs[0]; 317 | lhs[1] *= rhs[1]; 318 | return lhs; 319 | } 320 | 321 | @:op(A / B) 322 | inline public static function divide(lhs:Vector2, rhs:Vector2):Vector2 { 323 | var res = new Vector2(); 324 | res[0] = lhs[0] / rhs[0]; 325 | res[1] = lhs[1] / rhs[1]; 326 | return res; 327 | } 328 | 329 | @:op(A /= B) 330 | inline public static function divideIn(lhs:Vector2, rhs:Vector2):Vector2 { 331 | lhs[0] /= rhs[0]; 332 | lhs[1] /= rhs[1]; 333 | return lhs; 334 | } 335 | 336 | @:op(A * B) 337 | inline public static function multScalar(lhs:Vector2, scalar:GDExtensionFloat):Vector2 { 338 | var res = new Vector2(); 339 | res[0] = lhs[0] * scalar; 340 | res[1] = lhs[1] * scalar; 341 | return res; 342 | } 343 | 344 | @:op(A *= B) 345 | inline public static function multInScalar(lhs:Vector2, scalar:GDExtensionFloat):Vector2 { 346 | lhs[0] *= scalar; 347 | lhs[1] *= scalar; 348 | return lhs; 349 | } 350 | 351 | @:op(A / B) 352 | inline public static function divideScalar(lhs:Vector2, scalar:GDExtensionFloat):Vector2 { 353 | var res = new Vector2(); 354 | res[0] = lhs[0] / scalar; 355 | res[1] = lhs[1] / scalar; 356 | return res; 357 | } 358 | 359 | @:op(A /= B) 360 | inline public static function divideInScalar(lhs:Vector2, scalar:GDExtensionFloat):Vector2 { 361 | lhs[0] /= scalar; 362 | lhs[1] /= scalar; 363 | return lhs; 364 | } 365 | 366 | @:op(A + B) 367 | inline public static function add(lhs:Vector2, rhs:Vector2):Vector2 { 368 | var res = new Vector2(); 369 | res[0] = lhs[0] + rhs[0]; 370 | res[1] = lhs[1] + rhs[1]; 371 | return res; 372 | } 373 | 374 | @:op(A += B) 375 | inline public static function addIn(lhs:Vector2, rhs:Vector2):Vector2 { 376 | lhs[0] += rhs[0]; 377 | lhs[1] += rhs[1]; 378 | return lhs; 379 | } 380 | 381 | @:op(A - B) 382 | inline public static function subtract(lhs:Vector2, rhs:Vector2):Vector2 { 383 | var res = new Vector2(); 384 | res[0] = lhs[0] - rhs[0]; 385 | res[1] = lhs[1] - rhs[1]; 386 | return res; 387 | } 388 | 389 | @:op(A -= B) 390 | inline public static function subtractIn(lhs:Vector2, rhs:Vector2):Vector2 { 391 | lhs[0] -= rhs[0]; 392 | lhs[1] -= rhs[1]; 393 | return lhs; 394 | } 395 | 396 | @:op(-A) 397 | inline public static function negate(lhs:Vector2):Vector2 { 398 | var res = new Vector2(); 399 | res[0] = -lhs[0]; 400 | res[1] = -lhs[1]; 401 | return res; 402 | } 403 | 404 | 405 | } -------------------------------------------------------------------------------- /src/godot/variant/Vector2i.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Vector2i = Array; 11 | 12 | @:forward 13 | abstract Vector2i(__Vector2i) from __Vector2i to __Vector2i { 14 | inline public function new(?_x:Int=0, ?_y:Int=0):Vector2i this = _alloc(_x, _y); 15 | 16 | inline private static function _alloc(_x:Int, _y:Int):__Vector2i 17 | return [_x, _y]; 18 | 19 | inline public function native_ptr():GDExtensionTypePtr { 20 | #if !macro 21 | return cast cpp.NativeArray.getBase(this).getBase(); 22 | #else 23 | return 0; 24 | #end 25 | } 26 | 27 | public var x(get, set):Int; 28 | inline function get_x() return this[0]; 29 | inline function set_x(_v:Int) {this[0] = _v; return _v;} 30 | 31 | public var y(get, set):Int; 32 | inline function get_y() return this[1]; 33 | inline function set_y(_v:Int) {this[1] = _v; return _v;} 34 | 35 | @:arrayAccess 36 | inline public function get(_i:Int) return this[_i]; 37 | 38 | @:arrayAccess 39 | inline public function setAt(_i:Int, _v:Int):Void 40 | this[_i] = _v; 41 | 42 | inline public function copy():Vector2i 43 | return new Vector2i(this[0], this[1]); 44 | 45 | public function min(p_vector2i:Vector2i):Vector2i { 46 | return new Vector2i(Std.int(MIN(x, p_vector2i.x)), Std.int(MIN(y, p_vector2i.y))); 47 | } 48 | 49 | public function max(p_vector2i:Vector2i):Vector2i { 50 | return new Vector2i(Std.int(MAX(x, p_vector2i.x)), Std.int(MAX(y, p_vector2i.y))); 51 | } 52 | 53 | public function aspect():Float { return x / y; } 54 | public function sign():Vector2i { return new Vector2i(Std.int(SIGN(x)), Std.int(SIGN(y))); } 55 | public function abs():Vector2i { return new Vector2i(Std.int(Math.abs(x)), Std.int(Math.abs(y))); } 56 | 57 | public function clamp(p_min:Vector2i, p_max:Vector2i):Vector2i { 58 | return new Vector2i( 59 | Std.int(CLAMP(x, p_min.x, p_max.x)), 60 | Std.int(CLAMP(y, p_min.y, p_max.y))); 61 | } 62 | 63 | public function snapped(p_step:Vector2i):Vector2i { 64 | return new Vector2i( 65 | Std.int(GDMath.snapped(x, p_step.x)), 66 | Std.int(GDMath.snapped(y, p_step.y))); 67 | } 68 | 69 | public function length_squared():haxe.Int64 { 70 | return x * x + y * y; 71 | } 72 | 73 | public function length():Float { 74 | return Math.sqrt( cast length_squared() ); 75 | } 76 | 77 | @:to public function toString():String { 78 | return "(" + x + ", " + y + ")"; 79 | } 80 | 81 | @:op(A == B) 82 | inline public static function eq(lhs:Vector2i, rhs:Vector2i):Bool { 83 | return lhs[0] == rhs[0] && lhs[1] == rhs[1]; 84 | } 85 | 86 | @:op(A != B) 87 | inline public static function neq(lhs:Vector2i, rhs:Vector2i):Bool { 88 | return lhs[0] != rhs[0] || lhs[1] != rhs[1]; 89 | } 90 | 91 | @:op(A * B) 92 | inline public static function mult(lhs:Vector2i, rhs:Vector2i):Vector2i { 93 | var res = new Vector2i(); 94 | res[0] = lhs[0] * rhs[0]; 95 | res[1] = lhs[1] * rhs[1]; 96 | return res; 97 | } 98 | 99 | @:op(A *= B) 100 | inline public static function multIn(lhs:Vector2i, rhs:Vector2i):Vector2i { 101 | lhs[0] *= rhs[0]; 102 | lhs[1] *= rhs[1]; 103 | return lhs; 104 | } 105 | 106 | @:op(A / B) 107 | inline public static function divide(lhs:Vector2i, rhs:Vector2i):Vector2i { 108 | var res = new Vector2i(); 109 | res[0] = Std.int(lhs[0] / rhs[0]); 110 | res[1] = Std.int(lhs[1] / rhs[1]); 111 | return res; 112 | } 113 | 114 | @:op(A /= B) 115 | inline public static function divideIn(lhs:Vector2i, rhs:Vector2i):Vector2i { 116 | lhs[0] = Std.int(lhs[0] / rhs[0]); 117 | lhs[1] = Std.int(lhs[1] / rhs[1]); 118 | return lhs; 119 | } 120 | 121 | @:op(A * B) 122 | inline public static function multScalar(lhs:Vector2i, scalar:GDExtensionFloat):Vector2i { 123 | var res = new Vector2i(); 124 | res[0] = Std.int(lhs[0] / lhs[0] * scalar); 125 | res[1] = Std.int(lhs[0] / lhs[1] * scalar); 126 | return res; 127 | } 128 | 129 | @:op(A *= B) 130 | inline public static function multInScalar(lhs:Vector2i, scalar:GDExtensionFloat):Vector2i { 131 | lhs[0] = Std.int(lhs[0] / lhs[0] * scalar); 132 | lhs[1] = Std.int(lhs[0] / lhs[1] * scalar); 133 | return lhs; 134 | } 135 | 136 | @:op(A / B) 137 | inline public static function divideScalar(lhs:Vector2i, scalar:GDExtensionFloat):Vector2i { 138 | var res = new Vector2i(); 139 | res[0] = Std.int(lhs[0] / scalar); 140 | res[1] = Std.int(lhs[1] / scalar); 141 | return res; 142 | } 143 | 144 | @:op(A /= B) 145 | inline public static function divideInScalar(lhs:Vector2i, scalar:GDExtensionFloat):Vector2i { 146 | lhs[0] = Std.int(lhs[0] / scalar); 147 | lhs[1] = Std.int(lhs[1] / scalar); 148 | return lhs; 149 | } 150 | 151 | @:op(A + B) 152 | inline public static function add(lhs:Vector2i, rhs:Vector2i):Vector2i { 153 | var res = new Vector2i(); 154 | res[0] = lhs[0] + rhs[0]; 155 | res[1] = lhs[1] + rhs[1]; 156 | return res; 157 | } 158 | 159 | @:op(A += B) 160 | inline public static function addIn(lhs:Vector2i, rhs:Vector2i):Vector2i { 161 | lhs[0] += rhs[0]; 162 | lhs[1] += rhs[1]; 163 | return lhs; 164 | } 165 | 166 | @:op(A - B) 167 | inline public static function subtract(lhs:Vector2i, rhs:Vector2i):Vector2i { 168 | var res = new Vector2i(); 169 | res[0] = lhs[0] - rhs[0]; 170 | res[1] = lhs[1] - rhs[1]; 171 | return res; 172 | } 173 | 174 | @:op(A -= B) 175 | inline public static function subtractIn(lhs:Vector2i, rhs:Vector2i):Vector2i { 176 | lhs[0] -= rhs[0]; 177 | lhs[1] -= rhs[1]; 178 | return lhs; 179 | } 180 | 181 | @:op(-A) 182 | inline public static function negate(lhs:Vector2i):Vector2i { 183 | var res = new Vector2i(); 184 | res[0] = -lhs[0]; 185 | res[1] = -lhs[1]; 186 | return res; 187 | } 188 | 189 | @:op(A < B) 190 | inline public static function lt(lhs:Vector2i, rhs:Vector2i) { 191 | return (lhs.x == rhs.x) ? (lhs.y < rhs.y) : (lhs.x < rhs.x); 192 | } 193 | @:op(A > B) 194 | inline public static function gt(lhs:Vector2i, rhs:Vector2i) { 195 | return (lhs.x == rhs.x) ? (lhs.y > rhs.y) : (lhs.x > rhs.x); 196 | } 197 | 198 | @:op(A <= B) 199 | inline public static function ltequals(lhs:Vector2i, rhs:Vector2i) { 200 | return lhs.x == rhs.x ? (lhs.y <= rhs.y) : (lhs.x < rhs.x); 201 | } 202 | @:op(A >= B) 203 | inline public static function gtequals(lhs:Vector2i, rhs:Vector2i) { 204 | return lhs.x == rhs.x ? (lhs.y >= rhs.y) : (lhs.x > rhs.x); 205 | } 206 | 207 | } -------------------------------------------------------------------------------- /src/godot/variant/Vector3i.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Vector3i = Array; 11 | 12 | @:forward 13 | abstract Vector3i(__Vector3i) from __Vector3i to __Vector3i { 14 | 15 | inline public function new(?_x:Int=0, ?_y:Int=0, ?_z:Int=0):Vector3i this = _alloc(_x, _y, _z); 16 | 17 | inline private static function _alloc(_x:Int, _y:Int, _z:Int):__Vector3i 18 | return [_x, _y, _z]; 19 | 20 | inline public function native_ptr():GDExtensionTypePtr { 21 | #if !macro 22 | return cast cpp.NativeArray.getBase(this).getBase(); 23 | #else 24 | return 0; 25 | #end 26 | } 27 | 28 | public var x(get, set):Int; 29 | inline function get_x() return this[0]; 30 | inline function set_x(_v:Int) {this[0] = _v; return _v;} 31 | 32 | public var y(get, set):Int; 33 | inline function get_y() return this[1]; 34 | inline function set_y(_v:Int) {this[1] = _v; return _v;} 35 | 36 | public var z(get, set):Int; 37 | inline function get_z() return this[2]; 38 | inline function set_z(_v:Int) {this[2] = _v; return _v;} 39 | 40 | @:arrayAccess 41 | inline public function get(_i:Int) return this[_i]; 42 | 43 | @:arrayAccess 44 | inline public function setAt(_i:Int, _v:Int):Void 45 | this[_i] = _v; 46 | 47 | inline public function copy():Vector3i 48 | return new Vector3i(this[0], this[1], this[2]); 49 | 50 | public function length_squared():haxe.Int64 { 51 | return x * x + y * y + z * z; 52 | } 53 | 54 | public function length():Float { 55 | return Math.sqrt(cast length_squared()); 56 | } 57 | 58 | public function abs():Vector3i { 59 | return new Vector3i(Std.int(Math.abs(x)), Std.int(Math.abs(y)), Std.int(Math.abs(z))); 60 | } 61 | 62 | public function sign():Vector3i { 63 | return new Vector3i(Std.int(SIGN(x)), Std.int(SIGN(y)), Std.int(SIGN(z))); 64 | } 65 | 66 | public function zero():Void { 67 | x = y = z = 0; 68 | } 69 | 70 | public function clamp(p_min:Vector3i, p_max:Vector3i):Vector3i { 71 | return new Vector3i( 72 | Std.int(CLAMP(x, p_min.x, p_max.x)), 73 | Std.int(CLAMP(y, p_min.y, p_max.y)), 74 | Std.int(CLAMP(z, p_min.z, p_max.z))); 75 | } 76 | 77 | public function snapped(p_step:Vector3i):Vector3i { 78 | return new Vector3i( 79 | Std.int(GDMath.snapped(x, p_step.x)), 80 | Std.int(GDMath.snapped(y, p_step.y)), 81 | Std.int(GDMath.snapped(z, p_step.z))); 82 | } 83 | 84 | @:to public function toString() { 85 | return "(" + x+ ", " + y + ", " + z + ")"; 86 | } 87 | 88 | @:op(A == B) 89 | inline public static function eq(lhs:Vector3i, rhs:Vector3i):Bool { 90 | return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]; 91 | } 92 | 93 | @:op(A != B) 94 | inline public static function neq(lhs:Vector3i, rhs:Vector3i):Bool { 95 | return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2]; 96 | } 97 | 98 | @:op(A * B) 99 | inline public static function mult(lhs:Vector3i, rhs:Vector3i):Vector3i { 100 | var res = new Vector3i(); 101 | res[0] = lhs[0] * rhs[0]; 102 | res[1] = lhs[1] * rhs[1]; 103 | res[2] = lhs[2] * rhs[2]; 104 | return res; 105 | } 106 | 107 | @:op(A *= B) 108 | inline public static function multIn(lhs:Vector3i, rhs:Vector3i):Vector3i { 109 | lhs[0] *= rhs[0]; 110 | lhs[1] *= rhs[1]; 111 | lhs[2] *= rhs[2]; 112 | return lhs; 113 | } 114 | 115 | @:op(A / B) 116 | inline public static function divide(lhs:Vector3i, rhs:Vector3i):Vector3i { 117 | var res = new Vector3i(); 118 | res[0] = Std.int(lhs[0] / rhs[0]); 119 | res[1] = Std.int(lhs[1] / rhs[1]); 120 | res[2] = Std.int(lhs[2] / rhs[2]); 121 | return res; 122 | } 123 | 124 | @:op(A /= B) 125 | inline public static function divideIn(lhs:Vector3i, rhs:Vector3i):Vector3i { 126 | lhs[0] = Std.int(lhs[0] / rhs[0]); 127 | lhs[1] = Std.int(lhs[1] / rhs[1]); 128 | lhs[2] = Std.int(lhs[2] / rhs[2]); 129 | return lhs; 130 | } 131 | 132 | @:op(A * B) 133 | inline public static function multScalar(lhs:Vector3i, scalar:GDExtensionFloat):Vector3i { 134 | var res = new Vector3i(); 135 | res[0] = Std.int(lhs[0] * scalar); 136 | res[1] = Std.int(lhs[1] * scalar); 137 | res[2] = Std.int(lhs[2] * scalar); 138 | return res; 139 | } 140 | 141 | @:op(A *= B) 142 | inline public static function multInScalar(lhs:Vector3i, scalar:GDExtensionFloat):Vector3i { 143 | lhs[0] = Std.int(lhs[0] * scalar); 144 | lhs[1] = Std.int(lhs[1] * scalar); 145 | lhs[2] = Std.int(lhs[2] * scalar); 146 | return lhs; 147 | } 148 | 149 | @:op(A / B) 150 | inline public static function divideScalar(lhs:Vector3i, scalar:GDExtensionFloat):Vector3i { 151 | var res = new Vector3i(); 152 | res[0] = Std.int(lhs[0] / scalar); 153 | res[1] = Std.int(lhs[1] / scalar); 154 | res[2] = Std.int(lhs[2] / scalar); 155 | return res; 156 | } 157 | 158 | @:op(A /= B) 159 | inline public static function divideInScalar(lhs:Vector3i, scalar:GDExtensionFloat):Vector3i { 160 | lhs[0] = Std.int(lhs[0] / scalar); 161 | lhs[1] = Std.int(lhs[1] / scalar); 162 | lhs[2] = Std.int(lhs[2] / scalar); 163 | return lhs; 164 | } 165 | 166 | @:op(A + B) 167 | inline public static function add(lhs:Vector3i, rhs:Vector3i):Vector3i { 168 | var res = new Vector3i(); 169 | res[0] = lhs[0] + rhs[0]; 170 | res[1] = lhs[1] + rhs[1]; 171 | res[2] = lhs[2] + rhs[2]; 172 | return res; 173 | } 174 | 175 | @:op(A += B) 176 | inline public static function addIn(lhs:Vector3i, rhs:Vector3i):Vector3i { 177 | lhs[0] += rhs[0]; 178 | lhs[1] += rhs[1]; 179 | lhs[2] += rhs[2]; 180 | return lhs; 181 | } 182 | 183 | @:op(A - B) 184 | inline public static function subtract(lhs:Vector3i, rhs:Vector3i):Vector3i { 185 | var res = new Vector3i(); 186 | res[0] = lhs[0] - rhs[0]; 187 | res[1] = lhs[1] - rhs[1]; 188 | res[2] = lhs[2] - rhs[2]; 189 | return res; 190 | } 191 | 192 | @:op(A -= B) 193 | inline public static function subtractIn(lhs:Vector3i, rhs:Vector3i):Vector3i { 194 | lhs[0] -= rhs[0]; 195 | lhs[1] -= rhs[1]; 196 | lhs[2] -= rhs[2]; 197 | return lhs; 198 | } 199 | 200 | @:op(-A) 201 | inline public static function negate(lhs:Vector3i):Vector3i { 202 | var res = new Vector3i(); 203 | res[0] = -lhs[0]; 204 | res[1] = -lhs[1]; 205 | res[2] = -lhs[2]; 206 | return res; 207 | } 208 | 209 | @:op(A < B) 210 | inline public static function lt(lhs:Vector3i, rhs:Vector3i) { 211 | if (lhs.x == rhs.x) { 212 | if (lhs.y == rhs.y) { 213 | return lhs.z < rhs.z; 214 | } else { 215 | return lhs.y < rhs.y; 216 | } 217 | } else { 218 | return lhs.x < rhs.x; 219 | } 220 | } 221 | 222 | @:op(A > B) 223 | inline public static function gt(lhs:Vector3i, rhs:Vector3i) { 224 | if (lhs.x == rhs.x) { 225 | if (lhs.y == rhs.y) { 226 | return lhs.z > rhs.z; 227 | } else { 228 | return lhs.y > rhs.y; 229 | } 230 | } else { 231 | return lhs.x > rhs.x; 232 | } 233 | } 234 | 235 | @:op(A <= B) 236 | inline public static function ltequals(lhs:Vector3i, rhs:Vector3i) { 237 | if (lhs.x == rhs.x) { 238 | if (lhs.y == rhs.y) { 239 | return lhs.z <= rhs.z; 240 | } else { 241 | return lhs.y < rhs.y; 242 | } 243 | } else { 244 | return lhs.x < rhs.x; 245 | } 246 | } 247 | 248 | @:op(A >= B) 249 | inline public static function gtequals(lhs:Vector3i, rhs:Vector3i) { 250 | if (lhs.x == rhs.x) { 251 | if (lhs.y == rhs.y) { 252 | return lhs.z >= rhs.z; 253 | } else { 254 | return lhs.y > rhs.y; 255 | } 256 | } else { 257 | return lhs.x > rhs.x; 258 | } 259 | } 260 | 261 | } -------------------------------------------------------------------------------- /src/godot/variant/Vector4.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Vector4 = Array; 11 | 12 | private class __Vector4Defaults { 13 | public static final ZERO:Vector4 = [0,0,0,0]; 14 | public static final ONE:Vector4 = [1,1,1,1]; 15 | } 16 | 17 | @:forward 18 | abstract Vector4(__Vector4) from __Vector4 to __Vector4 { 19 | 20 | inline public static var AXIS_X:Int = 0; 21 | inline public static var AXIS_Y:Int = 0; 22 | inline public static var AXIS_Z:Int = 0; 23 | inline public static var AXIS_W:Int = 0; 24 | 25 | inline public static function ZERO():Vector4 { 26 | return __Vector4Defaults.ZERO; 27 | } 28 | 29 | inline public static function ONE():Vector4 { 30 | return __Vector4Defaults.ONE; 31 | } 32 | 33 | inline public function new(?_x:GDExtensionFloat=0, ?_y:GDExtensionFloat=0, ?_z:GDExtensionFloat=0, ?_w:GDExtensionFloat=0):Vector4 this = _alloc(_x, _y, _z, _w); 34 | 35 | inline private static function _alloc(_x:GDExtensionFloat, _y:GDExtensionFloat, _z:GDExtensionFloat, _w:GDExtensionFloat):__Vector4 36 | return [_x, _y, _z, _w]; 37 | 38 | inline public function native_ptr():GDExtensionTypePtr { 39 | #if !macro 40 | return cast cpp.NativeArray.getBase(this).getBase(); 41 | #else 42 | return 0; 43 | #end 44 | } 45 | 46 | public var x(get, set):GDExtensionFloat; 47 | inline function get_x() return this[0]; 48 | inline function set_x(_v:GDExtensionFloat) {this[0] = _v; return _v;} 49 | 50 | public var y(get, set):GDExtensionFloat; 51 | inline function get_y() return this[1]; 52 | inline function set_y(_v:GDExtensionFloat) {this[1] = _v; return _v;} 53 | 54 | public var z(get, set):GDExtensionFloat; 55 | inline function get_z() return this[2]; 56 | inline function set_z(_v:GDExtensionFloat) {this[2] = _v; return _v;} 57 | 58 | public var w(get, set):GDExtensionFloat; 59 | inline function get_w() return this[3]; 60 | inline function set_w(_v:GDExtensionFloat) {this[3] = _v; return _v;} 61 | 62 | @:arrayAccess 63 | inline public function get(_i:Int) return this[_i]; 64 | 65 | @:arrayAccess 66 | inline public function setAt(_i:Int, _v:GDExtensionFloat):Void 67 | this[_i] = _v; 68 | 69 | inline public function copy():Vector4 70 | return new Vector4(this[0], this[1], this[2], this[3]); 71 | 72 | public function dot(p_vec4:Vector4):Float { 73 | return x * p_vec4.x + y * p_vec4.y + z * p_vec4.z + w * p_vec4.w; 74 | } 75 | 76 | public function length_squared():Float { 77 | return dot(this); 78 | } 79 | 80 | public function is_equal_approx(p_vec4:Vector4):Bool { 81 | return GDMath.is_equal_approx(x, p_vec4.x) && GDMath.is_equal_approx(y, p_vec4.y) && GDMath.is_equal_approx(z, p_vec4.z) && GDMath.is_equal_approx(w, p_vec4.w); 82 | } 83 | 84 | public function is_zero_approx():Bool { 85 | return GDMath.is_zero_approx(x) && GDMath.is_zero_approx(y) && GDMath.is_zero_approx(z) && GDMath.is_zero_approx(w); 86 | } 87 | 88 | public function is_finite():Bool { 89 | return GDMath.is_finite(x) && GDMath.is_finite(y) && GDMath.is_finite(z) && GDMath.is_finite(w); 90 | } 91 | 92 | public function length():Float { 93 | return Math.sqrt(length_squared()); 94 | } 95 | 96 | public function normalize():Void { 97 | var lengthsq:Float = length_squared(); 98 | if (lengthsq == 0) { 99 | x = y = z = w = 0; 100 | } else { 101 | var length:Float = Math.sqrt(lengthsq); 102 | x /= length; 103 | y /= length; 104 | z /= length; 105 | w /= length; 106 | } 107 | } 108 | 109 | public function normalized():Vector4 { 110 | var v:Vector4 = copy(); 111 | v.normalize(); 112 | return v; 113 | } 114 | 115 | public function is_normalized():Bool { 116 | return GDMath.is_equal_approx(length_squared(), 1, UNIT_EPSILON); 117 | } 118 | 119 | public function distance_to(p_to:Vector4):Float { 120 | return (p_to - this).length(); 121 | } 122 | 123 | public function distance_squared_to(p_to:Vector4):Float { 124 | return (p_to - this).length_squared(); 125 | } 126 | 127 | public function direction_to(p_to:Vector4):Vector4 { 128 | var ret:Vector4 = new Vector4(p_to.x - x, p_to.y - y, p_to.z - z, p_to.w - w); 129 | ret.normalize(); 130 | return ret; 131 | } 132 | 133 | public function abs():Vector4 { 134 | return new Vector4(Math.abs(x), Math.abs(y), Math.abs(z), Math.abs(w)); 135 | } 136 | 137 | public function sign():Vector4 { 138 | return new Vector4(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); 139 | } 140 | 141 | public function floor():Vector4 { 142 | return new Vector4(Math.floor(x), Math.floor(y), Math.floor(z), Math.floor(w)); 143 | } 144 | 145 | public function ceil():Vector4 { 146 | return new Vector4(Math.ceil(x), Math.ceil(y), Math.ceil(z), Math.ceil(w)); 147 | } 148 | 149 | public function round():Vector4 { 150 | return new Vector4(Math.round(x), Math.round(y), Math.round(z), Math.round(w)); 151 | } 152 | 153 | public function lerp(p_to:Vector4, p_weight:Float):Vector4 { 154 | var res:Vector4 = copy(); 155 | res.x = GDMath.lerp(res.x, p_to.x, p_weight); 156 | res.y = GDMath.lerp(res.y, p_to.y, p_weight); 157 | res.z = GDMath.lerp(res.z, p_to.z, p_weight); 158 | res.w = GDMath.lerp(res.w, p_to.w, p_weight); 159 | return res; 160 | } 161 | 162 | public function cubic_interpolate(p_b:Vector4, p_pre_a:Vector4, p_post_b:Vector4, p_weight:Float):Vector4 { 163 | var res:Vector4 = copy(); 164 | res.x = GDMath.cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight); 165 | res.y = GDMath.cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight); 166 | res.z = GDMath.cubic_interpolate(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight); 167 | res.w = GDMath.cubic_interpolate(res.w, p_b.w, p_pre_a.w, p_post_b.w, p_weight); 168 | return res; 169 | } 170 | 171 | public function cubic_interpolate_in_time(p_b:Vector4, p_pre_a:Vector4, p_post_b:Vector4, p_weight:Float, p_b_t:Float, p_pre_a_t:Float, p_post_b_t:Float):Vector4 { 172 | var res:Vector4 = copy(); 173 | res.x = GDMath.cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 174 | res.y = GDMath.cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 175 | res.z = GDMath.cubic_interpolate_in_time(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 176 | res.w = GDMath.cubic_interpolate_in_time(res.w, p_b.w, p_pre_a.w, p_post_b.w, p_weight, p_b_t, p_pre_a_t, p_post_b_t); 177 | return res; 178 | } 179 | 180 | public function posmod(p_mod:Float):Vector4 { 181 | return new Vector4(GDMath.fposmod(x, p_mod), GDMath.fposmod(y, p_mod), GDMath.fposmod(z, p_mod), GDMath.fposmod(w, p_mod)); 182 | } 183 | 184 | public function posmodv(p_modv:Vector4):Vector4 { 185 | return new Vector4(GDMath.fposmod(x, p_modv.x), GDMath.fposmod(y, p_modv.y), GDMath.fposmod(z, p_modv.z), GDMath.fposmod(w, p_modv.w)); 186 | } 187 | 188 | public function snap(p_step:Vector4):Void { 189 | x = GDMath.snapped(x, p_step.x); 190 | y = GDMath.snapped(y, p_step.y); 191 | z = GDMath.snapped(z, p_step.z); 192 | w = GDMath.snapped(w, p_step.w); 193 | } 194 | 195 | public function snapped(p_step:Vector4):Vector4 { 196 | var v:Vector4 = copy(); 197 | v.snap(p_step); 198 | return v; 199 | } 200 | 201 | public function inverse():Vector4 { 202 | return new Vector4(1.0 / x, 1.0 / y, 1.0 / z, 1.0 / w); 203 | } 204 | 205 | public function clamp(p_min:Vector4, p_max:Vector4):Vector4 { 206 | return new Vector4( 207 | CLAMP(x, p_min.x, p_max.x), 208 | CLAMP(y, p_min.y, p_max.y), 209 | CLAMP(z, p_min.z, p_max.z), 210 | CLAMP(w, p_min.w, p_max.w)); 211 | } 212 | 213 | @:to public function toString() { 214 | return "(" + x + ", " + y + ", " + z + ", " + w + ")"; 215 | } 216 | 217 | 218 | @:op(A == B) 219 | inline public static function eq(lhs:Vector4, rhs:Vector4):Bool { 220 | return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3]; 221 | } 222 | 223 | @:op(A != B) 224 | inline public static function neq(lhs:Vector4, rhs:Vector4):Bool { 225 | return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3]; 226 | } 227 | 228 | @:op(A * B) 229 | inline public static function mult(lhs:Vector4, rhs:Vector4):Vector4 { 230 | var res = new Vector4(); 231 | res[0] = lhs[0] * rhs[0]; 232 | res[1] = lhs[1] * rhs[1]; 233 | res[2] = lhs[2] * rhs[2]; 234 | res[3] = lhs[3] * rhs[3]; 235 | return res; 236 | } 237 | 238 | @:op(A *= B) 239 | inline public static function multIn(lhs:Vector4, rhs:Vector4):Vector4 { 240 | lhs[0] *= rhs[0]; 241 | lhs[1] *= rhs[1]; 242 | lhs[2] *= rhs[2]; 243 | lhs[3] *= rhs[3]; 244 | return lhs; 245 | } 246 | 247 | @:op(A / B) 248 | inline public static function divide(lhs:Vector4, rhs:Vector4):Vector4 { 249 | var res = new Vector4(); 250 | res[0] = lhs[0] / rhs[0]; 251 | res[1] = lhs[1] / rhs[1]; 252 | res[2] = lhs[2] / rhs[2]; 253 | res[3] = lhs[3] / rhs[3]; 254 | return res; 255 | } 256 | 257 | @:op(A /= B) 258 | inline public static function divideIn(lhs:Vector4, rhs:Vector4):Vector4 { 259 | lhs[0] /= rhs[0]; 260 | lhs[1] /= rhs[1]; 261 | lhs[2] /= rhs[2]; 262 | lhs[3] /= rhs[3]; 263 | return lhs; 264 | } 265 | 266 | @:op(A * B) 267 | inline public static function multScalar(lhs:Vector4, scalar:GDExtensionFloat):Vector4 { 268 | var res = new Vector4(); 269 | res[0] = lhs[0] * scalar; 270 | res[1] = lhs[1] * scalar; 271 | res[2] = lhs[2] * scalar; 272 | res[3] = lhs[3] * scalar; 273 | return res; 274 | } 275 | 276 | @:op(A *= B) 277 | inline public static function multInScalar(lhs:Vector4, scalar:GDExtensionFloat):Vector4 { 278 | lhs[0] *= scalar; 279 | lhs[1] *= scalar; 280 | lhs[2] *= scalar; 281 | lhs[3] *= scalar; 282 | return lhs; 283 | } 284 | 285 | @:op(A / B) 286 | inline public static function divideScalar(lhs:Vector4, scalar:GDExtensionFloat):Vector4 { 287 | var res = new Vector4(); 288 | res[0] = lhs[0] / scalar; 289 | res[1] = lhs[1] / scalar; 290 | res[2] = lhs[2] / scalar; 291 | res[3] = lhs[3] / scalar; 292 | return res; 293 | } 294 | 295 | @:op(A /= B) 296 | inline public static function divideInScalar(lhs:Vector4, scalar:GDExtensionFloat):Vector4 { 297 | lhs[0] /= scalar; 298 | lhs[1] /= scalar; 299 | lhs[2] /= scalar; 300 | lhs[3] /= scalar; 301 | return lhs; 302 | } 303 | 304 | @:op(A + B) 305 | inline public static function add(lhs:Vector4, rhs:Vector4):Vector4 { 306 | var res = new Vector4(); 307 | res[0] = lhs[0] + rhs[0]; 308 | res[1] = lhs[1] + rhs[1]; 309 | res[2] = lhs[2] + rhs[2]; 310 | res[3] = lhs[3] + rhs[3]; 311 | return res; 312 | } 313 | 314 | @:op(A += B) 315 | inline public static function addIn(lhs:Vector4, rhs:Vector4):Vector4 { 316 | lhs[0] += rhs[0]; 317 | lhs[1] += rhs[1]; 318 | lhs[2] += rhs[2]; 319 | lhs[3] += rhs[3]; 320 | return lhs; 321 | } 322 | 323 | @:op(A - B) 324 | inline public static function subtract(lhs:Vector4, rhs:Vector4):Vector4 { 325 | var res = new Vector4(); 326 | res[0] = lhs[0] - rhs[0]; 327 | res[1] = lhs[1] - rhs[1]; 328 | res[2] = lhs[2] - rhs[2]; 329 | res[3] = lhs[3] - rhs[3]; 330 | return res; 331 | } 332 | 333 | @:op(A -= B) 334 | inline public static function subtractIn(lhs:Vector4, rhs:Vector4):Vector4 { 335 | lhs[0] -= rhs[0]; 336 | lhs[1] -= rhs[1]; 337 | lhs[2] -= rhs[2]; 338 | lhs[3] -= rhs[3]; 339 | return lhs; 340 | } 341 | 342 | @:op(-A) 343 | inline public static function negate(lhs:Vector4):Vector4 { 344 | var res = new Vector4(); 345 | res[0] = -lhs[0]; 346 | res[1] = -lhs[1]; 347 | res[2] = -lhs[2]; 348 | res[3] = -lhs[3]; 349 | return res; 350 | } 351 | 352 | @:op(A < B) 353 | inline public static function lt(lhs:Vector4, rhs:Vector4) { 354 | if (lhs.x == rhs.x) { 355 | if (lhs.y == rhs.y) { 356 | if (lhs.z == rhs.z) { 357 | return lhs.w < rhs.w; 358 | } 359 | return lhs.z < rhs.z; 360 | } 361 | return lhs.y < rhs.y; 362 | } 363 | return lhs.x < rhs.x; 364 | } 365 | 366 | @:op(A > B) 367 | inline public static function gt(lhs:Vector4, rhs:Vector4) { 368 | if (lhs.x == rhs.x) { 369 | if (lhs.y == rhs.y) { 370 | if (lhs.z == rhs.z) { 371 | return lhs.w > rhs.w; 372 | } 373 | return lhs.z > rhs.z; 374 | } 375 | return lhs.y > rhs.y; 376 | } 377 | return lhs.x > rhs.x; 378 | } 379 | 380 | @:op(A <= B) 381 | inline public static function ltequals(lhs:Vector4, rhs:Vector4) { 382 | if (lhs.x == rhs.x) { 383 | if (lhs.y == rhs.y) { 384 | if (lhs.z == rhs.z) { 385 | return lhs.w <= rhs.w; 386 | } 387 | return lhs.z < rhs.z; 388 | } 389 | return lhs.y < rhs.y; 390 | } 391 | return lhs.x < rhs.x; 392 | } 393 | 394 | @:op(A >= B) 395 | inline public static function gtequals(lhs:Vector4, rhs:Vector4) { 396 | if (lhs.x == rhs.x) { 397 | if (lhs.y == rhs.y) { 398 | if (lhs.z == rhs.z) { 399 | return lhs.w >= rhs.w; 400 | } 401 | return lhs.z > rhs.z; 402 | } 403 | return lhs.y > rhs.y; 404 | } 405 | return lhs.x > rhs.x; 406 | } 407 | 408 | } -------------------------------------------------------------------------------- /src/godot/variant/Vector4i.hx: -------------------------------------------------------------------------------- 1 | package godot.variant; 2 | 3 | import godot.Types; 4 | import godot.core.GDMath; 5 | 6 | #if cpp 7 | using cpp.NativeArray; 8 | #end 9 | 10 | typedef __Vector4i = Array; 11 | 12 | @:forward 13 | abstract Vector4i(__Vector4i) from __Vector4i to __Vector4i { 14 | 15 | inline public function new(?_x:Int=0, ?_y:Int=0, ?_z:Int=0, ?_w:Int=0):Vector4i this = _alloc(_x, _y, _z, _w); 16 | 17 | inline private static function _alloc(_x:Int, _y:Int, _z:Int, _w:Int):__Vector4i 18 | return [_x, _y, _z, _w]; 19 | 20 | inline public function native_ptr():GDExtensionTypePtr { 21 | #if !macro 22 | return cast cpp.NativeArray.getBase(this).getBase(); 23 | #else 24 | return 0; 25 | #end 26 | } 27 | 28 | public var x(get, set):Int; 29 | inline function get_x() return this[0]; 30 | inline function set_x(_v:Int) {this[0] = _v; return _v;} 31 | 32 | public var y(get, set):Int; 33 | inline function get_y() return this[1]; 34 | inline function set_y(_v:Int) {this[1] = _v; return _v;} 35 | 36 | public var z(get, set):Int; 37 | inline function get_z() return this[2]; 38 | inline function set_z(_v:Int) {this[2] = _v; return _v;} 39 | 40 | public var w(get, set):Int; 41 | inline function get_w() return this[3]; 42 | inline function set_w(_v:Int) {this[3] = _v; return _v;} 43 | 44 | @:arrayAccess 45 | inline public function get(_i:Int) return this[_i]; 46 | 47 | @:arrayAccess 48 | inline public function setAt(_i:Int, _v:Int):Void 49 | this[_i] = _v; 50 | 51 | inline public function copy():Vector4i 52 | return new Vector4i(this[0], this[1], this[2], this[3]); 53 | 54 | public function length_squared():haxe.Int64 { 55 | return x * x + y * y + z * z + w * w; 56 | } 57 | 58 | public function length():Float { 59 | return Math.sqrt(cast length_squared()); 60 | } 61 | 62 | public function abs():Vector4i { 63 | return new Vector4i(Std.int(Math.abs(x)), Std.int(Math.abs(y)), Std.int(Math.abs(z)), Std.int(Math.abs(w))); 64 | } 65 | 66 | public function sign():Vector4i { 67 | return new Vector4i(Std.int(SIGN(x)), Std.int(SIGN(y)), Std.int(SIGN(z)), Std.int(SIGN(w))); 68 | } 69 | 70 | public function zero():Void { 71 | x = y = z = w = 0; 72 | } 73 | 74 | public function clamp(p_min:Vector4i, p_max:Vector4i):Vector4i { 75 | return new Vector4i( 76 | Std.int(CLAMP(x, p_min.x, p_max.x)), 77 | Std.int(CLAMP(y, p_min.y, p_max.y)), 78 | Std.int(CLAMP(z, p_min.z, p_max.z)), 79 | Std.int(CLAMP(w, p_min.w, p_max.w))); 80 | } 81 | 82 | public function snapped(p_step:Vector4i):Vector4i { 83 | return new Vector4i( 84 | Std.int(GDMath.snapped(x, p_step.x)), 85 | Std.int(GDMath.snapped(y, p_step.y)), 86 | Std.int(GDMath.snapped(z, p_step.z)), 87 | Std.int(GDMath.snapped(w, p_step.w))); 88 | } 89 | 90 | @:to public function toString() { 91 | return "(" + x + ", " + y + ", " + z + ", " + w + ")"; 92 | } 93 | 94 | @:op(A == B) 95 | inline public static function eq(lhs:Vector4i, rhs:Vector4i):Bool { 96 | return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3]; 97 | } 98 | 99 | @:op(A != B) 100 | inline public static function neq(lhs:Vector4i, rhs:Vector4i):Bool { 101 | return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3]; 102 | } 103 | 104 | @:op(A * B) 105 | inline public static function mult(lhs:Vector4i, rhs:Vector4i):Vector4i { 106 | var res = new Vector4i(); 107 | res[0] = lhs[0] * rhs[0]; 108 | res[1] = lhs[1] * rhs[1]; 109 | res[2] = lhs[2] * rhs[2]; 110 | res[3] = lhs[3] * rhs[3]; 111 | return res; 112 | } 113 | 114 | @:op(A *= B) 115 | inline public static function multIn(lhs:Vector4i, rhs:Vector4i):Vector4i { 116 | lhs[0] *= rhs[0]; 117 | lhs[1] *= rhs[1]; 118 | lhs[2] *= rhs[2]; 119 | lhs[3] *= rhs[3]; 120 | return lhs; 121 | } 122 | 123 | @:op(A / B) 124 | inline public static function divide(lhs:Vector4i, rhs:Vector4i):Vector4i { 125 | var res = new Vector4i(); 126 | res[0] = Std.int(lhs[0] / rhs[0]); 127 | res[1] = Std.int(lhs[1] / rhs[1]); 128 | res[2] = Std.int(lhs[2] / rhs[2]); 129 | res[3] = Std.int(lhs[3] / rhs[3]); 130 | return res; 131 | } 132 | 133 | @:op(A /= B) 134 | inline public static function divideIn(lhs:Vector4i, rhs:Vector4i):Vector4i { 135 | lhs[0] = Std.int(lhs[0] / rhs[0]); 136 | lhs[1] = Std.int(lhs[1] / rhs[1]); 137 | lhs[2] = Std.int(lhs[2] / rhs[2]); 138 | lhs[3] = Std.int(lhs[3] / rhs[3]); 139 | return lhs; 140 | } 141 | 142 | @:op(A * B) 143 | inline public static function multScalar(lhs:Vector4i, scalar:GDExtensionFloat):Vector4i { 144 | var res = new Vector4i(); 145 | res[0] = Std.int(lhs[0] * scalar); 146 | res[1] = Std.int(lhs[1] * scalar); 147 | res[2] = Std.int(lhs[2] * scalar); 148 | res[3] = Std.int(lhs[3] * scalar); 149 | return res; 150 | } 151 | 152 | @:op(A *= B) 153 | inline public static function multInScalar(lhs:Vector4i, scalar:GDExtensionFloat):Vector4i { 154 | lhs[0] = Std.int(lhs[0] * scalar); 155 | lhs[1] = Std.int(lhs[1] * scalar); 156 | lhs[2] = Std.int(lhs[2] * scalar); 157 | lhs[3] = Std.int(lhs[3] * scalar); 158 | return lhs; 159 | } 160 | 161 | @:op(A / B) 162 | inline public static function divideScalar(lhs:Vector4i, scalar:GDExtensionFloat):Vector4i { 163 | var res = new Vector4i(); 164 | res[0] = Std.int(lhs[0] / scalar); 165 | res[1] = Std.int(lhs[1] / scalar); 166 | res[2] = Std.int(lhs[2] / scalar); 167 | res[3] = Std.int(lhs[3] / scalar); 168 | return res; 169 | } 170 | 171 | @:op(A /= B) 172 | inline public static function divideInScalar(lhs:Vector4i, scalar:GDExtensionFloat):Vector4i { 173 | lhs[0] = Std.int(lhs[0] / scalar); 174 | lhs[1] = Std.int(lhs[1] / scalar); 175 | lhs[2] = Std.int(lhs[2] / scalar); 176 | lhs[3] = Std.int(lhs[3] / scalar); 177 | return lhs; 178 | } 179 | 180 | @:op(A + B) 181 | inline public static function add(lhs:Vector4i, rhs:Vector4i):Vector4i { 182 | var res = new Vector4i(); 183 | res[0] = lhs[0] + rhs[0]; 184 | res[1] = lhs[1] + rhs[1]; 185 | res[2] = lhs[2] + rhs[2]; 186 | res[3] = lhs[3] + rhs[3]; 187 | return res; 188 | } 189 | 190 | @:op(A += B) 191 | inline public static function addIn(lhs:Vector4i, rhs:Vector4i):Vector4i { 192 | lhs[0] += rhs[0]; 193 | lhs[1] += rhs[1]; 194 | lhs[2] += rhs[2]; 195 | lhs[3] += rhs[3]; 196 | return lhs; 197 | } 198 | 199 | @:op(A - B) 200 | inline public static function subtract(lhs:Vector4i, rhs:Vector4i):Vector4i { 201 | var res = new Vector4i(); 202 | res[0] = lhs[0] - rhs[0]; 203 | res[1] = lhs[1] - rhs[1]; 204 | res[2] = lhs[2] - rhs[2]; 205 | res[3] = lhs[3] - rhs[3]; 206 | return res; 207 | } 208 | 209 | @:op(A -= B) 210 | inline public static function subtractIn(lhs:Vector4i, rhs:Vector4i):Vector4i { 211 | lhs[0] -= rhs[0]; 212 | lhs[1] -= rhs[1]; 213 | lhs[2] -= rhs[2]; 214 | lhs[3] -= rhs[3]; 215 | return lhs; 216 | } 217 | 218 | @:op(-A) 219 | inline public static function negate(lhs:Vector4i):Vector4i { 220 | var res = new Vector4i(); 221 | res[0] = -lhs[0]; 222 | res[1] = -lhs[1]; 223 | res[2] = -lhs[2]; 224 | res[3] = -lhs[3]; 225 | return res; 226 | } 227 | 228 | @:op(A < B) 229 | inline public static function lt(lhs:Vector4i, rhs:Vector4i) { 230 | if (lhs.x == rhs.x) { 231 | if (lhs.y == rhs.y) { 232 | if (lhs.z == rhs.z) { 233 | return lhs.w < rhs.w; 234 | } else { 235 | return lhs.z < rhs.z; 236 | } 237 | } else { 238 | return lhs.y < rhs.y; 239 | } 240 | } else { 241 | return lhs.x < rhs.x; 242 | } 243 | } 244 | 245 | @:op(A > B) 246 | inline public static function gt(lhs:Vector4i, rhs:Vector4i) { 247 | if (lhs.x == rhs.x) { 248 | if (lhs.y == rhs.y) { 249 | if (lhs.z == rhs.z) { 250 | return lhs.w > rhs.w; 251 | } else { 252 | return lhs.z > rhs.z; 253 | } 254 | } else { 255 | return lhs.y > rhs.y; 256 | } 257 | } else { 258 | return lhs.x > rhs.x; 259 | } 260 | } 261 | 262 | @:op(A <= B) 263 | inline public static function ltequals(lhs:Vector4i, rhs:Vector4i) { 264 | if (lhs.x == rhs.x) { 265 | if (lhs.y == rhs.y) { 266 | if (lhs.z == rhs.z) { 267 | return lhs.w <= rhs.w; 268 | } else { 269 | return lhs.z < rhs.z; 270 | } 271 | } else { 272 | return lhs.y < rhs.y; 273 | } 274 | } else { 275 | return lhs.x < rhs.x; 276 | } 277 | } 278 | 279 | @:op(A >= B) 280 | inline public static function gtequals(lhs:Vector4i, rhs:Vector4i) { 281 | if (lhs.x == rhs.x) { 282 | if (lhs.y == rhs.y) { 283 | if (lhs.z == rhs.z) { 284 | return lhs.w >= rhs.w; 285 | } else { 286 | return lhs.z > rhs.z; 287 | } 288 | } else { 289 | return lhs.y > rhs.y; 290 | } 291 | } else { 292 | return lhs.x > rhs.x; 293 | } 294 | } 295 | 296 | } -------------------------------------------------------------------------------- /src/godot_cpp/core/defs.hpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /* defs.hpp */ 3 | /**************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT ENGINE */ 6 | /* https://godotengine.org */ 7 | /**************************************************************************/ 8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ 9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ 10 | /* */ 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ 12 | /* a copy of this software and associated documentation files (the */ 13 | /* "Software"), to deal in the Software without restriction, including */ 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 | /* permit persons to whom the Software is furnished to do so, subject to */ 17 | /* the following conditions: */ 18 | /* */ 19 | /* The above copyright notice and this permission notice shall be */ 20 | /* included in all copies or substantial portions of the Software. */ 21 | /* */ 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 | /**************************************************************************/ 30 | 31 | #ifndef GODOT_DEFS_HPP 32 | #define GODOT_DEFS_HPP 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #if !defined(GDE_EXPORT) 39 | #if defined(_WIN32) 40 | #define GDE_EXPORT __declspec(dllexport) 41 | #elif defined(__GNUC__) 42 | #define GDE_EXPORT __attribute__((visibility("default"))) 43 | #else 44 | #define GDE_EXPORT 45 | #endif 46 | #endif 47 | 48 | // Turn argument to string constant: 49 | // https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing 50 | #ifndef _STR 51 | #define _STR(m_x) #m_x 52 | #define _MKSTR(m_x) _STR(m_x) 53 | #endif 54 | 55 | // Should always inline no matter what. 56 | #ifndef _ALWAYS_INLINE_ 57 | #if defined(__GNUC__) 58 | #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline 59 | #elif defined(_MSC_VER) 60 | #define _ALWAYS_INLINE_ __forceinline 61 | #else 62 | #define _ALWAYS_INLINE_ inline 63 | #endif 64 | #endif 65 | 66 | // Should always inline, except in debug builds because it makes debugging harder. 67 | #ifndef _FORCE_INLINE_ 68 | #ifdef DISABLE_FORCED_INLINE 69 | #define _FORCE_INLINE_ inline 70 | #else 71 | #define _FORCE_INLINE_ _ALWAYS_INLINE_ 72 | #endif 73 | #endif 74 | 75 | #ifndef _NO_DISCARD_ 76 | #define _NO_DISCARD_ [[nodiscard]] 77 | #endif 78 | 79 | // Windows badly defines a lot of stuff we'll never use. Undefine it. 80 | #ifdef _WIN32 81 | #undef min // override standard definition 82 | #undef max // override standard definition 83 | #undef ERROR // override (really stupid) wingdi.h standard definition 84 | #undef DELETE // override (another really stupid) winnt.h standard definition 85 | #undef MessageBox // override winuser.h standard definition 86 | #undef MIN // override standard definition 87 | #undef MAX // override standard definition 88 | #undef CLAMP // override standard definition 89 | #undef Error 90 | #undef OK 91 | #undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum 92 | #endif 93 | 94 | #if defined(__GNUC__) 95 | #define likely(x) __builtin_expect(!!(x), 1) 96 | #define unlikely(x) __builtin_expect(!!(x), 0) 97 | #else 98 | #define likely(x) x 99 | #define unlikely(x) x 100 | #endif 101 | 102 | #ifdef REAL_T_IS_DOUBLE 103 | typedef double real_t; 104 | #else 105 | typedef float real_t; 106 | #endif 107 | 108 | // Generic swap template. 109 | #ifndef SWAP 110 | #define SWAP(m_x, m_y) __swap_tmpl((m_x), (m_y)) 111 | template 112 | inline void __swap_tmpl(T &x, T &y) { 113 | T aux = x; 114 | x = y; 115 | y = aux; 116 | } 117 | #endif // SWAP 118 | 119 | // Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple. 120 | // https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion 121 | template 122 | struct IndexSequence {}; 123 | 124 | template 125 | struct BuildIndexSequence : BuildIndexSequence {}; 126 | 127 | template 128 | struct BuildIndexSequence<0, Is...> : IndexSequence {}; 129 | 130 | #endif // GODOT_DEFS_HPP 131 | -------------------------------------------------------------------------------- /src/godot_cpp/variant/variant_size.hpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* variant_size.hpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT ENGINE */ 6 | /* https://godotengine.org */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ 9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ 10 | /* */ 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ 12 | /* a copy of this software and associated documentation files (the */ 13 | /* "Software"), to deal in the Software without restriction, including */ 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 | /* permit persons to whom the Software is furnished to do so, subject to */ 17 | /* the following conditions: */ 18 | /* */ 19 | /* The above copyright notice and this permission notice shall be */ 20 | /* included in all copies or substantial portions of the Software. */ 21 | /* */ 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 | /*************************************************************************/ 30 | 31 | // THIS FILE IS GENERATED. EDITS WILL BE LOST. 32 | 33 | #ifndef GODOT_CPP_VARIANT_SIZE_HPP 34 | #define GODOT_CPP_VARIANT_SIZE_HPP 35 | #define GODOT_CPP_VARIANT_SIZE 24 36 | #endif // ! GODOT_CPP_VARIANT_SIZE_HPP -------------------------------------------------------------------------------- /src/hxcpp_ext/Dynamic2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace hx { 6 | 7 | struct CStaticFunction6 : public hx::Object 8 | { 9 | StaticFunction6 mFunction; 10 | const char *mName; 11 | 12 | HX_IS_INSTANCE_OF enum { _hx_ClassId = 254 }; // this is a hack! Lets see when this explodes :D 13 | 14 | 15 | CStaticFunction6(const char *inName,StaticFunction6 inFunction) 16 | { 17 | mName = inName; 18 | mFunction = inFunction; 19 | } 20 | int __Compare(const hx::Object *inRHS) const 21 | { 22 | const CStaticFunction6 *other = dynamic_cast(inRHS); 23 | if (!other) 24 | return -1; 25 | return mName==other->mName && mFunction==other->mFunction && mName==other->mName ? 0 : -1; 26 | } 27 | 28 | int __GetType() const { return vtFunction; } 29 | int __ArgCount() const { return 6; } 30 | ::String __ToString() const{ return String(mName); } 31 | Dynamic __Run(const Array &inArgs) 32 | { 33 | return mFunction(inArgs[0],inArgs[1],inArgs[2],inArgs[3],inArgs[4],inArgs[5]); 34 | } 35 | Dynamic __run(const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4,const Dynamic &inArg5) 36 | { 37 | return mFunction(inArg0,inArg1,inArg2,inArg3,inArg4,inArg5); 38 | } 39 | }; 40 | 41 | 42 | HXCPP_EXTERN_CLASS_ATTRIBUTES 43 | Dynamic CreateStaticFunction6(const char *inName,StaticFunction6 inFunc) 44 | { return new CStaticFunction6(inName,inFunc); } 45 | 46 | 47 | struct CMemberFunction8 : public hx::Object 48 | { 49 | hx::ObjectPtr mThis; 50 | MemberFunction8 mFunction; 51 | const char *mName; 52 | 53 | HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdCMember8 }; 54 | 55 | 56 | CMemberFunction8(const char *inName, hx::Object *inObj, MemberFunction8 inFunction) 57 | { 58 | mName = inName; 59 | mThis = inObj; 60 | mFunction = inFunction; 61 | } 62 | int __Compare(const hx::Object *inRHS) const 63 | { 64 | const CMemberFunction8 *other = dynamic_cast(inRHS); 65 | if (!other) 66 | return -1; 67 | return (mName==other->mName && mFunction==other->mFunction && mThis.GetPtr()==other->mThis.GetPtr())? 0 : -1; 68 | } 69 | 70 | int __GetType() const { return vtFunction; } 71 | int __ArgCount() const { return 8; } 72 | ::String __ToString() const{ return String(mName); } 73 | void __Mark(hx::MarkContext *__inCtx) { HX_MARK_MEMBER_NAME(mThis,"CMemberFunction8.this"); } 74 | #ifdef HXCPP_VISIT_ALLOCS 75 | void __Visit(hx::VisitContext *__inCtx) { HX_VISIT_MEMBER(mThis); } 76 | #endif 77 | void *__GetHandle() const { return mThis.GetPtr(); } 78 | Dynamic __Run(const Array &inArgs) 79 | { 80 | 81 | return mFunction(mThis.GetPtr(), inArgs[0],inArgs[1],inArgs[2],inArgs[3],inArgs[4], 82 | inArgs[5],inArgs[6],inArgs[7]); 83 | 84 | } 85 | Dynamic __run(const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4, 86 | const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7) 87 | { 88 | 89 | return mFunction(mThis.GetPtr(), inArg0,inArg1,inArg2,inArg3,inArg4, inArg5,inArg6,inArg7); 90 | 91 | } 92 | }; 93 | 94 | HXCPP_EXTERN_CLASS_ATTRIBUTES 95 | Dynamic CreateMemberFunction8(const char *inName,hx::Object *inObj, MemberFunction8 inFunc) 96 | { return new CMemberFunction8(inName,inObj,inFunc); } 97 | 98 | struct CMemberFunction9 : public hx::Object 99 | { 100 | hx::ObjectPtr mThis; 101 | MemberFunction9 mFunction; 102 | const char *mName; 103 | 104 | HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdCMember9 }; 105 | 106 | 107 | CMemberFunction9(const char *inName, hx::Object *inObj, MemberFunction9 inFunction) 108 | { 109 | mName = inName; 110 | mThis = inObj; 111 | mFunction = inFunction; 112 | } 113 | int __Compare(const hx::Object *inRHS) const 114 | { 115 | const CMemberFunction9 *other = dynamic_cast(inRHS); 116 | if (!other) 117 | return -1; 118 | return (mName==other->mName && mFunction==other->mFunction && mThis.GetPtr()==other->mThis.GetPtr())? 0 : -1; 119 | } 120 | 121 | int __GetType() const { return vtFunction; } 122 | int __ArgCount() const { return 9; } 123 | ::String __ToString() const{ return String(mName); } 124 | void __Mark(hx::MarkContext *__inCtx) { HX_MARK_MEMBER_NAME(mThis,"CMemberFunction9.this"); } 125 | #ifdef HXCPP_VISIT_ALLOCS 126 | void __Visit(hx::VisitContext *__inCtx) { HX_VISIT_MEMBER(mThis); } 127 | #endif 128 | void *__GetHandle() const { return mThis.GetPtr(); } 129 | Dynamic __Run(const Array &inArgs) 130 | { 131 | 132 | return mFunction(mThis.GetPtr(), inArgs[0],inArgs[1],inArgs[2],inArgs[3],inArgs[4], 133 | inArgs[5],inArgs[6],inArgs[7],inArgs[8]); 134 | 135 | } 136 | Dynamic __run(const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4, 137 | const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7,const Dynamic &inArg8) 138 | { 139 | 140 | return mFunction(mThis.GetPtr(), inArg0,inArg1,inArg2,inArg3,inArg4, inArg5,inArg6,inArg7,inArg8); 141 | 142 | } 143 | }; 144 | 145 | HXCPP_EXTERN_CLASS_ATTRIBUTES 146 | Dynamic CreateMemberFunction9(const char *inName,hx::Object *inObj, MemberFunction9 inFunc) 147 | { return new CMemberFunction9(inName,inObj,inFunc); } 148 | 149 | 150 | 151 | struct CMemberFunction10 : public hx::Object 152 | { 153 | hx::ObjectPtr mThis; 154 | MemberFunction10 mFunction; 155 | const char *mName; 156 | 157 | HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdCMember10 }; 158 | 159 | 160 | CMemberFunction10(const char *inName, hx::Object *inObj, MemberFunction10 inFunction) 161 | { 162 | mName = inName; 163 | mThis = inObj; 164 | mFunction = inFunction; 165 | } 166 | int __Compare(const hx::Object *inRHS) const 167 | { 168 | const CMemberFunction10 *other = dynamic_cast(inRHS); 169 | if (!other) 170 | return -1; 171 | return (mName==other->mName && mFunction==other->mFunction && mThis.GetPtr()==other->mThis.GetPtr())? 0 : -1; 172 | } 173 | 174 | int __GetType() const { return vtFunction; } 175 | int __ArgCount() const { return 10; } 176 | ::String __ToString() const{ return String(mName); } 177 | void __Mark(hx::MarkContext *__inCtx) { HX_MARK_MEMBER_NAME(mThis,"CMemberFunction10.this"); } 178 | #ifdef HXCPP_VISIT_ALLOCS 179 | void __Visit(hx::VisitContext *__inCtx) { HX_VISIT_MEMBER(mThis); } 180 | #endif 181 | void *__GetHandle() const { return mThis.GetPtr(); } 182 | Dynamic __Run(const Array &inArgs) 183 | { 184 | 185 | return mFunction(mThis.GetPtr(), inArgs[0],inArgs[1],inArgs[2],inArgs[3],inArgs[4], 186 | inArgs[5],inArgs[6],inArgs[7],inArgs[8],inArgs[9]); 187 | 188 | } 189 | Dynamic __run(const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4, 190 | const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7,const Dynamic &inArg8,const Dynamic &inArg9) 191 | { 192 | 193 | return mFunction(mThis.GetPtr(), inArg0,inArg1,inArg2,inArg3,inArg4, inArg5,inArg6,inArg7,inArg8,inArg9); 194 | 195 | } 196 | }; 197 | 198 | HXCPP_EXTERN_CLASS_ATTRIBUTES 199 | Dynamic CreateMemberFunction10(const char *inName,hx::Object *inObj, MemberFunction10 inFunc) 200 | { return new CMemberFunction10(inName,inObj,inFunc); } 201 | 202 | } -------------------------------------------------------------------------------- /src/hxcpp_ext/Dynamic2.h: -------------------------------------------------------------------------------- 1 | #ifndef HX_DYNAMIC2_H 2 | #define HX_DYNAMIC2_H 3 | 4 | namespace hx 5 | { 6 | typedef Dynamic (*StaticFunction6)(const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4,const Dynamic &inArg5); 7 | 8 | HXCPP_EXTERN_CLASS_ATTRIBUTES 9 | Dynamic CreateStaticFunction6(const char *,StaticFunction6); 10 | 11 | enum 12 | { 13 | clsIdCMember8 = clsIdZLib+1, 14 | clsIdCMember9, 15 | clsIdCMember10, 16 | }; 17 | 18 | typedef Dynamic (*MemberFunction10)(hx::Object *inObj, 19 | const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4,const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7,const Dynamic &inArg8,const Dynamic &inArg9); 20 | 21 | typedef Dynamic (*MemberFunction9)(hx::Object *inObj, 22 | const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4,const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7,const Dynamic &inArg8); 23 | 24 | typedef Dynamic (*MemberFunction8)(hx::Object *inObj, 25 | const Dynamic &inArg0,const Dynamic &inArg1,const Dynamic &inArg2,const Dynamic &inArg3,const Dynamic &inArg4,const Dynamic &inArg5,const Dynamic &inArg6,const Dynamic &inArg7); 26 | 27 | HXCPP_EXTERN_CLASS_ATTRIBUTES 28 | Dynamic CreateMemberFunction8(const char *,hx::Object *, MemberFunction8); 29 | 30 | HXCPP_EXTERN_CLASS_ATTRIBUTES 31 | Dynamic CreateMemberFunction9(const char *,hx::Object *, MemberFunction9); 32 | 33 | HXCPP_EXTERN_CLASS_ATTRIBUTES 34 | Dynamic CreateMemberFunction10(const char *,hx::Object *, MemberFunction10); 35 | 36 | 37 | } 38 | 39 | #endif -------------------------------------------------------------------------------- /src/hxcpp_ext/hxgodot_api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace godot; 8 | 9 | typedef void (*HxgHaxeFinalizer)(Dynamic); 10 | typedef std::unordered_map HxgFinalizerMap; 11 | HxgFinalizerMap sBuiltinFinalizers; 12 | HxgFinalizerMap sFinalizers; 13 | HxMutex *gHxgShadowObjectLock = new HxMutex(); 14 | 15 | void hxgodot_set_finalizer(Dynamic obj, void*inFunction, bool builtin) { 16 | 17 | AutoLock lock(*gHxgShadowObjectLock); 18 | HxgFinalizerMap ¤t = builtin ? sBuiltinFinalizers : sFinalizers; 19 | 20 | if (inFunction==0) { 21 | HxgFinalizerMap::iterator i = current.find(obj.mPtr); 22 | if (i!=current.end()) 23 | current.erase(i); 24 | } 25 | else 26 | current[obj.mPtr] = (HxgHaxeFinalizer)inFunction; 27 | 28 | __hxcpp_set_finalizer(obj, inFunction); 29 | } 30 | 31 | void hxgodot_clear_finalizer(Dynamic obj) { 32 | AutoLock lock(*gHxgShadowObjectLock); 33 | HxgFinalizerMap::iterator i = sBuiltinFinalizers.find(obj.mPtr); 34 | 35 | if (i!=sBuiltinFinalizers.end()) 36 | sBuiltinFinalizers.erase(i); 37 | 38 | i = sFinalizers.find(obj.mPtr); 39 | if (i!=sFinalizers.end()) 40 | sFinalizers.erase(i); 41 | } 42 | 43 | void hxgodot_finalize(bool builtin) { 44 | AutoLock lock(*gHxgShadowObjectLock); 45 | HxgFinalizerMap ¤t = builtin ? sBuiltinFinalizers : sFinalizers; 46 | 47 | for(HxgFinalizerMap::iterator i=current.begin(); i!=current.end(); ) { 48 | hx::Object *obj = i->first; 49 | HxgFinalizerMap::iterator next = i; 50 | ++next; 51 | (*i->second)(obj); 52 | __hxcpp_set_finalizer(obj, 0x0); 53 | i = next; 54 | } 55 | current.clear(); 56 | } 57 | 58 | extern "C" 59 | { 60 | void __hxcpp_main(); 61 | 62 | void hxgodot_boot() 63 | { 64 | int base = 99; 65 | hx::SetTopOfStack(&base,true); 66 | 67 | ::hx::Boot(); 68 | __boot_all(); 69 | __hxcpp_main(); 70 | 71 | hx::SetTopOfStack((int*)0,true); 72 | } 73 | 74 | void hxgodot_init_level(ModuleInitializationLevel p_level) 75 | { 76 | int base = 99; 77 | hx::SetTopOfStack(&base,true); 78 | 79 | HxGodot_obj::init_level((int32_t)p_level); 80 | 81 | hx::SetTopOfStack((int*)0,true); 82 | } 83 | 84 | void hxgodot_shutdown_level(ModuleInitializationLevel p_level) 85 | { 86 | int base = 99; 87 | hx::SetTopOfStack(&base,true); 88 | __hxcpp_enable(false); 89 | 90 | HxGodot_obj::shutdown_level(p_level); 91 | 92 | if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { 93 | hxgodot_finalize(false); 94 | } else if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) 95 | hxgodot_finalize(true); 96 | 97 | // hx::InternalCollect(true, true); // collect after every shutdown level 98 | 99 | hx::SetTopOfStack((int*)0,true); 100 | } 101 | } -------------------------------------------------------------------------------- /src/hxgodot_extension.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* register_types.cpp */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT ENGINE */ 6 | /* https://godotengine.org */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ 9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ 10 | /* */ 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ 12 | /* a copy of this software and associated documentation files (the */ 13 | /* "Software"), to deal in the Software without restriction, including */ 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 | /* permit persons to whom the Software is furnished to do so, subject to */ 17 | /* the following conditions: */ 18 | /* */ 19 | /* The above copyright notice and this permission notice shall be */ 20 | /* included in all copies or substantial portions of the Software. */ 21 | /* */ 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 | /*************************************************************************/ 30 | 31 | #include "hxgodot_extension.h" 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace godot; 37 | 38 | extern "C" void hxgodot_boot(); 39 | extern "C" void hxgodot_init_level(ModuleInitializationLevel p_level); 40 | extern "C" void hxgodot_shutdown_level(ModuleInitializationLevel p_level); 41 | 42 | void initialize_hxgodot_module(ModuleInitializationLevel p_level) { 43 | hxgodot_init_level(p_level); 44 | } 45 | 46 | void uninitialize_hxgodot_module(ModuleInitializationLevel p_level) { 47 | hxgodot_shutdown_level(p_level); 48 | } 49 | 50 | extern "C" { 51 | // Initialization. 52 | GDExtensionBool GDE_EXPORT hxgodot_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { 53 | godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); 54 | 55 | init_obj.register_initializer(initialize_hxgodot_module); 56 | init_obj.register_terminator(uninitialize_hxgodot_module); 57 | init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); 58 | 59 | hxgodot_boot(); 60 | 61 | return init_obj.init(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/hxgodot_extension.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* register_types.h */ 3 | /*************************************************************************/ 4 | /* This file is part of: */ 5 | /* GODOT ENGINE */ 6 | /* https://godotengine.org */ 7 | /*************************************************************************/ 8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ 9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ 10 | /* */ 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ 12 | /* a copy of this software and associated documentation files (the */ 13 | /* "Software"), to deal in the Software without restriction, including */ 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 | /* permit persons to whom the Software is furnished to do so, subject to */ 17 | /* the following conditions: */ 18 | /* */ 19 | /* The above copyright notice and this permission notice shall be */ 20 | /* included in all copies or substantial portions of the Software. */ 21 | /* */ 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 | /*************************************************************************/ 30 | 31 | #ifndef HXGODOT_EXTENSION_H 32 | #define HXGODOT_EXTENSION_H 33 | 34 | #include 35 | using namespace godot; 36 | 37 | void initialize_hxgodot_module(ModuleInitializationLevel p_level); 38 | void uninitialize_hxgodot_module(ModuleInitializationLevel p_level); 39 | 40 | #endif // ! HXGODOT_EXTENSION_H 41 | -------------------------------------------------------------------------------- /src/import.hx: -------------------------------------------------------------------------------- 1 | import godot.core.GDConstants.*; 2 | #if !macro 3 | import godot.core.GDUtils; 4 | #end -------------------------------------------------------------------------------- /src/utils/RootedObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT No Attribution 3 | 4 | Copyright 2022 Aidan Lee 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #include 21 | #include "utils/RootedObject.hpp" 22 | 23 | cpp::utils::RootedObject::RootedObject(void* _baton) 24 | : rooted(static_cast(_baton)), weak(true) 25 | { 26 | } 27 | 28 | cpp::utils::RootedObject::RootedObject(hx::Object** _root) 29 | : rooted(_root), weak(true) 30 | { 31 | } 32 | 33 | cpp::utils::RootedObject::RootedObject(hx::Object* _object) 34 | : rooted(new hx::Object*(_object)), weak(true) 35 | { 36 | 37 | } 38 | 39 | cpp::utils::RootedObject::~RootedObject() 40 | { 41 | if (rooted != nullptr) { 42 | if (!weak) 43 | hx::GCRemoveRoot(rooted); 44 | delete rooted; 45 | rooted = nullptr; 46 | } 47 | } 48 | 49 | void cpp::utils::RootedObject::makeStrong() 50 | { 51 | hx::GCAddRoot(rooted); 52 | weak = false; 53 | } 54 | 55 | void cpp::utils::RootedObject::makeWeak() 56 | { 57 | hx::GCRemoveRoot(rooted); 58 | weak = true; 59 | // rooted = nullptr; 60 | } 61 | 62 | bool cpp::utils::RootedObject::isWeak() { 63 | return weak; 64 | } 65 | 66 | inline hx::Object** cpp::utils::RootedObject::getObjectPtr() const 67 | { 68 | return rooted; 69 | } 70 | 71 | cpp::utils::RootedObject::operator hx::Object*() const 72 | { 73 | return *rooted; 74 | } 75 | 76 | hx::Object* cpp::utils::RootedObject::getObject() const 77 | { 78 | return *rooted; 79 | } 80 | 81 | void cpp::utils::RootedObject::setObject(hx::Object* _object) const 82 | { 83 | *rooted = _object; 84 | } -------------------------------------------------------------------------------- /src/utils/RootedObject.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT No Attribution 3 | 4 | Copyright 2022 Aidan Lee 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | #pragma once 21 | 22 | #ifndef HXCPP_H 23 | #include 24 | #endif 25 | 26 | namespace cpp 27 | { 28 | namespace utils { 29 | class RootedObject 30 | { 31 | private: 32 | bool weak; 33 | hx::Object** rooted; 34 | 35 | public: 36 | RootedObject(void*); 37 | RootedObject(hx::Object**); 38 | RootedObject(hx::Object*); 39 | 40 | ~RootedObject(); 41 | 42 | void makeStrong(); 43 | void makeWeak(); 44 | bool isWeak(); 45 | inline hx::Object** getObjectPtr() const; 46 | 47 | hx::Object* getObject() const; 48 | void setObject(hx::Object*) const; 49 | 50 | operator hx::Object*() const; 51 | }; 52 | } 53 | } -------------------------------------------------------------------------------- /tools/run/compile.hxml: -------------------------------------------------------------------------------- 1 | -neko ../../run.n 2 | -main RunMain 3 | -D neko_v1 4 | -debug 5 | -------------------------------------------------------------------------------- /tools/run/hxformat.json: -------------------------------------------------------------------------------- 1 | { 2 | "lineEnds": { 3 | "leftCurly": "after", 4 | "emptyCurly": "noBreak" 5 | }, 6 | "sameLine": { 7 | "ifElse": "same", 8 | "doWhile": "next", 9 | "tryBody": "next", 10 | "tryCatch": "next" 11 | }, 12 | "indentation": { 13 | "character": " " 14 | } 15 | } -------------------------------------------------------------------------------- /tools/template/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "haxe.configurations": [ 3 | ["-cpp", "bin/", "-cp", "bindings", "build.hxml"], 4 | ] 5 | } -------------------------------------------------------------------------------- /tools/template/SConstruct: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os, sys, subprocess 3 | 4 | from SCons.Tool import msvc, mingw 5 | from SCons.Variables import * 6 | 7 | default_platform = "windows" 8 | platforms = ("windows", "linux", "macos") 9 | architecture_array = ["x86_64", "x86_32", "arm64"] 10 | haxe_target_array = ['cpp', 'cppia'] 11 | 12 | opts = Variables([], ARGUMENTS) 13 | env = Environment(tools=["default"], PLATFORM="") 14 | 15 | opts.Add(EnumVariable('target', "Compilation target", 'debug', ['debug', 'release'])) 16 | opts.Add( 17 | EnumVariable( 18 | "platform", 19 | "Target platform", 20 | default_platform, 21 | allowed_values=platforms, 22 | ignorecase=2, 23 | ) 24 | ) 25 | opts.Add(EnumVariable("arch", "CPU architecture", architecture_array[0], architecture_array)) 26 | opts.Add(BoolVariable("scriptable", "Compile your cpp-code with cppia context extensions", False)) 27 | opts.Add(EnumVariable('haxe_target', 'Haxe Target', haxe_target_array[0], haxe_target_array)) 28 | opts.Update(env) 29 | 30 | # hxgodot haxelib folder 31 | hxgodotPath = subprocess.check_output('haxelib libpath hxgodot', shell=True).decode('utf-8').strip() 32 | 33 | libTargetString = '-debug' if env['target'] == 'debug' else '' 34 | 35 | # hxgodot libnames 36 | static_lib_name = f'libHxGodot{libTargetString}' 37 | shared_lib_name = f"hxgodot.{env['target']}.{env['arch']}" 38 | 39 | # platform specifics 40 | link_flags = [] 41 | cc_flags = [] 42 | if env['platform'] == "windows": 43 | static_lib_name += '.lib' 44 | shared_lib_name = 'lib' + shared_lib_name + '.dll' 45 | env.Append(ENV = os.environ) 46 | 47 | if env["arch"] == "x86_64": 48 | env["TARGET_ARCH"] = "amd64" 49 | link_flags.append("-machine:x64") 50 | elif env["arch"] == "x86_32": 51 | env["TARGET_ARCH"] = 'x86' 52 | link_flags.append("-machine:x86") 53 | env["is_msvc"] = True 54 | 55 | msvc.generate(env) 56 | env.Tool("mslib") 57 | env.Tool("mslink") 58 | 59 | env.Append(LIBS=['user32.lib', 'Ws2_32.lib', 'Crypt32.lib', 'Advapi32.lib']) 60 | env.Append(CPPDEFINES=["WIN32", "_WIN32", "_WINDOWS", "_CRT_SECURE_NO_WARNINGS"]) 61 | 62 | cc_flags = cc_flags + ['-EHs', '-FS', '-GR', '-GS-', '-MT', '-nologo', '-Oy-', '-wd4996', '/fp:precise', '/WX-'] 63 | if env['target'] == 'debug': 64 | cc_flags.append('-Od') 65 | link_flags.append('-debug:full') 66 | else: 67 | cc_flags.append('-O2') 68 | 69 | elif env['platform'] == "linux": 70 | static_lib_name += '.a' 71 | shared_lib_name += '.dso' 72 | env.Append(ENV = os.environ) 73 | 74 | if env["arch"] == "x86_64": 75 | cc_flags.append('-m64') 76 | else: 77 | cc_flags.append('-m32') 78 | 79 | env.Append(CPPDEFINES=["_CRT_SECURE_NO_DEPRECATE"]) 80 | cc_flags = cc_flags + ['-fpic', '-fPIC', '-frtti', '-fvisibility=hidden', '-std=c++11', '-Wno-invalid-offsetof', '-Wno-overflow', '-x', 'c++'] 81 | 82 | if env['target'] == 'debug': 83 | cc_flags.append('-g') 84 | else: 85 | cc_flags.append('-O2') 86 | 87 | elif env['platform'] == "macos": 88 | static_lib_name += '.a' 89 | shared_lib_name += '.dylib' 90 | env.Append(ENV = os.environ) 91 | 92 | if env["arch"] == "x86_64": 93 | cc_flags.append('-m64') 94 | elif env["arch"] == "arm64": 95 | cc_flags.append('-m64') 96 | else: 97 | cc_flags.append('-m32') 98 | 99 | env.Append(CPPDEFINES=["_CRT_SECURE_NO_DEPRECATE"]) 100 | cc_flags = cc_flags + ['-frtti', '-fvisibility=hidden', '-std=c++11', '-Wno-invalid-offsetof', '-Wno-overflow', '-x', 'c++'] 101 | if env['target'] == 'debug': 102 | cc_flags.append('-g') 103 | else: 104 | cc_flags.append('-O2') 105 | 106 | env.Append(LINKFLAGS = link_flags) 107 | env.Append(CCFLAGS = cc_flags) 108 | 109 | # build shared objs here 110 | env.VariantDir('bin/obj', f'{hxgodotPath}src/', duplicate=0) 111 | 112 | # run haxe compile 113 | 114 | if env['haxe_target'] == 'cppia': 115 | hxCmd = f'haxe script.hxml {libTargetString}' 116 | else: 117 | hxCmd = f'haxe build.hxml {libTargetString}' 118 | hxCmd = hxCmd + ' -D HXCPP_GC_GENERATIONAL -D HXCPP_CPP11 -D static_link -cpp bin/ -cp bindings' 119 | if env["arch"] == "x86_64": 120 | hxCmd = hxCmd + ' -D HXCPP_M64' 121 | elif env["arch"] == "arm64": 122 | hxCmd = hxCmd + ' -D HXCPP_ARM64' 123 | if env["scriptable"] == True: 124 | hxCmd = hxCmd + ' -D scriptable' 125 | 126 | hxlib = env.Command('bin/'+static_lib_name, [], hxCmd) 127 | env.AlwaysBuild(hxlib) 128 | 129 | # build our lib 130 | env.Append(CPPPATH=[ 131 | 'bin/include' 132 | ]) 133 | env.Append(LIBPATH=['bin/']) 134 | env.Append(LIBS=[static_lib_name]) 135 | 136 | env.Append(CPPPATH=[f'bin/obj/']) 137 | sources = Glob(f'bin/obj/*.cpp') 138 | 139 | library = env.SharedLibrary(target='bin/' + shared_lib_name , source=sources) 140 | 141 | # make the shared lib depend on hxcpp builds 142 | env.Depends(library, hxlib) 143 | 144 | # 145 | Default(library) 146 | 147 | # Generates help for the -h scons option. 148 | Help(opts.GenerateHelpText(env)) 149 | -------------------------------------------------------------------------------- /tools/template/bin/.gdignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HxGodot/hxgodot/0b5ca05e0189725724b0c9b03d748d5c2424a079/tools/template/bin/.gdignore -------------------------------------------------------------------------------- /tools/template/build.hxml: -------------------------------------------------------------------------------- 1 | # add libs, let hxgodot add its extraParams.hxml first 2 | -lib hxgodot 3 | -lib compiletime 4 | # use dll entrypoint of haxelib 5 | -main HxGodot 6 | -cp src 7 | # force include our gamecode into the extension 8 | # make sure you add all your "src/" this way. 9 | --macro include('example', true) 10 | -------------------------------------------------------------------------------- /tools/template/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=3 uid="uid://bk1i3p25ntj66"] 2 | 3 | [sub_resource type="Sky" id="1"] 4 | 5 | [resource] 6 | background_mode = 2 7 | sky = SubResource("1") 8 | -------------------------------------------------------------------------------- /tools/template/example.gdextension: -------------------------------------------------------------------------------- 1 | [configuration] 2 | 3 | compatibility_minimum = "4.1.0" 4 | entry_symbol = "hxgodot_library_init" 5 | 6 | [icons] 7 | HxExample = "res://icons/haxe-logo-glyph.svg" 8 | HxOther = "res://icons/haxe-logo-glyph.svg" 9 | HxOtherInPackage = "res://icons/haxe-logo-glyph.svg" 10 | 11 | [libraries] 12 | 13 | macos.debug.arm64 = "bin/libhxgodot.debug.arm64.dylib" 14 | macos.release.arm64 = "bin/libhxgodot.release.arm64.dylib" 15 | macos.template_debug.arm64 = "bin/libhxgodot.debug.arm64.dylib" 16 | macos.template_release.arm64 = "bin/libhxgodot.release.arm64.dylib" 17 | 18 | macos.debug.x86_64 = "bin/libhxgodot.debug.x86_64.dylib" 19 | macos.release.x86_64 = "bin/libhxgodot.release.x86_64.dylib" 20 | macos.template_debug.x86_64 = "bin/libhxgodot.debug.x86_64.dylib" 21 | macos.template_release.x86_64 = "bin/libhxgodot.release.x86_64.dylib" 22 | 23 | windows.debug.x86_64 = "bin/libhxgodot.debug.x86_64.dll" 24 | windows.release.x86_64 = "bin/libhxgodot.release.x86_64.dll" 25 | windows.template_debug.x86_64 = "bin/libhxgodot.debug.x86_64.dll" 26 | windows.template_release.x86_64 = "bin/libhxgodot.release.x86_64.dll" 27 | 28 | linux.debug.x86_64 = "bin/libhxgodot.debug.x86_64.dso" 29 | linux.release.x86_64 = "bin/libhxgodot.release.x86_64.dso" 30 | linux.template_debug.x86_64 = "bin/libhxgodot.debug.x86_64.dso" 31 | linux.template_release.x86_64 = "bin/libhxgodot.release.x86_64.dso" 32 | 33 | windows.debug.x86_32 = "bin/libhxgodot.debug.x86_32.dll" 34 | windows.release.x86_32 = "bin/libhxgodot.release.x86_32.dll" 35 | windows.template_debug.x86_32 = "bin/libhxgodot.debug.x86_32.dll" 36 | windows.template_release.x86_32 = "bin/libhxgodot.release.x86_32.dll" 37 | 38 | web.template_debug.wasm32 = "bin/libhxgodot.debug.x86_32.dll" 39 | web.template_release.wasm32 = "bin/libhxgodot.release.x86_32.dll" -------------------------------------------------------------------------------- /tools/template/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HxGodot/hxgodot/0b5ca05e0189725724b0c9b03d748d5c2424a079/tools/template/icon.png -------------------------------------------------------------------------------- /tools/template/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cswr8vy4lt7dt" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /tools/template/icons/haxe-logo-glyph.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/template/icons/haxe-logo-glyph.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cqbnhlchdw2o" 6 | path="res://.godot/imported/haxe-logo-glyph.svg-7b111e80bed5c597b3b9ad2b347060a2.ctex" 7 | metadata={ 8 | "has_editor_variant": true, 9 | "vram_texture": false 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://icons/haxe-logo-glyph.svg" 15 | dest_files=["res://.godot/imported/haxe-logo-glyph.svg-7b111e80bed5c597b3b9ad2b347060a2.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=0 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=false 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=1 36 | svg/scale=0.1 37 | editor/scale_with_editor_scale=true 38 | editor/convert_colors_with_editor_theme=false 39 | -------------------------------------------------------------------------------- /tools/template/main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cta3g6aiq0sl"] 2 | 3 | [ext_resource type="Script" path="res://test.gd" id="1_t53o3"] 4 | 5 | [node name="Node" type="Node"] 6 | 7 | [node name="HxExample" type="HxExample" parent="."] 8 | hx_ImportantFloat = 40.69 9 | hx_ImportantString = "This is an super important string" 10 | hx_random_MyVector3 = Vector3(1.119, 2.088, 3.133) 11 | script = ExtResource("1_t53o3") 12 | 13 | [node name="HxOther" type="HxOther" parent="."] 14 | 15 | [node name="Node2D" type="Node2D" parent="."] 16 | -------------------------------------------------------------------------------- /tools/template/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="hxgodot Sample Project" 14 | run/main_scene="res://main.tscn" 15 | config/features=PackedStringArray("4.2") 16 | config/icon="res://icon.png" 17 | 18 | [native_extensions] 19 | 20 | paths=["res://example.gdextension"] 21 | 22 | [rendering] 23 | 24 | environment/defaults/default_environment="res://default_env.tres" 25 | -------------------------------------------------------------------------------- /tools/template/src/.gdignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HxGodot/hxgodot/0b5ca05e0189725724b0c9b03d748d5c2424a079/tools/template/src/.gdignore -------------------------------------------------------------------------------- /tools/template/src/example/HxExample.hx: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import godot.GlobalConstants; 4 | import godot.core.GDUtils; 5 | import godot.*; 6 | import godot.variant.*; 7 | 8 | class HxExample extends godot.Node { 9 | 10 | @:export 11 | public var onHit:TypedSignal<(count:Int)->Void>; 12 | 13 | @:export 14 | public var onTest:TypedSignal<(node:HxExample)->Void>; 15 | 16 | static var test_static_initialization:StringName = "no more crash"; 17 | static var test_static_initialization_of_this_node = new godot.Node(); 18 | var myInstanceVec = new Vector3(0,0,0); 19 | 20 | @:export 21 | @:hint(PropertyHint.PROPERTY_HINT_RANGE, "0,64,1") 22 | public var testProperty(default, default):Int = 42; 23 | 24 | // 25 | @:export 26 | @:hint(PropertyHint.PROPERTY_HINT_RANGE, "0,64,0.01") 27 | @:group("My Haxe Properties", "hx_") 28 | public var hx_ImportantFloat(default, set):Float = 22; 29 | 30 | @:export 31 | function set_hx_ImportantFloat(_v:Float):Float { 32 | 33 | var test = new HxExample(); 34 | test.queue_free(); 35 | 36 | //var crash:Array = ["crash"]; 37 | //var crash2:Array = [("crash":StringName)]; 38 | 39 | // custom print functions out of godot.core.GDUtils. The cast to GDString is important! 40 | GDUtils.print(("print: This is a test":GDString)); 41 | GDUtils.print_rich(("print_rich: [b]Bold[/b], [color=red]Red text[/color]":GDString)); 42 | GDUtils.print_verbose(("print_verbose: This is a test":GDString)); 43 | 44 | trace("Setting ImportantFloat to: " + _v); 45 | trace(GDString.humanize_size(Std.int(_v * 1000))); 46 | 47 | // mess with Basis and Vector3s 48 | var b = new godot.variant.Basis(); 49 | trace(b); 50 | trace(b.x); 51 | trace(b.y); 52 | trace(b.z); 53 | 54 | trace(this.hx_random_MyVector3); 55 | b.x = this.hx_random_MyVector3; 56 | trace(b); 57 | trace(b.x); 58 | //trace(b[4]); // out of bounds <3 59 | trace(b[1] = new Vector3(3,2,1)); 60 | trace(b.y); 61 | trace(b.z); 62 | 63 | // Mess with Strings 64 | var tmp1:GDString = "%s"; 65 | var tmp2:GDString = "Test2"; 66 | trace(tmp1 < tmp2); 67 | trace(tmp1 + " " + tmp2); 68 | trace(tmp1 % tmp2); // Godot's format string <3 69 | 70 | for (i in 0...tmp1.length().toInt()) 71 | trace(tmp1[i]); 72 | 73 | // mess with arrays 74 | var arr = new godot.variant.GDArray(); 75 | arr.push_back(1); 76 | arr.push_back("x2"); // mix types! 77 | 78 | /* 79 | for (v in 0...arr.size()) { 80 | trace((arr[v]:Int)); // [1] will fail on cast 81 | } 82 | */ 83 | 84 | hx_ImportantFloat = _v; 85 | return _v; 86 | } 87 | 88 | // 89 | @:export 90 | @:hint(PropertyHint.PROPERTY_HINT_MULTILINE_TEXT, "") 91 | public var hx_ImportantString(default, set):GDString = "Initial String Value"; 92 | 93 | @:export 94 | function set_hx_ImportantString(_v:GDString):GDString { 95 | trace("Setting String to: " + _v); 96 | trace("Similarity to Foo: " + _v.similarity("Foo")); 97 | hx_ImportantString = _v; 98 | return _v; 99 | } 100 | 101 | // 102 | @:export 103 | @:hint(PropertyHint.PROPERTY_HINT_NONE, "suffix:m") 104 | @:subGroup("Random Properties", "hx_random") 105 | public var hx_random_MyVector3(default, default):Vector3 = new Vector3(1,2,3); 106 | 107 | // 108 | @:export 109 | @:hint(PropertyHint.PROPERTY_HINT_RESOURCE_TYPE, "Image") 110 | public var test_image(default, default):Image; 111 | 112 | // ... 113 | 114 | 115 | public function new() { 116 | super(); 117 | 118 | onHit = Signal.fromObjectSignal(this, "onHit"); 119 | onTest = Signal.fromObjectSignal(this, "onTest"); 120 | } 121 | 122 | //@:export // TODO: static function are not correctly bound at the moment 123 | public static function test() { 124 | trace("test called"); 125 | } 126 | 127 | @:export 128 | public function simple_func():Bool { 129 | trace("simple_func called"); 130 | return true; 131 | } 132 | 133 | @:export 134 | public function simple_add(_a:Int, _b:Float, _bool:Bool):Float { 135 | trace('simple_add called ($_a, $_b, $_bool)'); 136 | return _a + _b; 137 | } 138 | 139 | @:export 140 | public function simple_add_vector3(_v0:Vector3, _v1:Vector3):Vector3 { 141 | trace('simple_add_vector3 called ($_v0, $_v1)'); 142 | return _v0 + _v1; 143 | } 144 | 145 | @:export 146 | public function test_array(_v:PackedFloat32Array):PackedFloat32Array { 147 | trace("test_array:"); 148 | 149 | // use normal packedfloat32array index through api 150 | trace(_v[0]); 151 | trace(_v[1]); 152 | trace(_v[2]); 153 | 154 | // use raw data-ptr for fast access 155 | _v.data()[0] = 99; // modify in place 156 | trace(_v.data()[0]); 157 | 158 | // use haxe's float32array, makes memcpy 159 | var tmp:haxe.io.Float32Array = _v; 160 | trace(tmp[0]); 161 | trace(tmp[1] = 88); 162 | _v = tmp; 163 | 164 | return _v; 165 | } 166 | 167 | @:export 168 | public function test_bytes(_v:PackedByteArray):PackedByteArray { 169 | trace("test_bytes:"); 170 | 171 | trace(_v[0]); 172 | trace(_v[1]); 173 | 174 | _v.data()[1] = 44; // modify in place 175 | trace(_v.data()[1]); 176 | 177 | var tmp:haxe.io.Bytes = _v; 178 | trace(tmp.get(0) + ", " + tmp.get(1)); 179 | 180 | trace(tmp.get(0)); 181 | tmp.set(0, 55); 182 | trace(tmp.get(0)); 183 | trace(tmp.get(0) + ", " + tmp.get(1)); 184 | 185 | _v = tmp; 186 | 187 | return _v; 188 | } 189 | 190 | @:export 191 | public function test_strings(_v:PackedStringArray):PackedStringArray { 192 | trace("test_strings:"); 193 | 194 | // this uses managed types, dont do fancy pointer stuff here 195 | trace(_v[0]); 196 | trace(_v[1]); 197 | 198 | return _v; 199 | } 200 | 201 | @:export 202 | public function test_vector4i(_v:Vector4i):Vector4i { 203 | _v.x = 55; 204 | trace(_v.x); 205 | return _v; 206 | } 207 | 208 | @:export 209 | public function test_dict(_v:Dictionary):Dictionary { 210 | _v["foo"] = 99; 211 | trace(_v); 212 | return _v; 213 | } 214 | 215 | @:export 216 | function test_regexp():godot.RegEx { 217 | var re = new godot.RegEx(); 218 | re.compile("\\w-(\\d+)"); 219 | return re; 220 | } 221 | 222 | @:export 223 | function test_void():Void { 224 | trace("test_void"); 225 | } 226 | 227 | static var c = 0; 228 | override function _process(_delta:Float):Void { 229 | //trace('_process($_delta) called'); 230 | //trace(simple_add(10, _delta, false)); 231 | } 232 | 233 | override function _enter_tree():Void { 234 | trace("_enter_tree called: start"); 235 | var name:String = GDString.fromStringName(this.get_name()); 236 | this.print_tree_pretty(); 237 | trace(name); 238 | 239 | var node = new godot.Node(); 240 | node = null; 241 | 242 | onTest.emit(this); 243 | trace("_enter_tree called: end"); 244 | } 245 | 246 | /* 247 | override function _ready():Void { 248 | trace("_ready called"); 249 | //simple_func(); 250 | } 251 | 252 | 253 | 254 | override function _exit_tree():Void { 255 | trace("_exit_tree called"); 256 | } 257 | */ 258 | 259 | } -------------------------------------------------------------------------------- /tools/template/src/example/HxOther.hx: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import godot.variant.StringName; 4 | using StringTools; 5 | 6 | class HxOther extends godot.Node { 7 | 8 | static var someStringName:godot.variant.StringName = "test2"; 9 | 10 | var someNodePath2 = new godot.variant.NodePath(); 11 | 12 | public function new() { 13 | super(); 14 | } 15 | 16 | override function _ready() { 17 | trace('HxOther.$someStringName'); 18 | 19 | var stringName:StringName = "s"; 20 | trace(stringName == "s"); // true 21 | trace(stringName == ("s":StringName)); // true 22 | trace(stringName.toString() == "s"); // true 23 | trace(stringName.toString().length); // 1 24 | trace(stringName.toString().trim() == "s"); // true 25 | } 26 | 27 | @:export 28 | function onAreaEntered2(body:HxExample):Void { 29 | trace("area entered!"); 30 | trace(body); 31 | } 32 | 33 | @:export 34 | function onAreaEntered(body:godot.Node):godot.Node { 35 | trace("area entered!"); 36 | trace(body); 37 | return body; 38 | } 39 | 40 | @:export 41 | function onAreaEntered3(val:Int):Int { 42 | trace("area entered!"); 43 | trace(val); 44 | return val; 45 | } 46 | } -------------------------------------------------------------------------------- /tools/template/src/example/testPackage/HxOtherInPackage.hx: -------------------------------------------------------------------------------- 1 | package example.testPackage; 2 | 3 | class HxOtherInPackage extends godot.Node { 4 | public function new() { 5 | super(); 6 | } 7 | } -------------------------------------------------------------------------------- /tools/template/test.gd: -------------------------------------------------------------------------------- 1 | extends HxExample 2 | 3 | # Called when the node enters the scene tree for the first time. 4 | func _ready(): 5 | var res := simple_func() 6 | test_variant(res) 7 | 8 | var res2 := simple_add(69, 0.66, true) 9 | test_variant(res2 + 1) 10 | 11 | var res3 = simple_add_vector3(Vector3(400, 300, 500), Vector3(1, 2, 3)) 12 | test_variant(res3) 13 | print(res3) 14 | 15 | var arr = PackedFloat32Array([33.0,22.0,11.0]) 16 | print(arr) 17 | 18 | var arr2 = test_array(arr) 19 | print(arr2) 20 | 21 | var bytes = test_bytes(PackedByteArray([1,2])) 22 | print(bytes) 23 | 24 | var strings = test_strings(PackedStringArray(["was", "geht"])) 25 | print(strings) 26 | 27 | var vec4 = test_vector4i(Vector4i(11, 22, 33, 44)) 28 | print(vec4) 29 | 30 | var dict = {"test": 444, "foo": 77} 31 | print(dict) 32 | test_dict(dict) 33 | print(dict) 34 | 35 | var re = test_regexp() 36 | print("re: " + str(re)) 37 | var result = re.search("abc n-0123") 38 | print("result: " + str(result)) 39 | if (result): 40 | print(result.get_string()) # Would print n-0123 41 | 42 | # Called every frame. 'delta' is the elapsed time since the previous frame. 43 | func _process(_delta): 44 | #simple_add(69, _delta, true) 45 | pass 46 | 47 | # helper function 48 | func test_variant(res): 49 | match typeof(res): 50 | TYPE_NIL: 51 | prints("res is null", res) 52 | TYPE_BOOL: 53 | prints("res is a bool", res) 54 | TYPE_INT: 55 | prints("res is an integer", res) 56 | TYPE_FLOAT: 57 | prints("res is a float", res) 58 | TYPE_STRING: 59 | prints("res is a string", res) 60 | TYPE_VECTOR3: 61 | prints("res is a vector3", res) 62 | --------------------------------------------------------------------------------