diff --git a/.gitignore b/.gitignore index 7ed1b30..e06f7ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,14 @@ nimcache/ -.DS_Store + /godot/apigen/apigen /godot/apigen/apigen.exe +/godot/godotapigen +/godot/godotapigen.exe + +/docgen +/docs/docbuild +/docs/docbuild.exe +/docs/docpublish +/docs/docpublish.exe + +.DS_Store \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b0b27d4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,53 @@ +sudo: false +language: c +os: + - osx +compiler: clang +env: + global: + - secure: o+IZkRS6J7bGYkiilm10KDeCTDIVHszZ9dPvb93cdUKX/9hFVRiUjDOvNXqBdyOv43JIAsRTppym4B2pfcp9cwLoVBJNW70GKhp6ChLZm3wFdabScWKemuG2YtAUyGiSmxbVmUZ4baltnADyGFHuYWgHLjx6AKO26SqrXRLJ0I1IzGNKKNIfoyZzm7qdFDGJRnSC7L+y1pOITK7dpy60D1vat4FhOLaz2K7L8T8tZYZFK7yyxKduFUlY3cy4z3TpjxMa9/ksCiPiuPDN5xOrVIw0AtgZ2gYodZJUEnfaRzFkgcZ4OJuTAMNMalu52mVAVAoDt4yc7BnbtfsYJzfIjTeLjjWKWz8mqqp/HpxcfVnmPKxV5zeN8UhbosT8vNjwretWbQcFndzt0ohK7E8uMsnDGER7sGPEhCZCttkId96gi7Ro1awPIKCqLaMqB43Bwo48nnW0oQgrfWe1ZKtREXWI4F1F2GMbU8Jsvv0N5GnPGd4RDieBH5KIkJXcttAwRk8AUQ4U5PVkQ/OK9xm9BH2tB0vrjZ4FZWnFPapKVcPUYw9deyyXOXwSMmDpuwkJIjqi3tRyBWJG9+tUlAJw8zyFkCPeN9kzyVH/PhbacwBMdSxew24VLAWWCUhQHCP+fcjpKio8uDUFQN3javIRV4N3mHJ9v0VAF7Ixzh8AviQ= + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-3.9 + packages: + - build-essential + - scons + - pkg-config + - libx11-dev + - libxcursor-dev + - libasound2-dev + - libfreetype6-dev + - libgl1-mesa-dev + - libglu1-mesa-dev + - libssl-dev + - libxinerama-dev + - libxrandr-dev + +before_install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then rvm --default use 2.3; brew update; brew install scons ; fi + +install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export GODOT_PLATFORM=osx; else export GODOT_PLATFORM=x11; fi + - git clone --depth=1 https://github.com/nim-lang/Nim.git + - cd Nim + - git checkout devel + - sh ci/build.sh + - export PATH=$PATH:"`pwd`/bin" + - ./koch tools -d:release + - nimble install -y + - cd .. + - git clone --depth=1 https://github.com/godotengine/godot.git godotengine + - cd godotengine + - scons -j 3 platform=$GODOT_PLATFORM + - export GODOT_BIN="`pwd`/bin/godot.$GODOT_PLATFORM.tools.64" + - cd .. + +script: + - set -e + - mkdir godotapi + - nim c -d:release -r godot/godotapigen.nim "$GODOT_BIN" godotapi + - nim c -d:useRealtimeGc --path:godot -c godotapi/godotall.nim + - nim c -d:release -r docs/docpublish.nim diff --git a/.vscode/settings.json b/.vscode/settings.json index c26d7e1..6960f9a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,10 +6,10 @@ "files.eol": "\n", "files.trimTrailingWhitespace": true, "nim.project": ["godot/godot.nim", - "godot/apigen/apigen.nim"], + "godot/godotapigen.nim"], "nim.buildOnSave": false, "nim.lintOnSave": true, - "nim.licenseString": "# Copyright 2017 Xored Software, Inc.\n\n", + "nim.licenseString": "# Copyright 2018 Xored Software, Inc.\n\n", "files.exclude": { "**/nimcache/**": true } diff --git a/LICENSE b/LICENSE index 16a448a..07ecdb6 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ godot-nim - Nim bindings for Godot Engine The MIT License -Copyright (c) 2017 Xored Software Inc. +Copyright (c) 2018 Xored Software Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, diff --git a/README.md b/README.md index 90a3e1b..62e28d3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Nim bindings for Godot Engine -Nim bindings for Godot 3.0 based on [GDNative](https://godotengine.org/article/dlscript-here). +Nim bindings for Godot 3 based on [GDNative](https://godotengine.org/article/dlscript-here). -Documentation is coming. You can learn from the [sample project](examples/simple) in the meantime. +Documentation: https://pragmagic.github.io/godot-nim/ ## Links @@ -13,4 +13,4 @@ Documentation is coming. You can learn from the [sample project](examples/simple This project is licensed under the MIT license. Read [LICENSE](LICENSE) file for details. -Copyright (c) 2017 Xored Software, Inc. \ No newline at end of file +Copyright (c) 2018 Xored Software, Inc. diff --git a/docs/docbuild.nim b/docs/docbuild.nim new file mode 100644 index 0000000..477c45b --- /dev/null +++ b/docs/docbuild.nim @@ -0,0 +1,161 @@ +# Copyright 2018 Xored Software, Inc. + +import threadpool, os, osproc, strutils, sequtils, pegs + +import "../godot/godotapigen.nim" + +const dirs = ["godot"/"core", "godot"/"internal", "godot"/"nim"] +const files = ["godot"/"godotapigen.nim", "godot"/"godotinternal.nim", + "godot"/"godot.nim"] +const indexFile = "docs"/"index.rst" +const gitHubUrl = "https://github.com/pragmagic/godot-nim" + +proc outName(outDir, file: string): string = + outDir / file.extractFilename().changeFileExt("html") + +template quoted(s: string): string = + ('"' & s & '"') + +proc execOrFail(cmd: string) = + echo "[exec] " & cmd + let ret = execShellCmd(cmd) + if ret != 0: + raise newException( + Exception, "Command quit with exit code " & $ret & ": " & cmd) + +template withDir(dir: string, body: typed) = + let curDir = getCurrentDir() + setCurrentDir(dir) + try: + body + finally: + setCurrentDir(curDir) + +iterator walkDirRec(dir: string, filter: set[PathComponent], + extensions: openarray[string]): string = + for file in walkDirRec(dir, filter): + if not extensions.anyIt(file.endsWith(it)): continue + yield file + +proc genApiFiles(targetDir, godotBin: string) = + let jsonFile = targetDir / "api.json" + try: + execOrFail(quoted(godotBin) & + " --gdnative-generate-json-api " & quoted(jsonFile)) + except: + # this fails unstably even if api.json is created successfully + discard + if not fileExists(jsonFile): + raise newException(Exception, "Failed to generate Godot API wrappers") + + genApi(targetDir, jsonFile) + + writeFile(targetDir / "nim.cfg", "path=\"$projectdir/../../godot\"") + +proc extractVersion(nimbleFile: string): string = + let contents = readFile(nimbleFile) + var matches: array[1, string] + doAssert match(contents, peg"""'version' \s* '=' \s* '"' {@} '"' """, matches) + result = matches[0] + +proc fixupHrefs(file: string) = + var contents = readFile(file) + contents = contents.replacef( + peg"""'href="' ('internal'/'core'/'nim') '/' {@} '"' """, + "href=\"$#\"") + if file.contains("godotapi"): + contents = contents.replacef( + peg"""'href="' {('godotinternal' / 'godot') '.html"'} """, + "href=\"../$#") + writeFile(file, contents) + +proc getGitHash(): string = + result = execProcess("git rev-parse HEAD") + if result.len > 0: + result = result.replace("\L", "").replace("\r", "") + +proc buildDocs*(outDir, godotNimDir, godotBin: string) = + removeDir(outDir) + createDir(outDir) + let outDirAbs = expandFilename(outDir) + let godotBinAbs = expandFilename(godotBin) + + setCurrentDir(godotNimDir) + + let godotNimVersion = extractVersion("godot.nimble") + putEnv("godotnimversion", godotNimVersion) + putEnv("godotnimgithub", gitHubUrl) + let gitCommit = getGitHash() + + var allNimFiles = newSeq[string]() + allNimFiles.add(files) + for dir in dirs: + for file in walkDirRec(dir, {pcFile, pcDir}, [".nim"]): + allNimFiles.add(file) + for file in allNimFiles: + spawn execOrFail( + "nim doc -d:useRealtimeGc --path:godot -o:" & + quoted(outName(outDirAbs, file)) & + " --git.url:" & quoted(gitHubUrl) & + " --git.commit:" & quoted(gitCommit) & + ' ' & quoted(file)) + + let godotApiFolder = outDirAbs / "godotapi" + createDir(godotApiFolder) + genApiFiles(godotApiFolder, godotBinAbs) + for file in walkDirRec(godotApiFolder, {pcFile, pcDir}, [".nim"]): + spawn execOrFail("nim doc -d:useRealtimeGc --path:godot -o:" & + quoted(outName(godotApiFolder, file)) & ' ' & quoted(file)) + + sync() + + var gitHash: string + withDir(godotBinAbs.parentDir()): + gitHash = getGitHash() + if gitHash.len == 0: + raise newException(Exception, + "Godot executable is not under Git repository") + + var indexContent = readFile(indexFile) + var apiList = newStringOfCap(4096) + for file in walkDirRec(godotApiFolder, {pcFile, pcDir}): + if not file.endsWith(".html"): + removeFile(file) + else: + let moduleHtml = file.extractFileName() + let moduleName = moduleHtml.changeFileExt("") + apiList.add("* `" & moduleName & " `_\L") + indexContent = indexContent.replace("$GODOTAPI_CHANGESET_HASH", gitHash). + replace("$AUTO_GENERATED_GODOTAPI_LIST", apiList). + replace("$GODOTNIM_GITHUB_URL", gitHubUrl) + + let tmpRst = outDirAbs/"index.rst" + writeFile(tmpRst, indexContent) + try: + execOrFail("nim rst2html -o:" & quoted(outName(outDirAbs, tmpRst)) & + ' ' & quoted(tmpRst)) + finally: + removeFile(tmpRst) + + for file in walkDirRec(outDir, {pcFile, pcDir}, [".html"]): + spawn fixupHrefs(file) + + sync() + +when isMainModule: + const outDir = "docgen" + + if not fileExists("godot.nimble"): + echo "Must be executed from godot-nim root dir" + quit(-1) + + let godotBin = getEnv("GODOT_BIN") + if godotBin.len == 0: + echo "GODOT_BIN environment variable must point to Godot executable" + quit(-1) + + try: + buildDocs(outDir, getCurrentDir(), godotBin) + except: + echo getCurrentExceptionMsg() + quit(-1) diff --git a/docs/docpublish.nim b/docs/docpublish.nim new file mode 100644 index 0000000..e55974c --- /dev/null +++ b/docs/docpublish.nim @@ -0,0 +1,97 @@ +# Copyright 2018 Xored Software, Inc. + +import os, pegs, strutils +import docbuild + +const indexTemplate = """ +godot-nim docs index + +

Documentation of Nim bindings for Godot Engine (GitHub)


+$VERSION_LIST + + +""" + +proc execOrQuit(cmd: string) = + let ret = execShellCmd(cmd) + if ret != 0: + quit(ret) + +proc walkDirRecRelative(dir: string, cb: proc (file: string), start = "") = + for kind, path in walkDir(dir, relative = true): + if kind in {pcFile, pcLinkToFile}: + cb(if start.len > 0: start / path else: path) + elif kind in {pcDir, pcLinkToDir}: + let fullPath = if start.len > 0: start / path else: path + walkDirRecRelative(dir / fullPath, cb, fullPath) + +proc publish(docDir, gitHubToken, repoSlug, branch, tag, changeset: string) = + let release = if branch == "master": branch else: tag + let commitComment = if release == "master": + "Update master documentation for changeset " & changeset + else: + "Update documentation for " & tag + + const repoDir = "gh-pages" + execOrQuit( + "git clone --depth=1 --branch=gh-pages https://github.com/$#.git $#" % + [repoSlug, repoDir]) + try: + removeDir(repoDir/release) + createDir(repoDir/release) + var versionList = newStringOfCap(4096) + for kind, path in walkDir(repoDir, relative = true): + if kind == pcDir and not path.startsWith("."): + versionList.add("$1
" % path) + let index = indexTemplate.replace("$REPO_SLUG", repoSlug). + replace("$VERSION_LIST", versionList) + writeFile(repoDir/"index.html", index) + + walkDirRecRelative(docDir) do (file: string): + createDir(parentDir(repoDir/release/file)) + copyFile(docDir/file, repoDir/release/file) + + setCurrentDir(repoDir) + try: + execOrQuit("git add --all") + execOrQuit("git commit -m \"$#\"" % commitComment) + execOrQuit("git push -fq \"https://$#@github.com/$#.git\" gh-pages" % + [gitHubToken, repoSlug]) + finally: + setCurrentDir("..") + finally: + removeDir(repoDir) + +when isMainModule: + proc getEnvOrQuit(key: string): string = + result = getEnv(key) + if result.len == 0: + echo "Expected environment variable: " & key + quit(1) + + let pr = getEnv("TRAVIS_PULL_REQUEST") + if pr.len > 0 and pr != "false": + echo "This is a PR build. Skipping." + quit(0) + + let repoSlug = getEnvOrQuit("TRAVIS_REPO_SLUG") + let branch = getEnvOrQuit("TRAVIS_BRANCH") + let changeset = getEnvOrQuit("TRAVIS_COMMIT") + let tag = getEnv("TRAVIS_TAG") + + # let repoSlug = "pragmagic/godot-nim" + # let branch = "master" + # let changeset = "0fd0101432c1fed1004f50b035fcf74f75f004a8" + # let tag = "" + + let gitHubToken = getEnvOrQuit("GITHUB_TOKEN") + + if branch != "master" and not (tag =~ peg"^ 'v' \d+ '.' \d+ '.' \d+ $"): + echo "This is not master or tagged changeset. Skipping." + quit(0) + + let godotBin = getEnvOrQuit("GODOT_BIN") + + const docDir = "docgen" + buildDocs(docDir, getCurrentDir(), godotBin) + publish(docDir, gitHubToken, repoSlug, branch, tag, changeset) diff --git a/docs/godotapi.rst b/docs/godotapi.rst new file mode 100644 index 0000000..9bea41d --- /dev/null +++ b/docs/godotapi.rst @@ -0,0 +1,12 @@ +=============== +Godot API (Nim) +=============== + +:Godot Git Hash: |godothash| + +.. contents:: + +This is an auto-generated index of Godot API. It's built from Git changeset +$GODOTAPI_CHANGESET_HASH. + +$AUTO_GENERATED_GODOTAPI_LIST \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..e14d38d --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,173 @@ +============================= +Nim bindings for Godot Engine +============================= + +:Author: Ruslan Mustakov +:Version: |godotnimversion| +:GitHub: `$GODOTNIM_GITHUB_URL <$GODOTNIM_GITHUB_URL>`_ +:License: MIT + +.. contents:: + +``godot-nim`` library allows to create games on +`Godot Engine `_ with +`Nim programming language `_. Nim is a statically typed +language with an elegant Python-like syntax that compiles to native code. +It is garbage-collected, but its GC supports real-time mode which this library +makes use of. It means the GC will never run during game frames and will use +fixed amount of frame idle time to collect garbage. This leads to no stalls +and close to zero compromise on performance comparing to native languages with +manual memory management. + +If you are not familiar with Nim yet, it is recommended to go through the +`official tutorial `_. + +`VSCode `_ is the recommended editor for +working with Nim code. It is cross-platform and has the excellent +`nim plugin `_ +that supports most of the features you would expect from an IDE. +It also has `godot-tools plugin `_ +which adds features for editing GDScript and Godot resource files. + + +Getting Started +=============== + +Getting Godot +-------------- + +The library requires Godot version 3.0, which you can get here: +https://godotengine.org/download + +Installing Nim +------------- + +The library requires Nim version 0.18.0 or newer, which you can get here: +https://nim-lang.org/install.html + +Make sure you also have ``nimble`` (Nim's package manager) installed. + +Creating Project +---------------- + +The fastest way to set up a Godot-Nim project is to use the existing stub: + +.. code-block:: bash + git clone --depth=1 https://github.com/pragmagic/godot-nim-stub.git myproject + +(you can then delete the .git directory within to untie the project from the +stub repository) + +The stub contains the necessary build configuration to compile your code for +desktop and mobile platforms, as well as a couple of very simple scenes to +help you get started. Consult the stub's `README +`_ for information about +compiling the project. + + +Adding Nim to Existing Project +------------------------------ + +If you would like to use Nim in an existing project: + +1. Copy ``nakefile.nim`` file and ``src`` directory from the stub described + in the previous section above your Godot project folder. Adjust paths in + build scripts (``nakefile.nim``, ``src/stub.nimble``) according to your + own project structure. + +2. Copy ``nimlib.gdnlib`` to your Godot project folder. It is a + GDNative library resource that contains paths to dynamic libraries + compiled by Nim. + +Next Steps +---------- + +Once you are familiarized with the build process (it's as simple as running +``nake build`` after you are set up), it is recommended to go through +`godotmacros `_ and `godotnim `_ module +documentations. They describe special macros and procedures needed to define +or instantiate Godot objects. After you learned that, the rest is similar to +using any Nim library. These bindings do not limit any of Nim's capabilities, +and you can use any Nim types as fields or parameters of Godot objects and +their procedures (but, obviously, you may not be able to export some of them +to Godot editor or GDScript, unless you define your own converters). + + +Modules +======= + +The binding library consists of three major modules: + +* `godot <#modules-godot-module>`_ - Contains core types and macro definitions. + You need to import this in any module that defines or makes use of Godot + types. + +* `godotinternal <#modules-godotinternal-module>`_ - Contains raw wrappers over + few core types, such as ``GodotVariant``, ``GodotString``, ``GodotNodePath``, + ``GodotDictionary``, pool arrays. These are used by ``godotapigen`` and macro + implementations, and you don't have to use them at all in your code, unless + you want to go into low-level details for some reason. Each of those types + needs to be destructed manually with ``deinit`` procedure. + +* `godotapigen `_ - Wrapper generator based on data from + Godot's ``ClassDB``. You only need to use it as a part of the build process. + + +godot Module +------------ + +Contains core types and macro definitions. You need to import this in any +module that defines or makes use of Godot types. The sumbodules below are +exported and you don't have to import any of them directly. + +* `godotnim `_ Defines ``NimGodotObject`` and Varaint converters + for standard Nim types. +* `godotmacros `_ Defines ``gdobj`` macro for defining + Godot objects. +* `variants `_ ``Variant`` type represents a "dynamic object" + that many Godot procedures make use of. +* `arrays `_ Defines ``Array`` of Variants. +* `basis `_ Defines 3D ``Basis``. +* `colors `_ Defines ARGB ``Color``. +* `dictionaries `_ Defines ``Variant`` -> ``Variant`` + ``Dictionary``. +* `nodepaths `_ Defines ``NodePath`` - a path to a ``Node``. +* `planes `_ Defines 3D ``Plane``. +* `poolarrays `_ Defines pooled arrays: ``PoolByteArray``, + ``PoolIntArray``, ``PoolRealArray``, ``PoolVector2Array``, + ``PoolVector3Array``, ``PoolColorArray``, ``PoolStringArray``. +* `quats `_ Defines ``Quat`` (quaternion) describing object + rotation in 3D space. +* `rect2 `_ Defines ``Rect2`` - a 2D rectangle. +* `aabb `_ Defines ``AABB`` - a 3D box. +* `rids `_ Defines ``RID`` - a resource identifier. +* `transform2d `_ Defines ``Transform2D``. +* `transforms `_ Defines ``Transform``. +* `vector2 `_ Defines ``Vector2``. +* `vector3 `_ Defines ``Vector3``. +* `godotbase `_ Defines ``Error`` type and few common math + procedures missing in Nim's standard library. + + +Godot API +--------- + +This is an auto-generated list of Godot API modules. It's built from Godot +changeset `$GODOTAPI_CHANGESET_HASH +`_. + +$AUTO_GENERATED_GODOTAPI_LIST + + +godotinternal Module +-------------------- + +Contains low-level wrappers over Godot types that require manual memory +management. This module is used within ``godot-nim`` implementation and you +don't need to import it unless you know what you are doing. + +* `godotdictionaries `_ +* `godotnodepaths `_ +* `godotpoolarrays `_ +* `godotstrings `_ +* `godotvariants `_ diff --git a/docs/nim.cfg b/docs/nim.cfg new file mode 100644 index 0000000..9d57ecf --- /dev/null +++ b/docs/nim.cfg @@ -0,0 +1 @@ +--threads:on \ No newline at end of file diff --git a/examples/simple/.gitignore b/examples/simple/.gitignore deleted file mode 100644 index 7bb79bb..0000000 --- a/examples/simple/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/project/.import -/project/_dlls -/nakefile -/godotapi -nimcache diff --git a/examples/simple/README.md b/examples/simple/README.md deleted file mode 100644 index 9eb7cb4..0000000 --- a/examples/simple/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Simple project just to demonstrate usage of the library. - -Prerequisites: - -1. Install [nake](https://github.com/fowlmouth/nake): `nimble install nake -n`. -2. Ensure `~/.nimble/bin` is in your PATH. -3. Set `GODOT_BIN` environment varible to point to Godot executable (currently requires Godot fork - see below). -4. Install godot-nim: `nimble install https://github.com/pragmagic/godot-nim.git` (needed for nakefile) - -Run `nake build` in this directory to compile for the current platform. - -**NOTE:** Currently this only works with `kingdom` branch of Godot fork: https://github.com/endragor/godot. However, there are pending PRs to make this work with Godot mainline version. \ No newline at end of file diff --git a/examples/simple/nakefile.nim b/examples/simple/nakefile.nim deleted file mode 100644 index 8b4c033..0000000 --- a/examples/simple/nakefile.nim +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -import nake -import os, ospaths, times -import apigen.apigen - -proc cmdParams(): string = - let params = commandLineParams() - assert(params.len > 0) - result = params[1.. jsonFile.getLastModificationTime(): - direShell(godotBin, "--gdnative-generate-json-api", jsonFile) - if not fileExists(jsonFile): - echo "Failed to generate api.json" - quit(-1) - - genApi(targetDir, jsonFile) - -task "build", "Builds the client for the current platform": - genGodotApi() - withDir "src": - direShell("nimble", "make") - -task "clean", "Remove files produced by build": - removeDir("nimcache") - removeDir("src"/"nimcache") - removeDir("godotapi") - removeDir("project"/"_dlls") - removeFile("nakefile") diff --git a/examples/simple/project/default_env.tres b/examples/simple/project/default_env.tres deleted file mode 100644 index a22ed59..0000000 --- a/examples/simple/project/default_env.tres +++ /dev/null @@ -1,99 +0,0 @@ -[gd_resource type="Environment" load_steps=2 format=2] - -[sub_resource type="ProceduralSky" id=1] - -radiance_size = 4 -sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) -sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) -sky_curve = 0.25 -sky_energy = 1.0 -ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) -ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) -ground_curve = 0.01 -ground_energy = 1.0 -sun_color = Color( 1, 1, 1, 1 ) -sun_latitude = 35.0 -sun_longitude = 0.0 -sun_angle_min = 1.0 -sun_angle_max = 100.0 -sun_curve = 0.05 -sun_energy = 16.0 -texture_size = 2 - -[resource] - -background_mode = 2 -background_sky = SubResource( 1 ) -background_sky_scale = 1.0 -background_color = Color( 0, 0, 0, 1 ) -background_energy = 1.0 -background_canvas_max_layer = 0 -ambient_light_color = Color( 0, 0, 0, 1 ) -ambient_light_energy = 1.0 -ambient_light_sky_contribution = 0.0 -fog_enabled = false -fog_color = Color( 0.5, 0.6, 0.7, 1 ) -fog_sun_color = Color( 1, 0.9, 0.7, 1 ) -fog_sun_amount = 0.0 -fog_depth_enabled = true -fog_depth_begin = 10.0 -fog_depth_curve = 1.0 -fog_transmit_enabled = false -fog_transmit_curve = 1.0 -fog_height_enabled = false -fog_height_min = 0.0 -fog_height_max = 100.0 -fog_height_curve = 1.0 -tonemap_mode = 0 -tonemap_exposure = 1.0 -tonemap_white = 1.0 -auto_exposure_enabled = false -auto_exposure_scale = 0.4 -auto_exposure_min_luma = 0.05 -auto_exposure_max_luma = 8.0 -auto_exposure_speed = 0.5 -ss_reflections_enabled = false -ss_reflections_max_steps = 64 -ss_reflections_fade_in = 0.15 -ss_reflections_fade_out = 2.0 -ss_reflections_depth_tolerance = 0.2 -ss_reflections_roughness = true -ssao_enabled = false -ssao_radius = 1.0 -ssao_intensity = 1.0 -ssao_radius2 = 0.0 -ssao_intensity2 = 1.0 -ssao_bias = 0.01 -ssao_light_affect = 0.0 -ssao_color = Color( 0, 0, 0, 1 ) -ssao_blur = true -dof_blur_far_enabled = false -dof_blur_far_distance = 10.0 -dof_blur_far_transition = 5.0 -dof_blur_far_amount = 0.1 -dof_blur_far_quality = 1 -dof_blur_near_enabled = false -dof_blur_near_distance = 2.0 -dof_blur_near_transition = 1.0 -dof_blur_near_amount = 0.1 -dof_blur_near_quality = 1 -glow_enabled = false -glow_levels/1 = false -glow_levels/2 = false -glow_levels/3 = true -glow_levels/4 = false -glow_levels/5 = true -glow_levels/6 = false -glow_levels/7 = false -glow_intensity = 0.8 -glow_strength = 1.0 -glow_bloom = 0.0 -glow_blend_mode = 2 -glow_hdr_threshold = 1.0 -glow_hdr_scale = 2.0 -glow_bicubic_upscale = false -adjustment_enabled = false -adjustment_brightness = 1.0 -adjustment_contrast = 1.0 -adjustment_saturation = 1.0 - diff --git a/examples/simple/project/fonts/Roboto/RobotoRegular.tres b/examples/simple/project/fonts/Roboto/RobotoRegular.tres deleted file mode 100644 index a1126e5..0000000 --- a/examples/simple/project/fonts/Roboto/RobotoRegular.tres +++ /dev/null @@ -1,5 +0,0 @@ -[gd_resource type="DynamicFontData" format=2] - -[resource] - -font_path = "res://fonts/Roboto/ttf/Roboto-Regular.ttf" diff --git a/examples/simple/project/fonts/Roboto/ttf/LICENSE.txt b/examples/simple/project/fonts/Roboto/ttf/LICENSE.txt deleted file mode 100755 index 75b5248..0000000 --- a/examples/simple/project/fonts/Roboto/ttf/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/examples/simple/project/fonts/Roboto/ttf/Roboto-Regular.ttf b/examples/simple/project/fonts/Roboto/ttf/Roboto-Regular.ttf deleted file mode 100755 index 2c97eea..0000000 Binary files a/examples/simple/project/fonts/Roboto/ttf/Roboto-Regular.ttf and /dev/null differ diff --git a/examples/simple/project/fps_counter.tscn b/examples/simple/project/fps_counter.tscn deleted file mode 100644 index 67fc001..0000000 --- a/examples/simple/project/fps_counter.tscn +++ /dev/null @@ -1,34 +0,0 @@ -[gd_scene load_steps=4 format=2] - -[ext_resource path="res://fonts/Roboto/RobotoRegular.tres" type="DynamicFontData" id=1] -[ext_resource path="res://scripts/FPSCounter.gdns" type="Script" id=2] - -[sub_resource type="DynamicFont" id=1] - -size = 40 -use_mipmaps = false -use_filter = false -font_data = ExtResource( 1 ) -_sections_unfolded = [ "Extra Spacing", "Font", "Settings" ] - -[node name="Label" type="Label"] - -anchor_left = 1 -anchor_right = 1 -margin_top = 10.0 -margin_right = 10.0 -grow_horizontal = 0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -size_flags_horizontal = 1 -size_flags_vertical = 4 -custom_fonts/font = SubResource( 1 ) -text = "FPS: 9000" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 -script = ExtResource( 2 ) -_sections_unfolded = [ "Anchor", "Grow Direction", "Margin", "custom_colors", "custom_fonts" ] - - diff --git a/examples/simple/project/icon.png b/examples/simple/project/icon.png deleted file mode 100644 index 21a097a..0000000 Binary files a/examples/simple/project/icon.png and /dev/null differ diff --git a/examples/simple/project/icon.png.import b/examples/simple/project/icon.png.import deleted file mode 100644 index 627820b..0000000 --- a/examples/simple/project/icon.png.import +++ /dev/null @@ -1,23 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -stream=false -size_limit=0 -detect_3d=true diff --git a/examples/simple/project/main.tscn b/examples/simple/project/main.tscn deleted file mode 100644 index 7e4e390..0000000 --- a/examples/simple/project/main.tscn +++ /dev/null @@ -1,50 +0,0 @@ -[gd_scene load_steps=5 format=2] - -[ext_resource path="res://scripts/MainPanel.gdns" type="Script" id=1] -[ext_resource path="res://fonts/Roboto/RobotoRegular.tres" type="DynamicFontData" id=2] -[ext_resource path="res://fps_counter.tscn" type="PackedScene" id=3] - -[sub_resource type="DynamicFont" id=1] - -size = 80 -use_mipmaps = false -use_filter = false -font_data = ExtResource( 2 ) -_sections_unfolded = [ "Font", "Settings" ] - -[node name="Panel" type="Panel"] - -anchor_right = 1 -anchor_bottom = 1 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -script = ExtResource( 1 ) -_sections_unfolded = [ "Anchor", "Margin" ] - -[node name="Label" type="Label" parent="."] - -anchor_right = 1 -anchor_bottom = 1 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -size_flags_horizontal = 1 -size_flags_vertical = 4 -custom_fonts/font = SubResource( 1 ) -text = "Click me to load scene" -align = 1 -valign = 1 -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 -_sections_unfolded = [ "Anchor", "Margin", "custom_fonts" ] - -[node name="FPS" parent="." instance=ExtResource( 3 )] - -margin_left = 189.0 -margin_bottom = 58.0 - - diff --git a/examples/simple/project/nimlib.tres b/examples/simple/project/nimlib.tres deleted file mode 100644 index f95a4f3..0000000 --- a/examples/simple/project/nimlib.tres +++ /dev/null @@ -1,12 +0,0 @@ -[gd_resource type="GDNativeLibrary" format=2] - -[resource] - -platform/X11_32bit = "res://_dlls/nim_linux_32.so" -platform/X11_64bit = "res://_dlls/nim_linux_64.so" -platform/Windows_32bit = "res://_dlls/nim_32.dll" -platform/Windows_64bit = "res://_dlls/nim_64.dll" -platform/OSX = "res://_dlls/nim_mac.dylib" -platform/Android = "res://_dlls/nim_android.so" -platform/iOS = "res://_dlls/nim_ios.dylib" -platform/WebAssembly = "" diff --git a/examples/simple/project/project.godot b/examples/simple/project/project.godot deleted file mode 100644 index 009f1e5..0000000 --- a/examples/simple/project/project.godot +++ /dev/null @@ -1,14 +0,0 @@ -config_version=3 -[application] - -config/name="Simple Sample" -run/main_scene="res://main.tscn" -config/icon="res://icon.png" - -[autoload] - -NimRuntime="*res://scripts/NimRuntime.gdns" - -[rendering] - -environment/default_environment="res://default_env.tres" diff --git a/examples/simple/project/scene.tscn b/examples/simple/project/scene.tscn deleted file mode 100644 index 07b4429..0000000 --- a/examples/simple/project/scene.tscn +++ /dev/null @@ -1,48 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://fps_counter.tscn" type="PackedScene" id=1] - -[sub_resource type="CapsuleMesh" id=1] - -radius = 1.0 -mid_height = 1.0 -radial_segments = 64 -rings = 8 - -[node name="Node" type="Node"] - -[node name="MeshInstance" type="MeshInstance" parent="."] - -layers = 1 -material_override = null -cast_shadow = 1 -extra_cull_margin = 0.0 -visible_in_all_rooms = false -use_in_baked_light = false -lod_min_distance = 0.0 -lod_min_hysteresis = 0.0 -lod_max_distance = 0.0 -lod_max_hysteresis = 0.0 -mesh = SubResource( 1 ) -skeleton = NodePath("..") -material/0 = null -_sections_unfolded = [ "Geometry", "material" ] - -[node name="Label" parent="." instance=ExtResource( 1 )] - -[node name="Camera" type="Camera" parent="."] - -transform = Transform( 0.930689, 0.16529, -0.326338, 0, 0.892097, 0.451845, 0.365811, -0.420527, 0.830265, -0.972205, 1.19673, 2.59579 ) -projection = 0 -fov = 65.0 -near = 0.1 -far = 100.0 -keep_aspect = 1 -current = true -cull_mask = 1048575 -environment = null -h_offset = 0.0 -v_offset = 0.0 -doppler/tracking = 0 - - diff --git a/examples/simple/project/scripts/FPSCounter.gdns b/examples/simple/project/scripts/FPSCounter.gdns deleted file mode 100644 index bae69db..0000000 --- a/examples/simple/project/scripts/FPSCounter.gdns +++ /dev/null @@ -1,9 +0,0 @@ -[gd_resource type="NativeScript" load_steps=2 format=2] - -[ext_resource path="res://nimlib.tres" type="GDNativeLibrary" id=1] - -[resource] - -resource_name = "FPSCounter" -library = ExtResource( 1 ) -class_name = "FPSCounter" \ No newline at end of file diff --git a/examples/simple/project/scripts/MainPanel.gdns b/examples/simple/project/scripts/MainPanel.gdns deleted file mode 100644 index 4458a47..0000000 --- a/examples/simple/project/scripts/MainPanel.gdns +++ /dev/null @@ -1,9 +0,0 @@ -[gd_resource type="NativeScript" load_steps=2 format=2] - -[ext_resource path="res://nimlib.tres" type="GDNativeLibrary" id=1] - -[resource] - -resource_name = "MainPanel" -library = ExtResource( 1 ) -class_name = "MainPanel" \ No newline at end of file diff --git a/examples/simple/project/scripts/NimRuntime.gdns b/examples/simple/project/scripts/NimRuntime.gdns deleted file mode 100644 index 34656e9..0000000 --- a/examples/simple/project/scripts/NimRuntime.gdns +++ /dev/null @@ -1,9 +0,0 @@ -[gd_resource type="NativeScript" load_steps=2 format=2] - -[ext_resource path="res://nimlib.tres" type="GDNativeLibrary" id=1] - -[resource] - -resource_name = "NimRuntime" -library = ExtResource( 1 ) -class_name = "NimRuntime" \ No newline at end of file diff --git a/examples/simple/src/config.nims b/examples/simple/src/config.nims deleted file mode 100644 index 1f1cdf3..0000000 --- a/examples/simple/src/config.nims +++ /dev/null @@ -1,43 +0,0 @@ -import ospaths - -switch("nimcache", "nimcache"/hostOS/hostCPU) - -when defined(macosx): - switch("passL", "-framework Cocoa -Wl,-undefined,dynamic_lookup") -elif defined(android): - let ndk = getEnv("ANDROID_NDK_ROOT") - let toolchain = getEnv("ANDROID_TOOLCHAIN") - - if ndk.len == 0: - raise newException(OSError, - "ANDROID_NDK_ROOT environment variable is necessary for android build") - if toolchain.len == 0: - raise newException(OSError, - "ANDROID_TOOLCHAIN environment variable is necessary for android build") - - const level = $16 # change this to the necessary API level - const arch = "arm" - let sysroot = "--sysroot=\"" & ndk & "/platforms/android-" & level & "/arch-" & arch & "/\"" - switch("passL", sysroot) - switch("passC", sysroot) - - switch("cc", "clang") - switch("arm.linux.clang.path", toolchain / "bin") - switch("arm.linux.clang.exe", arch & "-linux-androideabi-clang") - switch("arm.linux.clang.compilerexe", arch & "-linux-androideabi-clang") - switch("arm.linux.clang.linkerexe", arch & "-linux-androideabi-clang") -elif defined(windows): - assert(sizeof(int) == 8) - switch("cc", "vcc") - let godotLib = getEnv("GODOT_LIB") - if godotLib.len == 0: - raise newException(OSError, - "GODOT_LIB must be specified and point to the .lib file") - switch("clib", godotLib.changeFileExt("")) -elif defined(linux): - switch("passC", "-fPIC") -else: - raise newException(OSError, "Unsupported platform: " & hostOS) - -when not defined(release): - switch("debugger", "native") diff --git a/examples/simple/src/fpscounter.nim b/examples/simple/src/fpscounter.nim deleted file mode 100644 index 2227513..0000000 --- a/examples/simple/src/fpscounter.nim +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -import strutils -import godot -import engine, label, resource_loader, packed_scene - -gdobj FPSCounter of Label: - var lastFPS: float32 - - method ready*() = - setProcess(true) - - method process*(delta: float64) = - let fps = getFramesPerSecond() - if int(fps * 10) != int(lastFPS * 10): - lastFPS = fps - self.text = "FPS: " & formatFloat(fps, ffDecimal, 1) diff --git a/examples/simple/src/mainpanel.nim b/examples/simple/src/mainpanel.nim deleted file mode 100644 index 8f6c16e..0000000 --- a/examples/simple/src/mainpanel.nim +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -import godot -import scene_tree, resource_loader, packed_scene, panel, global_constants, - input_event_mouse_button - -gdobj MainPanel of Panel: - method ready*() = - setProcessInput(true) - - method input*(event: InputEvent) = - if event of InputEventMouseButton: - let ev = event as InputEventMouseButton - if ev.buttonIndex == BUTTON_LEFT: - getTree().setInputAsHandled() - let scene = load("res://scene.tscn") as PackedScene - getTree().getRoot().addChild(scene.instance()) - queueFree() diff --git a/examples/simple/src/nim.cfg b/examples/simple/src/nim.cfg deleted file mode 100644 index a64088d..0000000 --- a/examples/simple/src/nim.cfg +++ /dev/null @@ -1,8 +0,0 @@ ---path:"$projectdir" ---path:"$projectdir/../godotapi" ---experimental ---app:lib ---stackTrace:on --d:useRealtimeGc ---noMain ---warning[LockLevel]:off \ No newline at end of file diff --git a/examples/simple/src/simple.nim b/examples/simple/src/simple.nim deleted file mode 100644 index 5e725b8..0000000 --- a/examples/simple/src/simple.nim +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -## Import independent scene objects here -## (no need to import everything, just independent roots) - -when not defined(release): - import segfaults # converts segfaults into NilAccessError - -import nimruntime - -import fpscounter -import mainpanel diff --git a/examples/simple/src/simple.nimble b/examples/simple/src/simple.nimble deleted file mode 100644 index 22c3f19..0000000 --- a/examples/simple/src/simple.nimble +++ /dev/null @@ -1,34 +0,0 @@ -version = "0.1.0" -author = "Xored Software, Inc." -description = "Simple Sample" -license = "MIT" -bin = @["simple"] - -requires "https://github.com/pragmagic/godot-nim.git >= 0.3.0 & < 0.4.0" - -task make, "build": - const archPostfix = when sizeof(int) == 8: "_64" else: "_32" - const libFile = - when defined(windows): - "nim" & archPostfix & ".dll" - elif defined(ios): - "nim_ios.dylib" - elif defined(macosx): - "nim_mac.dylib" - elif defined(android): - "nim_android.so" - elif defined(linux): - "nim_linux" & archPostfix & ".so" - else: nil - if libFile.isNil: - raise newException(OSError, "Unsupported platform") - - exec "nimble build -y" - const dir = "../project/_dlls/" - const target = dir & libFile - mkDir(dir) - when defined(windows): - rmFile(target) - mvFile(bin[0] & ".exe", target) - else: - mvFile(bin[0], target) diff --git a/godot.nimble b/godot.nimble index 1788bf7..d7ca12b 100644 --- a/godot.nimble +++ b/godot.nimble @@ -1,7 +1,7 @@ -version = "0.3.0" +version = "0.8.2" author = "Xored Software, Inc." description = "Godot Engine bindings" license = "MIT" srcDir = "godot" -requires "nim >= 0.17.0", "compiler >= 0.17.0" \ No newline at end of file +requires "nim >= 0.17.3", "compiler >= 0.17.3" \ No newline at end of file diff --git a/godot/apigen/apigen.nim b/godot/apigen/apigen.nim deleted file mode 100644 index 295fd58..0000000 --- a/godot/apigen/apigen.nim +++ /dev/null @@ -1,875 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -import streams, json, ospaths, strutils, times, sets, tables -import sequtils, algorithm -import compiler / [ast, renderer, idents, astalgo] - -proc ident(ident: string): PNode = - result = newNode(nkIdent) - result.ident = getIdent(ident) - -proc addChain(node: PNode, others: varargs[PNode]): PNode {.discardable.} = - for other in others: - node.add(other) - result = node - -proc newIdentDefs(name, typ: PNode, - defaultVal: PNode = nil): PNode = - result = newNode(nkIdentDefs) - result.add(name) - result.add(typ) - if defaultVal.isNil: - result.add(newNode(nkEmpty)) - else: - result.add(defaultVal) - -proc newProc(name: PNode, params: openArray[PNode], body = newNode(nkEmpty), - procType = nkProcDef): PNode = - result = newNode(procType) - result.add(name) - result.add(newNode(nkEmpty)) - result.add(newNode(nkEmpty)) - let formalParams = newNode(nkFormalParams) - for param in params: - formalParams.add(param) - result.add(formalParams) - result.add(newNode(nkEmpty)) - result.add(newNode(nkEmpty)) - result.add(body) - -proc newIfStmt(condition, body: PNode): PNode = - result = newNode(nkIfStmt) - let branch = newNode(nkElifBranch) - result.add(branch) - branch.add(condition) - branch.add(body) - -proc newCall(theProc: PNode, args: varargs[PNode]): PNode = - result = newNode(nkCall) - result.add(theProc) - for arg in args: - result.add(arg) - -proc newCall(theProc: string, args: varargs[PNode]): PNode = - newCall(ident(theProc), args) - -proc newStrLit(s: string): PNode = - result = newNode(nkStrLit) - result.strVal = s - -proc newRStrLit(s: string): PNode = - result = newNode(nkRStrLit) - result.strVal = s - -proc newCStringLit(s: string): PNode = - newNode(nkCallStrLit).addChain(ident("cstring"), newRStrLit(s)) - -proc newIntLit(val: BiggestInt): PNode = - result = newNode(nkIntLit) - result.intVal = val - -proc newInt64Lit(val: BiggestInt): PNode = - result = newNode(nkInt64Lit) - result.intVal = val - -proc newFloatLit(val: BiggestFloat): PNode = - result = newNode(nkFloatLit) - result.floatVal = val - -proc newFloat64Lit(val: BiggestFloat): PNode = - result = newNode(nkFloat64Lit) - result.floatVal = val - -proc newNilLit(): PNode = - result = newNode(nkNilLit) - -proc newDotExpr(left, right: PNode): PNode = - result = newNode(nkDotExpr) - result.add(left) - result.add(right) - -proc newCommand(left, right: PNode): PNode = - result = newNode(nkCommand) - result.add(left) - result.add(right) - -proc newInfix(left, op, right: PNode): PNode = - result = newNode(nkInfix) - result.add(op) - result.add(left) - result.add(right) - -proc postfix(left: PNode, op: string): PNode = - result = newNode(nkPostfix) - result.add(ident(op)) - result.add(left) - -proc newBracketExpr(first, bracket: PNode): PNode = - newNode(nkBracketExpr).addChain(first, bracket) - -proc newEmptyNode(): PNode = - newNode(nkEmpty) - -type GodotType = ref object - name: string - godotName: string - baseName: string - doc: string - derivedCount: int - isSingleton: bool - jsonNode: JsonNode - -proc findCommonRoot(typeRegistry: Table[string, GodotType], - types: seq[string]): string = - if types.len == 0: return "Object" - var chains = newSeq[seq[string]](types.len) - for idx, typ in types: - chains[idx] = newSeq[string]() - chains[idx].add(typ) - var curTyp = typeRegistry[typ] - while curTyp.baseName != "NimGodotObject": - chains[idx].add(curTyp.baseName) - curTyp = typeRegistry[curTyp.baseName] - chains[idx].reverse() - - var idx = 0 - while true: - var curType: string - var allEqual = true - for chain in chains: - if idx >= chain.len: - allEqual = false - break - if curType.isNil: - curType = chain[idx] - elif curType != chain[idx]: - allEqual = false - break - if allEqual: - result = curType - else: - break - inc idx - -proc incDerivedCount(types: var Table[string, GodotType], - className: string) = - let typ = types.getOrDefault(className) - if not typ.isNil: - inc typ.derivedCount - types.incDerivedCount(typ.baseName) - -proc toNimType(godotType: string): string = - case godotType: - of "float": "float64" - of "int": "int64" - of "String": "string" - of "File": "godottypes.File" - else: godotType - -proc toNimType(types: Table[string, GodotType], godotType: string): string = - let origType = - if godotType.contains(','): - findCommonRoot(types, godotType.split(',')) - else: - godotType - result = toNimType(origType) - -proc toNimStyle(name: string): string = - result = newStringOfCap(name.len + 1) - var i = 0 - var makeUpperCase: bool - while i < name.len: - if name[i] == '_': - if result.len != 0: - makeUpperCase = true - elif name[i] != '/': # remove slashes - if makeUpperCase: - result.add(name[i].toUpperAscii()) - makeUpperCase = false - else: - result.add(name[i]) - inc i - - while isKeyword(getIdent(result)): - result.add(result[result.len - 1]) - - if result == "result": - result = "resultVal" - -proc newRefTypeNode(typeSection: PNode, typ, base, doc: string, - isExported = true) = - let typeDef = newNode(nkTypeDef) - typeSection.add(typeDef) - if isExported: - typeDef.add(postfix(ident(typ), "*")) - else: - typeDef.add(ident(typ)) - - typeDef.add(newNode(nkEmpty)) # generic - let objTy = newNode(nkObjectTy) - let refTy = newNode(nkRefTy) - refTy.add(objTy) - typeDef.add(refTy) - - objTy.add(newNode(nkEmpty)) - let inherit = newNode(nkOfInherit) - inherit.add(ident(base)) - objTy.add(inherit) - - if not doc.isNil: - let recList = newNode(nkRecList) - let docNode = newNode(nkCommentStmt) - docNode.comment = doc - recList.add(docNode) - objTy.add(recList) - else: - objTy.add(newNode(nkEmpty)) - -proc makeConstSection(constObj: JsonNode): PNode = - if constObj.len == 0: - return newNode(nkEmpty) - - result = newNode(nkConstSection) - for field, val in constObj: - let def = newNode(nkConstDef) - def.add(postfix(ident(field), "*")) - def.add(newNode(nkEmpty)) # infer type - var valNode: PNode - if val.kind == JInt: - valNode = newInt64Lit(val.num) - # valNode.intVal = val.num - elif val.kind == JFloat: - valNode = newFloat64Lit(val.fnum) - elif val.kind == JBool: - valNode = ident($val.bval) - elif val.kind == JString: - valNode = newNode(nkStrLit) - valNode.strVal = val.str - else: - raise newException(ValueError, "Unexpected constant kind: " & $val.kind) - def.add(valNode) - result.add(def) - -type MethodArg = tuple[name, typ: string, defaultVal: JsonNode, isVarargs: bool] - -const standardTypes = toSet( - ["bool", "cint", "int", "uint8", "int8", "uint16", "int16", "uint32", "int32", - "uint64", - "int64", "float32", "cfloat", "float64", "GodotString", "Vector2", "Rect2", - "Vector3", "Transform2D", "Plane", "Quat", "Rect3", "Basis", "Transform", - "Color", "RID", "NodePath", "Dictionary", "Variant", "Array", - "PoolByteArray", "PoolIntArray", "PoolRealArray", "PoolStringArray", - "PoolVector2Array", "PoolVector3Array", "PoolColorArray"]) - -const smallIntTypes = toSet(["uint8", "int8", "uint16", "int16", "uint32", "int32", - "cint", "int", "Error"]) -const int64Types = toSet(["uint64", "int64"]) -const intTypes = union(smallIntTypes, int64Types) -const float64Types = toSet(["float64", "cdouble"]) -const float32Types = toSet(["float32", "cfloat"]) -const floatTypes = union(float64Types, float32Types) -const arrayTypes = toSet(["Array", "PoolByteArray", - "PoolIntArray", "PoolRealArray", "PoolStringArray", "PoolVector2Array", - "PoolVector3Array", "PoolColorArray"]) -const wrapperTypes = union(arrayTypes, - toSet(["NodePath", "Dictionary", "Variant"])) - -proc getInternalPtr(varName: PNode, typ: string): PNode = - assert(typ in wrapperTypes) - result = newDotExpr(varName, ident("godot" & typ)) - -proc newNilCheck(ident, toAssign: PNode): PNode = - newIfStmt(newCall("isNil", ident), - newNode(nkAsgn).addChain(ident).addChain( - toAssign - ) - ) - -proc singletonName(typ: string): PNode = - ident("singleton" & typ) - -proc makeDefaultValue(arg: MethodArg): PNode = - result = newEmptyNode() - if not arg.defaultVal.isNil: - if arg.typ == "bool": - result = ident(arg.defaultVal.str.toLowerAscii()) - elif arg.typ in intTypes: - result = newInt64Lit(parseBiggestInt(arg.defaultVal.str)) - elif arg.typ == "string" or arg.typ == "NodePath": - result = newStrLit(arg.defaultVal.str) - elif arg.typ in floatTypes: - result = newFloatLit(parseFloat(arg.defaultVal.str)) - elif arg.defaultVal.str == "Null": - if arg.typ == "Variant": - result = newCall("newVariant") - else: - result = newNilLit() - elif arg.typ == "Color": - result = newCall("initColor", - arg.defaultVal.str.split(',').mapIt(newFloatLit(parseFloat(it)))) - # elif arg.typ in arrayTypes and (arg.defaultVal.str == "[]" or - # arg.defaultVal.str == "[" & arg.typ & "]"): - # result = newCall("init" & arg.typ) - elif arg.typ == "RID" and arg.defaultVal.str == "[RID]": - result = newCall("initRID") - elif arg.typ == "Vector2" or arg.typ == "Vector3" or arg.typ == "Rect2": - let parts = arg.defaultVal.str.replace("(", "").replace(")", ""). - replace(" ", ""). - split(",").mapIt(newFloatLit(parseFloat(it))) - if arg.typ.endsWith("r2"): - result = newCall("vec2", parts) - elif arg.typ.endsWith('3'): - result = newCall("vec3", parts) - else: - result = newCall("initRect2", parts) - elif arg.defaultVal.str == "[Object:null]": - result = newNilLit() - elif arg.typ != "Transform" and arg.typ != "Transform2D" and - arg.typ != "Variant" and arg.typ notin arrayTypes: # TODO - raise newException( - ValueError, - "Cannot build default value from $# ($#)" % - [$arg.defaultVal, arg.typ]) - -proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], - name: PNode, godotMethodName: string, - typ: GodotType, args: seq[MethodArg], - returnType: string, isVirtual, - isBase, withImplementation: bool) = - var body: PNode - if not withImplementation: - body = newNode(nkEmpty) - else: - var methodBindName = toNimStyle( - typ.name & "_" & godotMethodName & "_method_bind") - if methodBindName[0].isUpperAscii(): - methodBindName[0] = methodBindName[0].toLowerAscii() - if methodBindName notin methodBindRegistry: - let methodBindDecl = newNode(nkVarSection).addChain( - newIdentDefs( - newNode(nkPragmaExpr).addChain( - ident(methodBindName)).addChain( - newNode(nkPragma).addChain(ident("threadvar"))), - newNode(nkPtrTy).addChain(ident("GodotMethodBind")) - )) - tree.add(methodBindDecl) - methodBindRegistry.incl(methodBindName) - - let nilCheck = newNilCheck(ident(methodBindName), - newCall("getMethod", newCStringLit(typ.godotName), - newCStringLit(godotMethodName)) - ) - let vars = newNode(nkVarSection) - var varargsName: string - var isVarargs: bool - var staticArgsLen: int - var argLenNode = newIntLit(0) - let argsName = ident("argsToPassToGodot") - if args.len > 0: - for arg in args: - if arg.isVarargs: - varargsName = arg.name - isVarargs = true - vars.add(newIdentDefs(ident("callError"), ident("VariantCallError"))) - break - let argsAlloc = newNode(nkCast).addChain( - newNode(nkPtrTy).addChain( - newNode(nkBracketExpr).addChain( - ident("array"), ident("MAX_ARG_COUNT"), - if isVarargs: newNode(nkPtrTy).addChain(ident("GodotVariant")) - else: ident("pointer")))) - staticArgsLen = if varargsName.isNil: args.len - else: args.len - 1 - if not varargsName.isNil: - argLenNode = newCall("cint", - newInfix(newIntLit(staticArgsLen), - ident("+"), - newDotExpr(ident(varargsName), ident("len")))) - argsAlloc.add(newCall("godotAlloc", newCall("cint", newInfix( - newCall("sizeof", ident("Variant")), ident("*"), - newNode(nkPar).addChain(argLenNode)))) - ) - else: - argLenNode = newCall("cint", newIntLit(staticArgsLen)) - vars.add(newIdentDefs( - ident("argsStatic"), - newNode(nkBracketExpr).addChain( - ident("array"), newIntLit(staticArgsLen), ident("pointer")), - newNode(nkEmpty))) - argsAlloc.add(newCommand(ident("addr"), ident("argsStatic"))) - vars.add(newIdentDefs(argsName, newNode(nkEmpty), argsAlloc)) - - let argConversions = newNode(nkStmtList) - for idx, arg in args: - var argName = ident(arg.name) - if arg.isVarargs: - argName = newNode(nkBracketExpr).addChain( - ident(varargsName), - newInfix(ident("idx"), ident("-"), newIntLit(staticArgsLen))) - let argIdx = if arg.isVarargs: ident("idx") else: newIntLit(idx) - let isStandardType = arg.typ in standardTypes - let isWrappedType = arg.typ in wrapperTypes - let convArg = if not varargsName.isNil: - getInternalPtr(newCall("toGodot", argName), "Variant") - elif isWrappedType: getInternalPtr(argName, arg.typ) - elif isStandardType: newCall("unsafeAddr", argName) - elif arg.typ == "string": newCall("unsafeAddr", - ident("argToPassToGodot" & $idx)) - else: ident("argToPassToGodot" & $idx) # object - if not isStandardType and arg.isVarargs: - raise newException(ValueError, - "Non-standard type $# for varargs params of method $# of type $#" % - [arg.typ, godotMethodName, typ.godotName]) - if not isStandardType and varargsName.isNil: - if arg.typ == "string": - argConversions.add(newNode(nkVarSection).addChain( - newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(), - newCall("toGodotString", argName)))) - else: - argConversions.add(newNode(nkLetSection).addChain( - newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(), - newDotExpr(argName, ident("godotObject"))))) - let argAsgn = newNode(nkAsgn).addChain( - newNode(nkBracketExpr).addChain( - newNode(nkBracketExpr).addChain(argsName), argIdx), - convArg - ) - if not arg.isVarargs: - argConversions.add( - argAsgn - ) - else: - argConversions.add(newNode(nkVarSection).addChain( - newIdentDefs(ident("idx"), newNode(nkEmpty), newIntLit(staticArgsLen)))) - let argLoop = newNode(nkWhileStmt) - argConversions.add(argLoop) - argLoop.add(newInfix(ident("idx"), ident("<"), argLenNode) - ) - argLoop.add(newNode(nkStmtList).addChain( - argAsgn, - newCommand(ident("inc"), ident("idx")))) - - let retName = if isVarargs: "callRet" else: "ptrCallRet" - let theCall = newCall( - newDotExpr(ident(methodBindName), - ident(if isVarargs: "call" else: "ptrCall")), - newDotExpr(ident("self"), ident("godotObject")), - if args.len > 0: argsName else: newNode(nkNilLit), - argLenNode, - if not isVarargs: ident(retName) else: ident("callError") - ) - if not isVarargs: - theCall.sons.delete(3) - let freeCall = newCall("godotFree", argsName) - body = newNode(nkStmtList) - if typ.isSingleton: - let varName = singletonName(typ.name) - body.add(newNilCheck(varName, newCall( - newBracketExpr(ident("getSingleton"), ident(typ.name))))) - body.add(newNode(nkLetSection).addChain(newIdentDefs( - ident("self"), newNode(nkEmpty), varName - ))) - body.add(nilCheck) - body.add(vars) - body.add(argConversions) - if not isVarargs: - let retPtrDecl = newNode(nkVarSection).addChain( - newIdentDefs(ident(retName), ident("pointer"), newEmptyNode()) - ) - body.add(retPtrDecl) - var isVariantRet: bool - var isConversionRet: bool - var isObjRet: bool - var isStringRet: bool - var isWrapperRet: bool - let retValIdent = if not isVarargs: ident("ptrCallVal") else: ident(retName) - if not returnType.isNil and not isVarargs: - var addrToAssign = newCall("addr", retValIdent) - if returnType in smallIntTypes: - isConversionRet = true - body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, ident("int64"), - ))) - elif returnType in float32Types: - isConversionRet = true - body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, ident("float64"), - ))) - elif returnType in wrapperTypes: - isWrapperRet = true - body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, ident("Godot" & returnType), - ))) - elif returnType in standardTypes: - addrToAssign = newCall("addr", ident("result")) - elif returnType == "string": - isStringRet = true - body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, ident("GodotString"), - ))) - else: - isObjRet = true - body.add(newNode(nkVarSection).addChain(newIdentDefs( - retValIdent, newNode(nkPtrTy).addChain(ident("GodotObject")), - ))) - body.add(newNode(nkAsgn).addChain(ident(retName), addrToAssign)) - - if not isVarargs: - body.add(theCall) - else: - if not returnType.isNil: - isVariantRet = true - let callStmt = newNode(nkLetSection).addChain( - newIdentDefs( - newNode(nkPragmaExpr).addChain( - ident(retName), newNode(nkPragma).addChain(ident("used"))), - newNode(nkEmpty), theCall)) - body.add(callStmt) - - if varargsName.isNil: - for idx, arg in args: - if arg.typ == "string": - body.add(newCall("deinit", ident("argToPassToGodot" & $idx))) - - if args.len > 0 and not varargsName.isNil: - body.add(freeCall) - if not varargsName.isNil: - let errCheck = newIfStmt( - newInfix(newDotExpr(ident("callError"), ident("error")), ident("!="), - newDotExpr(ident("VariantCallErrorType"), ident("OK"))), - newNode(nkRaiseStmt).addChain( - newCall("newCallError", ident("callError"))) - ) - body.add(errCheck) - if isVariantRet: - let convErrDef = newNode(nkLetSection).addChain( - newIdentDefs(ident("convErr"), newNode(nkEmpty), - newCall("fromGodot", ident("result"), newCall("newVariant", retValIdent)))) - let convCheck = newIfStmt( - newInfix(ident("convErr"), ident("!="), - newDotExpr(ident("ConversionResult"), ident("OK"))), - newNode(nkRaiseStmt).addChain( - newCall("newConversionError", ident("convErr"))) - ) - body.add(convErrDef) - body.add(convCheck) - if isStringRet: - body.add(newCall("deinit", retValIdent)) - elif isConversionRet: - body.add(newNode(nkAsgn).addChain( - ident("result"), - newCall(returnType, retValIdent))) - elif isWrapperRet: - body.add(newNode(nkAsgn).addChain( - ident("result"), - newCall("new" & returnType, retValIdent))) - elif isObjRet: - body.add(newNode(nkAsgn).addChain(ident("result"), - newCall(newBracketExpr(ident("asNimGodotObject"), - newCall("type", ident("result"))), retValIdent))) - elif isStringRet: - body.add(newNode(nkAsgn).addChain(ident("result"), - newCall("$", retValIdent))) - - let procType = if isVirtual: nkMethodDef - else: nkProcDef - var params = newSeqOfCap[PNode](args.len + 2) - if not returnType.isNil: - params.add(ident(returnType)) - else: - params.add(newNode(nkEmpty)) - if not typ.isSingleton: - params.add(newIdentDefs(ident("self"), ident(toNimType(typ.name)))) - - for arg in args: - if arg.isVarargs: - params.add(newIdentDefs(ident(arg.name), - newNode(nkBracketExpr).addChain(ident("varargs"), ident(arg.typ)))) - else: - let defaultValue = arg.makeDefaultValue() - params.add(newIdentDefs(ident(arg.name), ident(arg.typ), defaultValue)) - let procDecl = newProc(if not withImplementation: postfix(name, "*") - else: name, - params, body, procType) - if not withImplementation: - let pragma = newNode(nkPragma) - pragma.add(ident("gcsafe")) - pragma.add(newNode(nkExprColonExpr).addChain(ident("locks"), - newIntLit(0))) - if isVirtual and isBase: - pragma.add(ident("base")) - procDecl.sons[4] = pragma - tree.add(procDecl) - -proc generateMethod(tree: PNode, methodBindRegistry: var HashSet[string], - name: PNode, godotMethodName: string, - typ: GodotType, args: seq[MethodArg], - returnType: string, - isVirtual, isBase, withImplementation: bool) = - doGenerateMethod( - tree, methodBindRegistry, name, godotMethodName, typ, - args, returnType, isVirtual, isBase, withImplementation) - -proc makeProperty(types: Table[string, GodotType], tree: PNode, - methodBindRegistry: var HashSet[string], - typ: GodotType, - propertyObj: JsonNode, withImplementation: bool) = - let getterNameStr = toNimStyle(propertyObj["name"].str) - let getterName = ident(toNimStyle(propertyObj["name"].str)) - let setterName = newNode(nkAccQuoted).addChain(ident(getterNameStr & "=")) - - let nimType = toNimType(types, propertyObj["type"].str) - generateMethod(tree, methodBindRegistry, - getterName, propertyObj["getter"].str, typ, - @[], nimType, isVirtual = false, - isBase = false, withImplementation) - generateMethod(tree, methodBindRegistry, - setterName, propertyObj["setter"].str, typ, - @[("val", nimType, JsonNode(nil), false)], - nil, isVirtual = false, isBase = false, withImplementation) - -proc makeMethod(types: Table[string, GodotType], tree: PNode, - methodBindRegistry: var HashSet[string], - typ: GodotType, methodObj: JsonNode, - withImplementation: bool) = - let returnType = if methodObj["return_type"].str != "void": - toNimType(types, methodObj["return_type"].str) - else: nil - - for prop in typ.jsonNode["properties"]: - if prop["getter"].str == methodObj["name"].str or - prop["setter"].str == methodObj["name"].str: - return - - var args = newSeqOfCap[MethodArg](methodObj["arguments"].len + 1) - var origArgs = methodObj["arguments"] - var isBase = methodObj["is_virtual"].bval - if methodObj["is_virtual"].bval: - proc getMethod(typNode: JsonNode, methName: string): JsonNode = - for meth in typNode["methods"]: - if meth["is_virtual"].bval and - meth["name"].str == methName: return meth - var curTyp = types.getOrDefault(typ.baseName) - while not curTyp.isNil: - let meth = curTyp.jsonNode.getMethod(methodObj["name"].str) - if not meth.isNil: - origArgs = meth["arguments"] - isBase = false - curTyp = types.getOrDefault(curTyp.baseName) - - for arg in origArgs: - let typ = toNimType(types, arg["type"].str) - let defaultVal = if arg["has_default_value"].bval: arg["default_value"] - else: nil - args.add((toNimStyle(arg["name"].str), typ, - defaultVal, false)) - if methodObj["has_varargs"].bval: - args.add(("variantArgs", "Variant", JsonNode(nil), true)) - - let godotName = methodObj["name"].str - var nimName = toNimStyle(godotName) - if not godotName.startsWith('_'): - for meth in typ.jsonNode["methods"]: - if meth["name"].str == '_' & godotName: - nimName = nimName & "Impl" - - generateMethod(tree, methodBindRegistry, - ident(nimName), methodObj["name"].str, - typ, args, - returnType, methodObj["is_virtual"].bval, isBase, - withImplementation) - -proc addAttributeToDoc(doc: var string, propName, propValue: string) = - if doc.len > 0: - doc.add("\n") - doc.add(propName & ": " & propValue) - -const classAttributes = ["singleton", "instanciable", "is_reference"] - -proc typeNameToModuleName(name: string): string = - var wasUpperOrDigit = true - result = newStringOfCap(name.len + 10) - for idx, c in name: - if c.isUpperAscii() or c.isDigit(): - if not wasUpperOrDigit or idx > 0 and idx < name.len - 1 and - name[idx + 1].isLowerAscii(): - result.add('_') - result.add(c.toLowerAscii()) - wasUpperOrDigit = true - else: - result.add(c) - wasUpperOrDigit = false - if result == "object": - # keyword - result = "objects" - if result == "os": - # to avoid clash with stdlib - result = "gd_os" - -proc newRegisterClassNode(typ: GodotType): PNode = - newCall("registerClass", - ident(typ.name), - newCStringLit(typ.godotName), - ident("true") # isNative - ) - -proc genSingletonDecl(typ: string): PNode = - result = newNode(nkVarSection) - let name = singletonName(typ) - let threadvar = newNode(nkPragma).addChain(ident("threadvar")) - result.add(newIdentDefs(newNode(nkPragmaExpr).addChain(name, threadvar), - ident(typ))) - -proc shouldExport(typ: GodotType, types: Table[string, GodotType]): bool = - var curTyp = typ - while not curTyp.isNil and not curTyp.isSingleton: - curTyp = types.getOrDefault(curTyp.baseName) - result = curTyp.isNil - -proc genTypeFile*(types: var Table[string, GodotType], targetDir: string) = - for typ in types.values(): - types.incDerivedCount(typ.baseName) - - var sortedTypes = toSeq(types.values()) - sortedTypes.sort do (x, y: GodotType) -> int: - cmp(y.derivedCount, x.derivedCount) - - let godotApiTypesTree = newNode(nkStmtList) - godotApiTypesTree.add(newNode(nkImportStmt).addChain(ident("godot"))) - let typeSection = newNode(nkTypeSection) - godotApiTypesTree.add(typeSection) - - for typ in sortedTypes: - if not typ.shouldExport(types): continue - newRefTypeNode(typeSection, typ.name, typ.baseName, typ.doc) - - for typ in sortedTypes: - if not typ.shouldExport(types): continue - let regNode = newCall("registerClass", - ident(typ.name), - newCStringLit(typ.godotName), - ident("true") # isNative - ) - godotApiTypesTree.add(regNode) - - renderModule(godotApiTypesTree, targetDir / "godottypes.nim") - -proc genApi*(targetDir: string, apiJsonFile: string) = - let apiJson = parseJson(newFileStream(apiJsonFile), - apiJsonFile.extractFilename()) - var megaImport = newStringOfCap(64 * 1024) - - var types = initTable[string, GodotType]() - for obj in apiJson: - let godotClassName = obj["name"].str - let className = godotClassName.replace("_", "") - var baseClassName = obj["base_class"].str - baseClassName = toNimType(baseClassName.replace("_", "")) - if baseClassName.isNil or baseClassName.len == 0: - baseClassName = "NimGodotObject" - var doc = "" - for attr in classAttributes: - if attr in obj: - addAttributeToDoc(doc, attr, $obj[attr]) - types[className] = GodotType( - name: className, - godotName: godotClassName, - baseName: baseClassName, - doc: doc, - jsonNode: obj, - isSingleton: obj["singleton"].bval - ) - for typ in types.values(): - let tree = newNode(nkStmtList) - let importStmt = newNode(nkImportStmt) - importStmt.add(ident("godot")) - importStmt.add(ident("godottypes")) - importStmt.add(ident("godotinternal")) - tree.add(importStmt) - let exportStmt = newNode(nkExportStmt) - exportStmt.add(ident("godottypes")) - tree.add(exportStmt) - - var methodBindRegsitry = initSet[string]() - let obj = typ.jsonNode - if typ.baseName != "NimGodotObject": - let baseModule = typeNameToModuleName(typ.baseName) - let baseModuleNode = if getIdent(baseModule).isKeyword: - newStrLit(baseModule & ".nim") - else: - ident(baseModule) - importStmt.add(baseModuleNode) - exportStmt.add(baseModuleNode) - let constSection = makeConstSection(obj["constants"]) - if constSection.kind != nkEmpty: - # renderer doesn't properly render empty stmt after type section - tree.add(makeConstSection(obj["constants"])) - - if typ.isSingleton: - let typeDecl = newNode(nkTypeSection) - newRefTypeNode(typeDecl, typ.name, typ.baseName, typ.doc, - isExported = false) - tree.add(typeDecl) - tree.add(newRegisterClassNode(typ)) - tree.add(genSingletonDecl(typ.name)) - - # first, generate declarations only for ease of - # human readability of the file - for property in obj["properties"]: - makeProperty(types, tree, methodBindRegsitry, typ, property, - withImplementation = false) - for meth in obj["methods"]: - makeMethod(types, tree, methodBindRegsitry, typ, - meth, withImplementation = false) - - for property in obj["properties"]: - makeProperty(types, tree, methodBindRegsitry, typ, - property, withImplementation = true) - for meth in obj["methods"]: - makeMethod(types, tree, methodBindRegsitry, typ, meth, - withImplementation = true) - - let moduleName = typeNameToModuleName(typ.name) - renderModule(tree, targetDir / moduleName & ".nim") - - megaImport.add("import \"" & moduleName & "\"\n") - - genTypeFile(types, targetDir) - - writeFile(targetDir / "godotall.nim", megaImport) - writeFile(targetDir / splitPath(targetDir)[1] & ".nimble", "") - -when isMainModule: - import os - - const usage = slurp("usage.txt") - - proc main() = - if paramCount() < 2: - echo usage - quit(-1) - let godotBin = paramStr(1) - let targetDir = paramStr(2) - - if not dirExists(targetDir): - echo "The specified directory does not exist" - quit(-1) - if not fileExists(godotBin): - echo "Invalid godot binary path" - quit(-1) - - let jsonFile = targetDir / "api.json" - if fileExists(jsonFile) and - godotBin.getLastModificationTime() <= jsonFile.getLastModificationTime(): - echo "api.json if up to date - doing nothing." - return - - discard execShellCmd( - "\"" & godotBin & "\" --gdnative-generate-json-api \"" & jsonFile & "\"") - if not fileExists(jsonFile): - echo "Failed to generate api.json" - quit(-1) - - genApi(targetDir, jsonFile) - - main() diff --git a/godot/apigen/usage.txt b/godot/apigen/usage.txt deleted file mode 100644 index 566634c..0000000 --- a/godot/apigen/usage.txt +++ /dev/null @@ -1,3 +0,0 @@ -Tool for wrapping Godot API into Nim - - apigen [godot binary path] [target directory] \ No newline at end of file diff --git a/godot/core/aabb.nim b/godot/core/aabb.nim new file mode 100644 index 0000000..2d816da --- /dev/null +++ b/godot/core/aabb.nim @@ -0,0 +1,79 @@ +# Copyright (c) 2018 Xored Software, Inc. + +import hashes + +import vector3 +import internal/godotinternaltypes, internal/godotstrings +import godotcoretypes, gdnativeapi + +proc initAABB*(pos, size: Vector3): AABB {.inline.} = + AABB(position: pos, size: size) + +proc `$`*(self: AABB): string {.inline.} = + $getGDNativeAPI().aabbAsString(self) + +proc hash*(self: AABB): Hash {.inline.} = + !$(self.position.hash() !& self.size.hash()) + +proc area*(self: AABB): float32 {.inline.} = + getGDNativeAPI().aabbGetArea(self) + +proc hasNoArea*(self: AABB): bool {.inline.} = + getGDNativeAPI().aabbHasNoArea(self) + +proc hasNoSurface*(self: AABB): bool {.inline.} = + getGDNativeAPI().aabbHasNoSurface(self) + +proc intersects*(self, other: AABB): bool {.inline.} = + getGDNativeAPI().aabbIntersects(self, other) + +proc encloses*(self, other: AABB): bool {.inline.} = + getGDNativeAPI().aabbEncloses(self, other) + +proc merge*(self, other: AABB): AABB {.inline.} = + getGDNativeAPI().aabbMerge(self, other).toAABB() + +proc intersection*(self, other: AABB): AABB {.inline.} = + getGDNativeAPI().aabbIntersection(self, other).toAABB() + +proc intersectsPlane*(self: AABB; plane: Plane): bool {.inline.} = + getGDNativeAPI().aabbIntersectsPlane(self, plane) + +proc intersectsSegment*(self: AABB; start, to: Vector3): bool {.inline.} = + getGDNativeAPI().aabbIntersectsSegment(self, start, to) + +proc contains*(self: AABB; point: Vector3): bool {.inline.} = + getGDNativeAPI().aabbHasPoint(self, point) + +proc getSupport*(self: AABB; dir: Vector3): Vector3 {.inline.} = + getGDNativeAPI().aabbGetSupport(self, dir).toVector3() + +proc getLongestAxis*(self: AABB): Vector3 {.inline.} = + getGDNativeAPI().aabbGetLongestAxis(self).toVector3() + +proc getLongestAxisIndex*(self: AABB): cint {.inline.} = + getGDNativeAPI().aabbGetLongestAxisIndex(self) + +proc getLongestAxisSize*(self: AABB): float32 {.inline.} = + getGDNativeAPI().aabbGetLongestAxisSize(self) + +proc getShortestAxis*(self: AABB): Vector3 {.inline.} = + getGDNativeAPI().aabbGetShortestAxis(self).toVector3() + +proc getShortestAxisIndex*(self: AABB): cint {.inline.} = + getGDNativeAPI().aabbGetShortestAxisIndex(self) + +proc getShortestAxisSize*(self: AABB): float32 {.inline.} = + getGDNativeAPI().aabbGetShortestAxisSize(self) + +proc expand*(self: AABB; toPoint: Vector3): AABB {.inline.} = + getGDNativeAPI().aabbExpand(self, toPoint).toAABB() + +proc grow*(self: AABB; by: float32): AABB {.inline.} = + getGDNativeAPI().aabbGrow(self, by).toAABB() + +proc getEndpoint*(self: AABB; idx: cint): Vector3 {.inline.} = + getGDNativeAPI().aabbGetEndpoint(self, idx).toVector3() + +proc `==`*(a, b: AABB): bool {.inline.} = + getGDNativeAPI().aabbOperatorEqual(a, b) diff --git a/godot/core/arrays.nim b/godot/core/arrays.nim index 7f07a86..fcbafb2 100644 --- a/godot/core/arrays.nim +++ b/godot/core/arrays.nim @@ -1,127 +1,146 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. import hashes -import "../internal/godotinternaltypes.nim", "../internal/godotarrays.nim" +import internal/godotinternaltypes, internal/godotarrays -import godotbase, poolarrays +type + Array* = ref object + godotArray: GodotArray + +proc godotArray*(arr: Array): ptr GodotArray {.inline.} = + ## WARNING: do not keep the returned value for longer than the lifetime of + ## ``arr`` + addr arr.godotArray proc arrayFinalizer(arr: Array) = - arr.godotArray[].deinit() - -proc newArray*(): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[]) + arr.godotArray.deinit() proc newArray*(arr: GodotArray): Array {.inline.} = new(result, arrayFinalizer) - result.godotArray[] = arr - -proc newArray*(pca: PoolColorArray): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pca.godotPoolColorArray[]) - -proc newArray*(pv3a: PoolVector3Array): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pv3a.godotPoolVector3Array[]) - -proc newArray*(pv2a: PoolVector2Array): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pv2a.godotPoolVector2Array[]) - -proc newArray*(psa: PoolStringArray): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], psa.godotPoolStringArray[]) - -proc newArray*(pra: PoolRealArray): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pra.godotPoolRealArray[]) - -proc newArray*(pia: PoolIntArray): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pia.godotPoolIntArray[]) - -proc newArray*(pba: PoolByteArray): Array {.inline.} = - new(result, arrayFinalizer) - initGodotArray(result.godotArray[], pba.godotPoolByteArray[]) + result.godotArray = arr import variants -proc `[]=`*(self: var Array; idx: int; value: Variant) {.inline.} = - self.godotArray[][idx.cint] = value.godotVariant[] +proc newArray*(s: varargs[Variant]): Array = + new(result, arrayFinalizer) + initGodotArray(result.godotArray) + for v in s: + result.godotArray.add(v.godotVariant[]) + +proc newArray*(s: openarray[Variant]): Array = + result = newArray() + for v in s: + result.godotArray.add(v.godotVariant[]) + +import poolarrays + +proc newArray*(pca: PoolColorArray): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pca.godotPoolColorArray[]) + +proc newArray*(pv3a: PoolVector3Array): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pv3a.godotPoolVector3Array[]) + +proc newArray*(pv2a: PoolVector2Array): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pv2a.godotPoolVector2Array[]) + +proc newArray*(psa: PoolStringArray): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, psa.godotPoolStringArray[]) + +proc newArray*(pra: PoolRealArray): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pra.godotPoolRealArray[]) + +proc newArray*(pia: PoolIntArray): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pia.godotPoolIntArray[]) + +proc newArray*(pba: PoolByteArray): Array {.inline.} = + new(result, arrayFinalizer) + initGodotArray(result.godotArray, pba.godotPoolByteArray[]) + +proc `[]=`*(self: Array; idx: int; value: Variant) {.inline.} = + self.godotArray[idx.cint] = value.godotVariant[] proc `[]`*(self: Array; idx: int): Variant {.inline.} = - newVariant(self.godotArray[][idx.cint]) + newVariant(self.godotArray[idx.cint]) -proc add*(self: var Array; value: Variant) {.inline.} = - self.godotArray[].add(value.godotVariant[]) +proc add*(self: Array; value: Variant) {.inline.} = + self.godotArray.add(value.godotVariant[]) -proc clear*(self: var Array) {.inline.} = - self.godotArray[].clear() +proc clear*(self: Array) {.inline.} = + self.godotArray.clear() proc count*(self: Array; value: Variant): int {.inline.} = - self.godotArray[].count(value.godotVariant[]).int + self.godotArray.count(value.godotVariant[]).int proc isEmpty*(self: Array): bool {.inline.} = - self.godotArray[].isEmpty() + self.godotArray.isEmpty() -proc erase*(self: var Array; value: Variant) {.inline.} = - self.godotArray[].erase(value.godotVariant[]) +proc erase*(self: Array; value: Variant) {.inline.} = + self.godotArray.erase(value.godotVariant[]) proc first*(self: Array): Variant {.inline.} = - newVariant(self.godotArray[].first()) + newVariant(self.godotArray.first()) proc last*(self: Array): Variant {.inline.} = - newVariant(self.godotArray[].last()) + newVariant(self.godotArray.last()) proc find*(self: Array; what: Variant; f: int): int {.inline.} = - self.godotArray[].find(what.godotVariant[], f.cint).int + self.godotArray.find(what.godotVariant[], f.cint).int proc findLast*(self: Array; what: Variant): int {.inline.} = - self.godotArray[].findLast(what.godotVariant[]).int + self.godotArray.findLast(what.godotVariant[]).int proc contains*(self: Array; value: Variant): bool {.inline.} = - self.godotArray[].contains(value.godotVariant[]) + self.godotArray.contains(value.godotVariant[]) proc hash*(self: Array): Hash {.inline.} = - hash(self.godotArray[].godotHash()) + hash(self.godotArray.godotHash()) -proc insert*(self: var Array; pos: int; value: Variant) {.inline.} = - self.godotArray[].insert(pos.cint, value.godotVariant[]) +proc insert*(self: Array; pos: int; value: Variant) {.inline.} = + self.godotArray.insert(pos.cint, value.godotVariant[]) -proc reverse*(self: var Array) {.inline.} = - self.godotArray[].reverse() +proc reverse*(self: Array) {.inline.} = + self.godotArray.reverse() -proc popLast*(self: var Array): Variant {.inline.} = - newVariant(self.godotArray[].popLast()) +proc popLast*(self: Array): Variant {.inline.} = + newVariant(self.godotArray.popLast()) -proc popFirst*(self: var Array): Variant {.inline.} = - newVariant(self.godotArray[].popFirst()) +proc popFirst*(self: Array): Variant {.inline.} = + newVariant(self.godotArray.popFirst()) -proc addLast*(self: var Array; value: Variant) {.inline.} = - self.godotArray[].addLast(value.godotVariant[]) +proc addLast*(self: Array; value: Variant) {.inline.} = + self.godotArray.addLast(value.godotVariant[]) -proc addFirst*(self: var Array; value: Variant) {.inline.} = - self.godotArray[].addFirst(value.godotVariant[]) +proc addFirst*(self: Array; value: Variant) {.inline.} = + self.godotArray.addFirst(value.godotVariant[]) -proc delete*(self: var Array; idx: int) {.inline.} = - self.godotArray[].delete(idx.cint) +proc delete*(self: Array; idx: int) {.inline.} = + self.godotArray.delete(idx.cint) -proc setLen*(self: var Array; size: int) {.inline.} = - self.godotArray[].setLen(size.cint) +proc setLen*(self: Array; size: int) {.inline.} = + self.godotArray.setLen(size.cint) -proc rfind*(self: Array; what: Variant; f: int): int {.inline.} = - self.godotArray[].rfind(what.godotVariant[], f.cint).int +proc rfind*(self: Array; what: Variant; fromIdx: int): int {.inline.} = + self.godotArray.rfind(what.godotVariant[], fromIdx.cint).int proc len*(self: Array): int {.inline.} = - self.godotArray[].len.int + self.godotArray.len.int -proc sort*(self: var Array) {.inline.} = - self.godotArray[].sort() +proc sort*(self: Array) {.inline.} = + self.godotArray.sort() -iterator items*(arr: Array): Variant {.inline.} = - for i in 0.. 1: + result.add(", ") + result.add($k) + result.add(": ") + result.add($v) + result.add('}') diff --git a/godot/core/godotbase.nim b/godot/core/godotbase.nim index 86ee42e..7b5b804 100644 --- a/godot/core/godotbase.nim +++ b/godot/core/godotbase.nim @@ -1,130 +1,64 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import math - -type - Error* {.size: sizeof(cint), pure.} = enum - OK, - Failed, ## Generic fail error - Unavailable, ## What is requested is unsupported/unavailable - Unconfigured, ## The object being used hasnt been properly set up yet - Unauthorized, ## Missing credentials for requested resource - ParameterRangeError, ## Parameter given out of range (5) - OutOfMemory, ## Out of memory - FileNotFound, - FileBadDrive, - FileBadPath, - FileNoPermission, ## (10) - FileAlreadyInUse, - FileCantOpen, - FileCantWrite, - FileCantRead, - FileUnrecognized, ## (15) - FileCorrupt, - FileMissingDependencies, - FileEOF, - CantOpen, ## Can't open a resource/socket/file - CantCreate, ## (20) - QueryFailed, - AlreadyInUse, - Locked, ## resource is locked - Timeout, - CantConnect, ## (25) - CantResolve, - ConnectionError, - CantAquireResource, - CantFork, - InvalidData, ## Data passed is invalid (30) - InvalidParameter, ## Parameter passed is invalid - AlreadyExists, ## When adding, item already exists - DoesNotExist, ## When retrieving/erasing, it item does not exist - DatabaseCantRead, ## Database is full - DatabaseCantWrite, ## Database is full (35) - CompilationFailed, - MethodNotFound, - LinkFailed, - ScriptFailed, - CyclicLink, ## (40) - InvalidDeclaration, - DuplicateSymbol, - PauseError, - Busy, - Skip, ## (45) - Help, ## user requested help!! - Bug, - ## a bug in the software certainly happened, due to a double - ## check failing or unexpected behavior. - PrinterOnFire, ## the parallel port printer is engulfed in flames - WTF ## shit happens, has never been used, though +import math, godotinternal # math helpers +{.push stackTrace: off.} const EPSILON = 0.00001'f32 -proc isEqualApprox*(a, b: float32): bool {.inline.} = +proc isEqualApprox*(a, b: float32): bool {.inline, noinit.} = abs(a - b) < EPSILON -proc isEqualApprox*(a, b: float64): bool {.inline.} = +proc isEqualApprox*(a, b: float64): bool {.inline, noinit.} = abs(a - b) < EPSILON -proc sign*(a: float32): float32 {.inline.} = +proc sign*(a: float32): float32 {.inline, noinit.} = if a < 0: -1.0'f32 else: 1.0'f32 -proc sign*(a: float64): float64 {.inline.} = +proc sign*(a: float64): float64 {.inline, noinit.} = if a < 0: -1.0'f64 else: 1.0'f64 -proc stepify*(value, step: float64): float64 = +proc stepify*(value, step: float64): float64 {.inline, noinit.} = if step != 0'f64: floor(value / step + 0.5'f64) * step else: value -proc stepify*(value, step: float32): float32 = +proc stepify*(value, step: float32): float32 {.inline, noinit.} = if step != 0'f32: floor(value / step + 0.5'f32) * step else: value -import "../internal/godotinternaltypes.nim" +when (NimMajor, NimMinor, NimPatch) < (0, 20, 4): + # Newer Nim has these procs in system module -type - Variant* = ref object - godotVariant: GodotVariant - noDeinit: bool # used to avoid copying when passing the variant to Godot + proc min*(x, y: float32): float32 {.inline, noinit.} = + if x <= y: x else: y - Array* = ref object - godotArray: GodotArray + proc abs*(x: float32): float32 {.inline, noinit.} = + if x < 0.0: -x else: x -proc markNoDeinit*(v: Variant) {.inline.} = - ## Makes it so that internal GodotVariant object will not be destroyed - ## when the reference is gone. Use only if you know what you are doing. - v.noDeinit = true + proc max*(x, y: float32): float32 {.inline, noinit.} = + if y <= x: x else: y -proc isNoDeinit*(v: Variant): bool {.inline.} = - v.noDeinit +{.pop.} # stackTrace: off -proc godotArray*(arr: Array): ptr GodotArray {.inline.} = - ## WARNING: do not keep the returned value for longer than the lifetime of - ## ``arr`` - addr arr.godotArray +template printWarning*(warning: typed) = + ## Prints ``warning`` to Godot log, adding filename and line information. + let instInfo = instantiationInfo() + godotPrintWarning(cstring($warning), cstring"", cstring(instInfo.filename), instInfo.line.cint) -proc godotVariant*(v: Variant): ptr GodotVariant {.inline.} = - ## WARNING: do not keep the returned value for longer than the lifetime of - ## ``v`` - addr v.godotVariant +template printError*(error: typed) = + ## Prints ``error`` to Godot log, adding filename and line information. + let instInfo = instantiationInfo() + godotPrintError(cstring($error), cstring"", cstring(instInfo.filename), instInfo.line.cint) -# System Functions - -proc godotAlloc*(bytes: cint): pointer {. - importc: "godot_alloc".} - ## Allocates the specified number of bytes. - ## Using this instead of stdlib proc will help Godot track how much memory - ## is in use in debug mode. -proc godotRealloc*(p: pointer; bytes: cint): pointer {. - importc: "godot_realloc".} - ## Reallocates the pointer for the specified number of bytes. - ## Using this instead of stdlib proc will help Godot track how much memory - ## is in use in debug mode. -proc godotFree*(p: pointer) {.importc: "godot_free".} - ## Frees the memory pointed to by the pointer. - ## Using this instead of stdlib proc will help Godot track how much memory - ## is in use in debug mode. +proc print*(parts: varargs[string, `$`]) = + ## Prints concatenated ``parts`` to Godot log. + var combined = "" + for v in parts: + combined.add(v) + var s = combined.toGodotString() + godotPrint(s) + s.deinit() diff --git a/godot/core/godotcoretypes.nim b/godot/core/godotcoretypes.nim new file mode 100644 index 0000000..c4c4b71 --- /dev/null +++ b/godot/core/godotcoretypes.nim @@ -0,0 +1,102 @@ +# Copyright 2018 Xored Software, Inc. + +type + Color* {.byref.} = object + r*: float32 + g*: float32 + b*: float32 + a*: float32 + + Vector3* {.byref.} = object + x*: float32 + y*: float32 + z*: float32 + + Vector2* {.byref.} = object + x*: float32 + y*: float32 + + Plane* {.byref.} = object + normal*: Vector3 + d*: float32 + + Basis* {.byref.} = object + elements*: array[3, Vector3] + + Quat* {.byref.} = object + x*: float32 + y*: float32 + z*: float32 + w*: float32 + + AABB* {.byref.} = object + position*: Vector3 + size*: Vector3 + + Rect2* {.byref.} = object + position*: Vector2 + size*: Vector2 + + Transform2D* {.byref.} = object + elements*: array[3, Vector2] + + Transform* {.byref.} = object + basis*: Basis + origin*: Vector3 + + RID* {.byref.} = object + data: array[sizeof(int), byte] + + Error* {.size: sizeof(cint), pure.} = enum + OK, + Failed, ## Generic fail error + Unavailable, ## What is requested is unsupported/unavailable + Unconfigured, ## The object being used hasnt been properly set up yet + Unauthorized, ## Missing credentials for requested resource + ParameterRangeError, ## Parameter given out of range (5) + OutOfMemory, ## Out of memory + FileNotFound, + FileBadDrive, + FileBadPath, + FileNoPermission, ## (10) + FileAlreadyInUse, + FileCantOpen, + FileCantWrite, + FileCantRead, + FileUnrecognized, ## (15) + FileCorrupt, + FileMissingDependencies, + FileEOF, + CantOpen, ## Can't open a resource/socket/file + CantCreate, ## (20) + QueryFailed, + AlreadyInUse, + Locked, ## resource is locked + Timeout, + CantConnect, ## (25) + CantResolve, + ConnectionError, + CantAquireResource, + CantFork, + InvalidData, ## Data passed is invalid (30) + InvalidParameter, ## Parameter passed is invalid + AlreadyExists, ## When adding, item already exists + DoesNotExist, ## When retrieving/erasing, it item does not exist + DatabaseCantRead, ## Database is full + DatabaseCantWrite, ## Database is full (35) + CompilationFailed, + MethodNotFound, + LinkFailed, + ScriptFailed, + CyclicLink, ## (40) + InvalidDeclaration, + DuplicateSymbol, + PauseError, + Busy, + Skip, ## (45) + Help, ## user requested help!! + Bug, + ## a bug in the software certainly happened, due to a double + ## check failing or unexpected behavior. + PrinterOnFire, ## the parallel port printer is engulfed in flames + WTF ## shit happens, has never been used, though diff --git a/godot/core/nim.cfg b/godot/core/nim.cfg new file mode 100644 index 0000000..f1fb6a7 --- /dev/null +++ b/godot/core/nim.cfg @@ -0,0 +1 @@ +--path:"$projectdir/../" \ No newline at end of file diff --git a/godot/core/nodepaths.nim b/godot/core/nodepaths.nim index bb1b989..bf690d7 100644 --- a/godot/core/nodepaths.nim +++ b/godot/core/nodepaths.nim @@ -1,8 +1,9 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. -import godotbase +import hashes -import "../internal/godotnodepaths.nim", "../internal/godotstrings.nim" +import internal/godotinternaltypes, internal/godotnodepaths, + internal/godotstrings type NodePath* = ref object @@ -33,6 +34,9 @@ proc `$`*(self: NodePath): string {.inline.} = result = $s s.deinit() +proc hash*(self: NodePath): Hash {.inline.} = + ($self).hash() + proc isAbsolute*(self: NodePath): bool {.inline.} = self.path.isAbsolute() @@ -52,8 +56,8 @@ proc getSubname*(self: NodePath; idx: int): string {.inline.} = result = $s s.deinit() -proc property*(self: NodePath): string {.inline.} = - var s = self.path.property() +proc getConcatenatedSubnames*(self: NodePath): string {.inline.} = + var s = self.path.getConcatenatedSubnames() result = $s s.deinit() diff --git a/godot/core/planes.nim b/godot/core/planes.nim index 46b062a..2d15c79 100644 --- a/godot/core/planes.nim +++ b/godot/core/planes.nim @@ -1,73 +1,66 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import godotbase, vector3 +import hashes -import "../internal/godotstrings.nim" +import vector3 -type - Plane* {.byref.} = object - normal*: Vector3 - d*: float32 +import internal/godotinternaltypes, internal/godotstrings +import godotcoretypes, gdnativeapi -proc initPlane(dest: var Plane; a, b, c, d: float32) {. - importc: "godot_plane_new_with_reals".} -proc initPlane(dest: var Plane; v1, v2, v3: Vector3) {. - importc: "godot_plane_new_with_vectors".} -proc initPlane(dest: var Plane; normal: Vector3; d: float32) {. - importc: "godot_plane_new_with_normal".} +proc initPlane*(a, b, c, d: float32): Plane {.inline.} = + getGDNativeAPI().planeNewWithReals(result, a, b, c, d) -proc initPlane*(a, b, c, d: float32): Plane = - initPlane(result, a, b, c, d) +proc initPlane*(v1, v2, v3: Vector3): Plane {.inline.} = + getGDNativeAPI().planeNewWithVectors(result, v1, v2, v3) -proc initPlane*(v1, v2, v3: Vector3): Plane = - initPlane(result, v1, v2, v3) - -proc initPlane*(normal: Vector3; d: float32): Plane = - initPlane(result, normal, d) - -proc toGodotString(self: Plane): GodotString {. - noSideEffect, - importc: "godot_plane_as_string".} +proc initPlane*(normal: Vector3; d: float32): Plane {.inline.} = + result = Plane( + normal: normal, + d: d + ) proc `$`*(self: Plane): string {.inline.} = - $self.toGodotString() + $getGDNativeAPI().planeAsString(self) + +proc hash*(self: Plane): Hash {.inline, noinit.} = + !$(self.normal.hash() !& self.d.hash()) + +proc normalized*(self: Plane): Plane {.inline.} = + getGDNativeAPI().planeNormalized(self).toPlane() + +proc center*(self: Plane): Vector3 {.inline.} = + getGDNativeAPI().planeCenter(self).toVector3() + +proc getAnyPoint*(self: Plane): Vector3 {.inline.} = + getGDNativeAPI().planeGetAnyPoint(self).toVector3() + +proc isPointOver*(self: Plane; point: Vector3): bool {.inline.} = + getGDNativeAPI().planeIsPointOver(self, point) + +proc distanceTo*(self: Plane; point: Vector3): float32 {.inline.} = + getGDNativeAPI().planeDistanceTo(self, point) -proc normalized*(self: Plane): Plane {. - noSideEffect, - importc: "godot_plane_normalized".} -proc center*(self: Plane): Vector3 {. - noSideEffect, - importc: "godot_plane_center".} -proc getAnyPoint*(self: Plane): Vector3 {. - noSideEffect, - importc: "godot_plane_get_any_point".} -proc isPointOver*(self: Plane; point: Vector3): bool {. - noSideEffect, - importc: "godot_plane_is_point_over".} -proc distanceTo*(self: Plane; point: Vector3): float32 {. - noSideEffect, - importc: "godot_plane_distance_to".} proc contains*(self: Plane; point: Vector3; - epsilon: float32): bool {. - noSideEffect, - importc: "godot_plane_has_point".} -proc project*(self: Plane; point: Vector3): Vector3 {. - noSideEffect, - importc: "godot_plane_project".} + epsilon: float32): bool {.inline.} = + getGDNativeAPI().planeHasPoint(self, point, epsilon) + +proc project*(self: Plane; point: Vector3): Vector3 {.inline.} = + getGDNativeAPI().planeProject(self, point).toVector3() + proc intersect3*(self: Plane; dest: var Vector3; - b, c: Plane): bool {. - noSideEffect, - importc: "godot_plane_intersect_3".} + b, c: Plane): bool {.inline.} = + getGDNativeAPI().planeIntersect3(self, dest, b, c) + proc intersectsRay*(self: Plane; dest: var Vector3; - v, dir: Vector3): bool {. - noSideEffect, - importc: "godot_plane_intersects_ray".} + v, dir: Vector3): bool {.inline.} = + getGDNativeAPI().planeIntersectsRay(self, dest, v, dir) + proc intersectsSegment*(self: Plane; dest: var Vector3; - segmentBegin, segmentEnd: Vector3): bool {. - noSideEffect, importc: "godot_plane_intersects_segment".} -proc `-`*(self: Plane): Plane {. - noSideEffect, - importc: "godot_plane_operator_neg".} -proc `==`*(a, b: Plane): bool {. - noSideEffect, - importc: "godot_plane_operator_equal".} + segmentBegin, segmentEnd: Vector3): bool {.inline.} = + getGDNativeAPI().planeIntersectsSegment(self, dest, segmentBegin, segmentEnd) + +proc `-`*(self: Plane): Plane {.inline.} = + getGDNativeAPI().planeOperatorNeg(self).toPlane() + +proc `==`*(a, b: Plane): bool {.inline.} = + getGDNativeAPI().planeOperatorEqual(a, b) diff --git a/godot/core/poolarrays.nim b/godot/core/poolarrays.nim index 054b8f1..29fda96 100644 --- a/godot/core/poolarrays.nim +++ b/godot/core/poolarrays.nim @@ -1,11 +1,14 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. -import godotbase, vector2, vector3, colors -import "../internal/godotpoolarrays.nim", "../internal/godotstrings.nim" +import hashes -# byte -template definePoolArray(T, GodotT, DataT, fieldName, newProcName, initProcName; - noData = false) = +import godotcoretypes +import internal/godotinternaltypes, internal/godotpoolarrays, + internal/godotstrings +import vector2, vector3, colors + +template definePoolArrayBase(T, GodotT, DataT, fieldName, newProcName, + initProcName) = type T* = ref object fieldName: GodotT @@ -17,57 +20,101 @@ template definePoolArray(T, GodotT, DataT, fieldName, newProcName, initProcName; new(result, poolArrayFinalizer) initProcName(result.fieldName) - proc newProcName*(arr: Array): T {.inline.} = - new(result, poolArrayFinalizer) - initProcName(result.fieldName, arr.godotArray[]) - - proc newProcName*(arr: GodotT): T {.inline.} = - new(result, poolArrayFinalizer) - result.fieldName = arr - - proc add*(self: var T; arr: T) {.inline.} = - self.fieldName.add(arr.fieldName) - - proc delete*(self: var T; idx: int) {.inline.} = - self.fieldName.delete(idx.cint) - - proc reverse*(self: var T) {.inline.} = - self.fieldName.reverse() - - proc setLen*(self: var T; size: int) {.inline.} = - self.fieldName.setLen(size.cint) - - proc len*(self: T): int {.inline.} = - self.fieldName.len.int - proc fieldName*(self: T): ptr GodotT {.inline.} = ## WARNING: do not keep the returned value for longer than the lifetime of ## the array. addr self.fieldName + proc newProcName*(arr: GodotT): T {.inline.} = + new(result, poolArrayFinalizer) + result.fieldName = arr + + proc hash*(arr: T): Hash = + for item in arr.fieldName.items(): + result = result !& + (when type(item) is GodotString: ($item).hash() else: item.hash()) + result = !$result + +definePoolArrayBase(PoolByteArray, GodotPoolByteArray, uint8, + godotPoolByteArray, newPoolByteArray, + initGodotPoolByteArray) +definePoolArrayBase(PoolIntArray, GodotPoolIntArray, cint, + godotPoolIntArray, newPoolIntArray, + initGodotPoolIntArray) +definePoolArrayBase(PoolRealArray, GodotPoolRealArray, float32, + godotPoolRealArray, newPoolRealArray, + initGodotPoolRealArray) +definePoolArrayBase(PoolVector2Array, GodotPoolVector2Array, Vector2, + godotPoolVector2Array, newPoolVector2Array, + initGodotPoolVector2Array) +definePoolArrayBase(PoolVector3Array, GodotPoolVector3Array, Vector3, + godotPoolVector3Array, newPoolVector3Array, + initGodotPoolVector3Array) +definePoolArrayBase(PoolColorArray, GodotPoolColorArray, Color, + godotPoolColorArray, newPoolColorArray, + initGodotPoolColorArray) +definePoolArrayBase(PoolStringArray, GodotPoolStringArray, string, + godotPoolStringArray, newPoolStringArray, + initGodotPoolStringArray) + +import arrays + +template definePoolArray(T, GodotT, DataT, fieldName, newProcName, initProcName; + noData = false) = + + proc newProcName*(arr: Array): T {.inline.} = + new(result, poolArrayFinalizer) + initProcName(result.fieldName, arr.godotArray[]) + + proc add*(self: T; arr: T) {.inline.} = + self.fieldName.add(arr.fieldName) + + proc delete*(self: T; idx: int) {.inline.} = + self.fieldName.delete(idx.cint) + + proc reverse*(self: T) {.inline.} = + self.fieldName.reverse() + + proc setLen*(self: T; size: int) {.inline.} = + self.fieldName.setLen(size.cint) + + proc len*(self: T): int {.inline.} = + self.fieldName.len.int + + proc subarray*(self: T, idxFrom, idxTo: int): T {.inline.} = + ## Indexes are inclusive, negative values count from the end of the array. + assert(idxFrom >= low(cint) and idxFrom <= high(cint) and + idxTo >= low(cint) and idxTo <= high(cint)) + newProcName(self.fieldName.subarray(idxFrom.cint, idxTo.cint)) + when not noData: - proc add*(self: var T; data: DataT) {.inline.} = + proc add*(self: T; data: DataT) {.inline.} = self.fieldName.add(data) - proc addFirst*(self: var T, data: DataT) {.inline.} = - self.fieldName.addFirst(data) - - proc insert*(self: var T; idx: int; data: DataT): Error {.inline.} = + proc insert*(self: T; idx: int; data: DataT): Error {.inline.} = self.fieldName.insert(idx.cint, data) - proc `[]=`*(self: var T; idx: int; data: DataT) {.inline.} = + proc `[]=`*(self: T; idx: int; data: DataT) {.inline.} = self.fieldName[idx.cint] = data proc `[]`*(self: T; idx: int): DataT {.inline.} = self.fieldName[idx.cint] iterator items*(arr: T): DataT = - for i in 0..= (b.position.x + b.size.x): + return false + if a.position.x + a.size.x <= b.position.x: + return false + if a.position.y >= (b.position.y + b.size.y): + return false + if a.position.y + a.size.y <= b.position.y: + return false + result = true + +proc distanceTo*(self: Rect2, p: Vector2): float32 {.noinit.} = + var inside = true + if p.x < self.position.x: + let d = self.position.x - p.x + result = d + inside = false + if p.y < self.position.y: + let d = self.position.y - p.y + result = if inside: d else: min(result, d) + inside = false + if p.x >= (self.position.x + self.size.x): + let d = p.x - (self.position.x + self.size.x) + result = if inside: d else: min(result, d) + inside = false + if p.y >= (self.position.y + self.size.y): + let d = p.y - (self.position.y + self.size.y) + result = if inside: d else: min(result, d) + inside = false + + if inside: + result = 0'f32 + +proc encloses*(a, b: Rect2): bool {.inline, noinit.} = + b.position.x >= a.position.x and b.position.y >= a.position.y and + (b.position.x + b.size.x) < (a.position.x + a.size.x) and + (b.position.y + b.size.y) < (a.position.y + a.size.y) + +proc hasNoArea*(self: Rect2): bool {.inline, noinit.} = + self.size.x <= 0 or self.size.y <= 0 + +proc clip*(self, b: Rect2): Rect2 {.inline, noinit.} = + if not self.intersects(b): + return initRect2() + + result = self + + result.position.x = max(b.position.x, self.position.x) + result.position.y = max(b.position.y, self.position.y) + + let bEnd = b.position + b.size + let selfEnd = self.position + self.size + + result.size.x = min(bEnd.x, selfEnd.x) - result.position.x + result.size.y = min(bEnd.y, selfEnd.y) - result.position.y + +proc merge*(self, b: Rect2): Rect2 {.inline, noinit.} = + result.position.x = min(b.position.x, self.position.x) + result.position.y = min(b.position.y, self.position.y) + + result.size.x = max(b.position.x + b.size.x, self.position.x + self.size.x) + result.size.y = max(b.position.y + b.size.y, self.position.y + self.size.y) + result.size -= result.position + +proc contains*(self: Rect2; point: Vector2): bool {.inline, noinit.} = + if point.x < self.position.x: + return false + if point.y < self.position.y: + return false + + if point.x >= self.position.x + self.size.x: + return false + if point.y >= self.position.y + self.size.y: + return false + + result = true + +proc grow*(self: Rect2; by: float32): Rect2 {.inline, noinit.} = + ## Returns Rect2 enlarged by the specified size in every direction. + result = self + + result.position.x -= by + result.position.y -= by + + result.size.x += by * 2 + result.size.y += by * 2 + +proc growIndividual*(self: Rect2, left, top: float32, + right, bottom: float32): Rect2 {.inline, noinit.} = + result = self + result.position.x -= left + result.position.y -= top + result.size.x += left + right + result.size.y += top + bottom + +proc expandTo*(self: var Rect2, to: Vector2) {.inline.} = + var startPoint = self.position + var endPoint = self.position + self.size + + if to.x < startPoint.x: + startPoint.x = to.x + if to.y < startPoint.y: + startPoint.y = to.y + + if to.x > endPoint.x: + endPoint.x = to.x + if to.y > endPoint.y: + endPoint.y = to.y + + self.position = startPoint + self.size = endPoint - startPoint + +proc expand*(self: Rect2; to: Vector2): Rect2 {.inline, noinit.} = + result = self + result.expandTo(to) + +proc abs*(self: Rect2): Rect2 {.inline, noinit.} = + Rect2(position: vec2(self.position.x + min(self.size.x, 0'f32), + self.position.y + min(self.size.y, 0'f32)), + size: abs(self.size)) + +proc `==`*(a, b: Rect2): bool {.inline, noinit.} = + a.position == b.position and a.size == b.size + +{.pop.} # stackTrace: off \ No newline at end of file diff --git a/godot/core/rect3.nim b/godot/core/rect3.nim deleted file mode 100644 index abb6b66..0000000 --- a/godot/core/rect3.nim +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2017 Xored Software, Inc. - -import godotbase, planes, vector3 - -import "../internal/godotstrings.nim" - -type - Rect3* {.byref.} = object - position*: Vector3 - size*: Vector3 - -proc initRect3*(pos, size: Vector3): Rect3 {.inline.} = - Rect3(position: pos, size: size) - -proc toGodotString(self: Rect3): GodotString {. - noSideEffect, - importc: "godot_rect3_as_string".} - -proc `$`*(self: Rect3): string {.inline.} = - $self.toGodotString() - -proc area*(self: Rect3): float32 {. - noSideEffect, - importc: "godot_rect3_get_area".} -proc hasNoArea*(self: Rect3): bool {. - noSideEffect, - importc: "godot_rect3_has_no_area".} -proc hasNoSurface*(self: Rect3): bool {. - noSideEffect, - importc: "godot_rect3_has_no_surface".} -proc intersects*(a, b: Rect3): bool {. - noSideEffect, - importc: "godot_rect3_intersects".} -proc encloses*(self, other: Rect3): bool {. - noSideEffect, - importc: "godot_rect3_encloses".} -proc merge*(self, other: Rect3): Rect3 {. - noSideEffect, - importc: "godot_rect3_merge".} -proc intersection*(self, other: Rect3): Rect3 {. - noSideEffect, - importc: "godot_rect3_intersection".} -proc intersectsPlane*(self: Rect3; plane: Plane): bool {. - noSideEffect, - importc: "godot_rect3_intersects_plane".} -proc intersectsSegment*(self: Rect3; start, to: Vector3): bool {. - noSideEffect, - importc: "godot_rect3_intersects_segment".} -proc contains*(self: Rect3; point: Vector3): bool {. - noSideEffect, - importc: "godot_rect3_has_point".} -proc getSupport*(self: Rect3; dir: Vector3): Vector3 {. - noSideEffect, - importc: "godot_rect3_get_support".} -proc getLongestAxis*(self: Rect3): Vector3 {. - noSideEffect, - importc: "godot_rect3_get_longest_axis".} -proc getLongestAxisIndex*(self: Rect3): cint {. - noSideEffect, - importc: "godot_rect3_get_longest_axis_index".} -proc getLongestAxisSize*(self: Rect3): float32 {. - noSideEffect, - importc: "godot_rect3_get_longest_axis_size".} -proc getShortestAxis*(self: Rect3): Vector3 {. - noSideEffect, - importc: "godot_rect3_get_shortest_axis".} -proc getShortestAxisIndex*(self: Rect3): cint {. - noSideEffect, - importc: "godot_rect3_get_shortest_axis_index".} -proc getShortestAxisSize*(self: Rect3): float32 {. - noSideEffect, - importc: "godot_rect3_get_shortest_axis_size".} -proc expand*(self: Rect3; toPoint: Vector3): Rect3 {. - noSideEffect, - importc: "godot_rect3_expand".} -proc grow*(self: Rect3; by: float32): Rect3 {. - noSideEffect, - importc: "godot_rect3_grow".} -proc getEndpoint*(self: Rect3; idx: cint): Vector3 {. - noSideEffect, - importc: "godot_rect3_get_endpoint".} -proc `==`*(a, b: Rect3): bool {. - noSideEffect, - importc: "godot_rect3_operator_equal".} diff --git a/godot/core/rids.nim b/godot/core/rids.nim index ad1ea84..a64137d 100644 --- a/godot/core/rids.nim +++ b/godot/core/rids.nim @@ -1,30 +1,26 @@ -import godotbase +# Copyright (c) 2018 Xored Software, Inc. -import "../internal/godotinternaltypes.nim" +import hashes -type - RID* {.byref.} = object - p: pointer - -proc initRID(dest: var RID) {. - importc: "godot_rid_new".} -proc initRID(dest: var RID; obj: ptr GodotObject) {. - importc: "godot_rid_new_with_resource".} +import godotcoretypes, internal/godotinternaltypes, gdnativeapi proc initRID*(): RID {.inline.} = - initRID(result) + getGDNativeAPI().ridNew(result) proc initRID*(obj: ptr GodotObject): RID {.inline.} = - initRID(result, obj) - -proc idCInt(self: RID): cint {. - noSideEffect, - importc: "godot_rid_get_id".} + getGDNativeAPI().ridNewWithResource(result, obj) proc id*(self: RID): uint32 {.inline.} = - cast[uint32](self.idCInt()) + cast[uint32](getGDNativeAPI().ridGetId(self)) -proc `==`*(a, b: RID): bool {. - importc: "godot_rid_operator_equal".} -proc `<`*(a, b: RID): bool {. - importc: "godot_rid_operator_less".} +proc `$`*(self: RID): string {.inline.} = + $self.id + +proc hash*(self: RID): Hash {.inline.} = + self.id.hash() + +proc `==`*(a, b: RID): bool {.inline.} = + getGDNativeAPI().ridOperatorEqual(a, b) + +proc `<`*(a, b: RID): bool {.inline.} = + getGDNativeAPI().ridOperatorLess(a, b) diff --git a/godot/core/transform2d.nim b/godot/core/transform2d.nim index 84baabd..a8db09e 100644 --- a/godot/core/transform2d.nim +++ b/godot/core/transform2d.nim @@ -1,76 +1,79 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import godotbase, vector2, rect2 +import hashes, vector2 -import "../internal/godotstrings.nim" - -type - Transform2D* {.byref.} = object - elements*: array[3, Vector2] - -proc initTransform2D(dest: var Transform2D) {. - importc: "godot_transform2d_new_identity".} -proc initTransform2D(dest: var Transform2D; rot: float32; pos: Vector2) {. - importc: "godot_transform2d_new".} -proc initTransform2D(dest: var Transform2D; xAxis, yAxis, origin: Vector2) {. - importc: "godot_transform2d_new_axis_origin".} +import internal/godotinternaltypes, internal/godotstrings +import godotcoretypes, gdnativeapi proc initTransform2D*(): Transform2D {.inline.} = - initTransform2D(result) + getGDNativeAPI().transform2DNewIdentity(result) proc initTransform2D*(rot: float32; pos: Vector2): Transform2D {.inline.} = - initTransform2D(result, rot, pos) + getGDNativeAPI().transform2DNew(result, rot, pos) proc initTransform2D*(xAxis, yAxis, origin: Vector2): Transform2D {.inline.} = - initTransform2D(result, xAxis, yAxis, origin) - -proc toGodotString(self: Transform2D): GodotString {. - importc: "godot_transform2d_as_string".} + getGDNativeAPI().transform2DNewAxisOrigin(result, xAxis, yAxis, origin) proc `$`*(self: Transform2D): string {.inline.} = - $self.toGodotString() + $getGDNativeAPI().transform2DAsString(self) -proc inverse*(self: Transform2D): Transform2D {. - importc: "godot_transform2d_inverse".} -proc affineInverse*(self: Transform2D): Transform2D {. - importc: "godot_transform2d_affine_inverse".} -proc rotation*(self: Transform2D): float32 {. - importc: "godot_transform2d_get_rotation".} -proc origin*(self: Transform2D): Vector2 {. - importc: "godot_transform2d_get_origin".} -proc scale*(self: Transform2D): Vector2 {. - importc: "godot_transform2d_get_scale".} -proc orthonormalized*(self: Transform2D): Transform2D {. - importc: "godot_transform2d_orthonormalized".} -proc rotated*(self: Transform2D; phi: float32): Transform2D {. - importc: "godot_transform2d_rotated".} -proc scaled*(self: Transform2D; scale: Vector2): Transform2D {. - importc: "godot_transform2d_scaled".} -proc translated*(self: Transform2D; - offset: Vector2): Transform2D {. - importc: "godot_transform2d_translated".} -proc xformVector2*(self: Transform2D; v: Vector2): Vector2 {. - importc: "godot_transform2d_xform_vector2".} -proc xformInvVector2*(self: Transform2D; v: Vector2): Vector2 {. - importc: "godot_transform2d_xform_inv_vector2".} -proc basisXformVector2*(self: Transform2D; - v: Vector2): Vector2 {. - importc: "godot_transform2d_basis_xform_vector2".} -proc basisXformInvVector2*(self: Transform2D; - v: Vector2): Vector2 {. - importc: "godot_transform2d_basis_xform_inv_vector2".} -proc xformRect2*(self: Transform2D; v: Rect2): Rect2 {. - importc: "godot_transform2d_xform_rect2".} -proc xformInvRect2*(self: Transform2D; v: Rect2): Rect2 {. - importc: "godot_transform2d_xform_inv_rect2".} +proc hash*(self: Transform2D): Hash {.inline, noinit.} = + !$(self.elements[0].hash() !& self.elements[1].hash() !& self.elements[2].hash()) + +proc inverse*(self: Transform2D): Transform2D {.inline.} = + getGDNativeAPI().transform2DInverse(self).toTransform2D() + +proc affineInverse*(self: Transform2D): Transform2D {.inline.} = + getGDNativeAPI().transform2DAffineInverse(self).toTransform2D() + +proc rotation*(self: Transform2D): float32 {.inline.} = + getGDNativeAPI().transform2DGetRotation(self) + +proc origin*(self: Transform2D): Vector2 {.inline.} = + getGDNativeAPI().transform2DGetOrigin(self).toVector2() + +proc scale*(self: Transform2D): Vector2 {.inline.} = + getGDNativeAPI().transform2DGetScale(self).toVector2() + +proc orthonormalized*(self: Transform2D): Transform2D {.inline.} = + getGDNativeAPI().transform2DOrthonormalized(self).toTransform2D() + +proc rotated*(self: Transform2D; phi: float32): Transform2D {.inline.} = + getGDNativeAPI().transform2DRotated(self, phi).toTransform2D() + +proc scaled*(self: Transform2D; scale: Vector2): Transform2D {.inline.} = + getGDNativeAPI().transform2DScaled(self, scale).toTransform2D() + +proc translated*(self: Transform2D; offset: Vector2): Transform2D {.inline.} = + getGDNativeAPI().transform2DTranslated(self, offset).toTransform2D() + +proc xformVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} = + getGDNativeAPI().transform2DXformVector2(self, v).toVector2() + +proc xformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} = + getGDNativeAPI().transform2DXformInvVector2(self, v).toVector2() + +proc basisXformVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} = + getGDNativeAPI().transform2DBasisXformVector2(self, v).toVector2() + +proc basisXformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} = + getGDNativeAPI().transform2DBasisXformInvVector2(self, v).toVector2() + +proc xformRect2*(self: Transform2D; rect: Rect2): Rect2 {.inline.} = + getGDNativeAPI().transform2DXformRect2(self, rect).toRect2() + +proc xformInvRect2*(self: Transform2D; rect: Rect2): Rect2 {.inline.} = + getGDNativeAPI().transform2DXformInvRect2(self, rect).toRect2() proc interpolateWith*(self, m: Transform2D; - c: float32): Transform2D {. - importc: "godot_transform2d_interpolate_with".} -proc `==`*(a, b: Transform2D): bool {. - importc: "godot_transform2d_operator_equal".} -proc `*`*(a, b: Transform2D): Transform2D {. - importc: "godot_transform2d_operator_multiply".} + c: float32): Transform2D {.inline.} = + getGDNativeAPI().transform2DInterpolateWith(self, m, c).toTransform2D() + +proc `==`*(a, b: Transform2D): bool {.inline.} = + getGDNativeAPI().transform2DOperatorEqual(a, b) + +proc `*`*(a, b: Transform2D): Transform2D {.inline.} = + getGDNativeAPI().transform2DOperatorMultiply(a, b).toTransform2D() proc `*=`*(a: var Transform2D, b: Transform2D) {.inline.} = a = a * b diff --git a/godot/core/transforms.nim b/godot/core/transforms.nim index a2558f1..501f743 100644 --- a/godot/core/transforms.nim +++ b/godot/core/transforms.nim @@ -1,16 +1,13 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import godotbase, basis, vector3, planes, rect3 +import hashes -import "../internal/godotstrings.nim" - -type - Transform* {.byref.} = object - basis*: Basis - origin*: Vector3 +import internal/godotinternaltypes, internal/godotstrings +import godotcoretypes, gdnativeapi +import basis, vector3 proc initTransform*(): Transform {.inline.} = - discard + result.basis = initBasis() proc initTransform*(xAxis, yAxis, zAxis, origin: Vector3): Transform {.inline.} = @@ -23,45 +20,57 @@ proc initTransform*(xAxis, yAxis, zAxis, proc initTransform*(basis: Basis, origin: Vector3): Transform {.inline.} = Transform(basis: basis, origin: origin) -proc toGodotString(self: Transform): GodotString {. - importc: "godot_transform_as_string".} - proc `$`*(self: Transform): string {.inline.} = - $self.toGodotString() + $getGDNativeAPI().transformAsString(self) + +proc hash*(self: Transform): Hash {.inline.} = + !$(self.basis.hash() !& self.origin.hash()) + +proc inverse*(self: Transform): Transform {.inline.} = + getGDNativeAPI().transformInverse(self).toTransform() + +proc affineInverse*(self: Transform): Transform {.inline.} = + getGDNativeAPI().transformAffineInverse(self).toTransform() + +proc orthonormalized*(self: Transform): Transform {.inline.} = + getGDNativeAPI().transformOrthonormalized(self).toTransform() -proc inverse*(self: Transform): Transform {. - importc: "godot_transform_inverse".} -proc affineInverse*(self: Transform): Transform {. - importc: "godot_transform_affine_inverse".} -proc orthonormalized*(self: Transform): Transform {. - importc: "godot_transform_orthonormalized".} proc rotated*(self: Transform; axis: Vector3; - phi: float32): Transform {. - importc: "godot_transform_rotated".} -proc scaled*(self: Transform; scale: Vector3): Transform {. - importc: "godot_transform_scaled".} -proc translated*(self: Transform; offset: Vector3): Transform {. - importc: "godot_transform_translated".} -proc lookingAt*(self: Transform; - target, up: Vector3): Transform {. - importc: "godot_transform_looking_at".} + phi: float32): Transform {.inline.} = + getGDNativeAPI().transformRotated(self, axis, phi).toTransform() -proc xformPlane*(self: Transform; v: Plane): Plane {. - importc: "godot_transform_xform_plane".} -proc xformInvPlane*(self: Transform; v: Plane): Plane {. - importc: "godot_transform_xform_inv_plane".} -proc xformVector3*(self: Transform; v: Vector3): Vector3 {. - importc: "godot_transform_xform_vector3".} -proc xformInvVector3*(self: Transform; v: Vector3): Vector3 {. - importc: "godot_transform_xform_inv_vector3".} -proc xformRect3*(self: Transform; v: Vector3): Rect3 {. - importc: "godot_transform_xform_rect3".} -proc xformInvRect3*(self: Transform; v: Vector3): Vector3 {. - importc: "godot_transform_xform_inv_rect3".} +proc scaled*(self: Transform; scale: Vector3): Transform {.inline.} = + getGDNativeAPI().transformScaled(self, scale).toTransform() -proc `==`*(self: Transform; b: Transform): bool {. - importc: "godot_transform_operator_equal".} -proc `*`*(a, b: Transform): Transform {. - importc: "godot_transform_operator_multiply".} -proc `*=`*(a: var Transform, b: Transform) {.inline.} = - a = a * b +proc translated*(self: Transform; offset: Vector3): Transform {.inline.} = + getGDNativeAPI().transformTranslated(self, offset).toTransform() + +proc lookingAt*(self: Transform; target, up: Vector3): Transform {.inline.} = + getGDNativeAPI().transformLookingAt(self, target, up).toTransform() + +proc xformPlane*(self: Transform; plane: Plane): Plane {.inline.} = + getGDNativeAPI().transformXformPlane(self, plane).toPlane() + +proc xformInvPlane*(self: Transform; plane: Plane): Plane {.inline.} = + getGDNativeAPI().transformXformInvPlane(self, plane).toPlane() + +proc xformVector3*(self: Transform; v: Vector3): Vector3 {.inline.} = + getGDNativeAPI().transformXformVector3(self, v).toVector3() + +proc xformInvVector3*(self: Transform; v: Vector3): Vector3 {.inline.} = + getGDNativeAPI().transformXformInvVector3(self, v).toVector3() + +proc xformAABB*(self: Transform; rect: AABB): AABB {.inline.} = + getGDNativeAPI().transformXformAABB(self, rect).toAABB() + +proc xformInvAABB*(self: Transform; rect: AABB): AABB {.inline.} = + getGDNativeAPI().transformXformInvAABB(self, rect).toAABB() + +proc `==`*(self: Transform; b: Transform): bool {.inline.} = + getGDNativeAPI().transformOperatorEqual(self, b) + +proc `*`*(self, other: Transform): Transform {.inline.} = + getGDNativeAPI().transformOperatorMultiply(self, other).toTransform() + +proc `*=`*(self: var Transform, other: Transform) {.inline.} = + self = self * other diff --git a/godot/core/variants.nim b/godot/core/variants.nim index c967370..fcb2b04 100644 --- a/godot/core/variants.nim +++ b/godot/core/variants.nim @@ -1,46 +1,59 @@ -import tables +import tables, hashes -import godotbase -import basis, nodepaths -import planes, poolarrays, quats, rect2, rect3, rids -import transforms, transform2d, vector2 -import vector3, colors +import godotcoretypes +import internal/godotinternaltypes, internal/godotvariants, + internal/godotstrings, internal/godotdictionaries, + internal/godotarrays -import "../internal/godotinternaltypes.nim" -import "../internal/godotvariants.nim", "../internal/godotpoolarrays.nim", - "../internal/godotstrings.nim", "../internal/godotnodepaths.nim" +type + Variant* = ref object + godotVariant: GodotVariant + noDeinit: bool # used to avoid copying when passing the variant to Godot export VariantType, VariantCallErrorType, VariantCallError -proc getType*(v: Variant): VariantType = - v.godotVariant[].getType() +proc markNoDeinit*(v: Variant) {.inline.} = + ## Makes it so that internal GodotVariant object will not be destroyed + ## when the reference is gone. Use only if you know what you are doing. + v.noDeinit = true -proc variantFinalizer(v: Variant) = - if not v.isNoDeinit: - v.godotVariant[].deinit() +proc godotVariant*(v: Variant): ptr GodotVariant {.inline.} = + ## WARNING: do not keep the returned value for longer than the lifetime of + ## ``v`` + addr v.godotVariant + +proc getType*(v: Variant): VariantType = + v.godotVariant.getType() + +proc variantFinalizer*(v: Variant) = + if not v.noDeinit: + v.godotVariant.deinit() + +proc `$`*(self: Variant): string {.inline.} = + $self.godotVariant proc newVariant*(): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[]) + initGodotVariant(result.godotVariant) proc newVariant*(v: Variant): Variant {.inline.} = ## Makes a copy new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], v.godotVariant[]) + initGodotVariant(result.godotVariant, v.godotVariant) proc newVariant*(v: GodotVariant): Variant {.inline.} = new(result, variantFinalizer) - result.godotVariant[] = v + result.godotVariant = v proc newVariant*(b: bool): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], b) + initGodotVariant(result.godotVariant, b) # resolves Nim call ambiguities well template numConstructor(T, ConvT) = proc newVariant*(i: T): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], ConvT(i)) + initGodotVariant(result.godotVariant, ConvT(i)) numConstructor(uint8, uint64) numConstructor(uint16, uint64) @@ -56,206 +69,240 @@ numConstructor(int, int64) proc newVariant*(r: cdouble): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], r) - -proc newVariant*(s: GodotString): Variant {.inline.} = - new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], s) + initGodotVariant(result.godotVariant, r) proc newVariant*(s: string): Variant {.inline.} = new(result, variantFinalizer) + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + if s.isNil: + initGodotVariant(result.godotVariant) + return var godotStr = s.toGodotString() - initGodotVariant(result.godotVariant[], godotStr) + initGodotVariant(result.godotVariant, godotStr) godotStr.deinit() +import basis, nodepaths +import planes, quats, rect2, aabb, rids +import transforms, transform2d, vector2 +import vector3, colors + proc newVariant*(v2: Vector2): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], v2) + initGodotVariant(result.godotVariant, v2) proc newVariant*(rect2: Rect2): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], rect2) + initGodotVariant(result.godotVariant, rect2) proc newVariant*(v3: Vector3): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], v3) + initGodotVariant(result.godotVariant, v3) proc newVariant*(t2d: Transform2D): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], t2d) + initGodotVariant(result.godotVariant, t2d) proc newVariant*(plane: Plane): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], plane) + initGodotVariant(result.godotVariant, plane) proc newVariant*(quat: Quat): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], quat) + initGodotVariant(result.godotVariant, quat) -proc newVariant*(rect3: Rect3): Variant {.inline.} = +proc newVariant*(aabb: AABB): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], rect3) + initGodotVariant(result.godotVariant, aabb) proc newVariant*(basis: Basis): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], basis) + initGodotVariant(result.godotVariant, basis) proc newVariant*(trans: Transform): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], trans) + initGodotVariant(result.godotVariant, trans) proc newVariant*(color: Color): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], color) + initGodotVariant(result.godotVariant, color) proc newVariant*(nodePath: NodePath): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], nodePath.godotNodePath[]) + initGodotVariant(result.godotVariant, nodePath.godotNodePath[]) proc newVariant*(godotNodePath: GodotNodePath): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], godotNodePath) + initGodotVariant(result.godotVariant, godotNodePath) proc newVariant*(rid: RID): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], rid) + initGodotVariant(result.godotVariant, rid) proc newVariant*(obj: ptr GodotObject): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], obj) + initGodotVariant(result.godotVariant, obj) + +import poolarrays + +proc newVariant*(pba: PoolByteArray): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pba.godotPoolByteArray[]) + +proc newVariant*(pia: PoolIntArray): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pia.godotPoolIntArray[]) + +proc newVariant*(pra: PoolRealArray): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pra.godotPoolRealArray[]) + +proc newVariant*(psa: PoolStringArray): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, psa.godotPoolStringArray[]) + +proc newVariant*(pv2a: PoolVector2Array): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pv2a.godotPoolVector2Array[]) + +proc newVariant*(pv3a: PoolVector3Array): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pv3a.godotPoolVector3Array[]) + +proc newVariant*(pca: PoolColorArray): Variant {.inline.} = + new(result, variantFinalizer) + initGodotVariant(result.godotVariant, pca.godotPoolColorArray[]) + +proc asBool*(self: Variant): bool {.inline.} = + self.godotVariant.asBool() + +proc asUInt*(self: Variant): uint64 {.inline.} = + self.godotVariant.asUInt() + +proc asInt*(self: Variant): int64 {.inline.} = + self.godotVariant.asInt() + +proc asReal*(self: Variant): cdouble {.inline.} = + self.godotVariant.asReal() + +proc asString*(self: Variant): string {.inline.} = + $self + +proc asVector2*(self: Variant): Vector2 {.inline.} = + self.godotVariant.asVector2() + +proc asRect2*(self: Variant): Rect2 {.inline.} = + self.godotVariant.asRect2() + +proc asVector3*(self: Variant): Vector3 {.inline.} = + self.godotVariant.asVector3() + +proc asTransform2D*(self: Variant): Transform2D {.inline.} = + self.godotVariant.asTransform2D() + +proc asPlane*(self: Variant): Plane {.inline.} = + self.godotVariant.asPlane() + +proc asQuat*(self: Variant): Quat {.inline.} = + self.godotVariant.asQuat() + +proc asAABB*(self: Variant): AABB {.inline.} = + self.godotVariant.asAABB() + +proc asBasis*(self: Variant): Basis {.inline.} = + self.godotVariant.asBasis() + +proc asTransform*(self: Variant): Transform {.inline.} = + self.godotVariant.asTransform() + +proc asColor*(self: Variant): Color {.inline.} = + self.godotVariant.asColor() + +proc asNodePath*(self: Variant): NodePath {.inline.} = + result = newNodePath(self.godotVariant.asNodePath()) + +proc asRID*(self: Variant): RID {.inline.} = + self.godotVariant.asRID() + +proc asGodotObject*(self: Variant): ptr GodotObject {.inline.} = + self.godotVariant.asGodotObject() + +proc asPoolByteArray*(self: Variant): PoolByteArray {.inline.} = + newPoolByteArray(self.godotVariant.asGodotPoolByteArray()) + +proc asPoolIntArray*(self: Variant): PoolIntArray {.inline.} = + newPoolIntArray(self.godotVariant.asGodotPoolIntArray()) + +proc asPoolRealArray*(self: Variant): PoolRealArray {.inline.} = + newPoolRealArray(self.godotVariant.asGodotPoolRealArray()) + +proc asPoolStringArray*(self: Variant): PoolStringArray {.inline.} = + newPoolStringArray(self.godotVariant.asGodotPoolStringArray()) + +proc asPoolVector2Array*(self: Variant): PoolVector2Array {.inline.} = + newPoolVector2Array(self.godotVariant.asGodotPoolVector2Array()) + +proc asPoolVector3Array*(self: Variant): PoolVector3Array {.inline.} = + newPoolVector3Array(self.godotVariant.asGodotPoolVector3Array()) + +proc asPoolColorArray*(self: Variant): PoolColorArray {.inline.} = + newPoolColorArray(self.godotVariant.asGodotPoolColorArray()) + +proc hash*(self: Variant): Hash = + proc objectHash(obj: ptr GodotObject): Hash = + if not obj.isNil: cast[int](obj).hash() else: 0.hash() + result = case self.getType(): + of VariantType.Nil: Hash(0) + of VariantType.Bool: self.asBool().hash() + of VariantType.Int: self.asInt().hash() + of VariantType.Real: self.asReal().hash() + of VariantType.String: self.asString().hash() + of VariantType.Vector2: self.asVector2().hash() + of VariantType.Rect2: self.asRect2().hash() + of VariantType.Vector3: self.asVector3().hash() + of VariantType.Transform2D: self.asTransform2D().hash() + of VariantType.Plane: self.asPlane().hash() + of VariantType.Quat: self.asQuat().hash() + of VariantType.AABB: self.asAABB().hash() + of VariantType.Basis: self.asBasis().hash() + of VariantType.Transform: self.asTransform().hash() + of VariantType.Color: self.asColor().hash() + of VariantType.NodePath: self.asNodePath().hash() + of VariantType.RID: self.asRID().hash() + of VariantType.Object: self.asGodotObject().objectHash() + of VariantType.Dictionary: hash(self.godotVariant.asGodotDictionary().godotHash()) + of VariantType.Array: hash(self.godotVariant.asGodotArray().godotHash()) + of VariantType.PoolByteArray: self.asPoolByteArray().hash() + of VariantType.PoolIntArray: self.asPoolIntArray().hash() + of VariantType.PoolRealArray: self.asPoolRealArray().hash() + of VariantType.PoolStringArray: self.asPoolStringArray().hash() + of VariantType.PoolVector2Array: self.asPoolVector2Array().hash() + of VariantType.PoolVector3Array: self.asPoolVector3Array().hash() + of VariantType.PoolColorArray: self.asPoolColorArray().hash() import arrays proc newVariant*(arr: Array): Variant {.inline.} = new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], arr.godotArray[]) + initGodotVariant(result.godotVariant, arr.godotArray[]) -proc newVariant*(pba: PoolByteArray): Variant {.inline.} = - new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], pba.godotPoolByteArray[]) - -proc newVariant*(pia: PoolIntArray): Variant {.inline.} = - initGodotVariant(result.godotVariant[], pia.godotPoolIntArray[]) - -proc newVariant*(pra: PoolRealArray): Variant {.inline.} = - initGodotVariant(result.godotVariant[], pra.godotPoolRealArray[]) - -proc newVariant*(psa: PoolStringArray): Variant {.inline.} = - initGodotVariant(result.godotVariant[], psa.godotPoolStringArray[]) - -proc newVariant*(pv2a: PoolVector2Array): Variant {.inline.} = - initGodotVariant(result.godotVariant[], pv2a.godotPoolVector2Array[]) - -proc newVariant*(pv3a: PoolVector3Array): Variant {.inline.} = - initGodotVariant(result.godotVariant[], pv3a.godotPoolVector3Array[]) - -proc newVariant*(pca: PoolColorArray): Variant {.inline.} = - initGodotVariant(result.godotVariant[], pca.godotPoolColorArray[]) - -import dictionaries - -proc newVariant*(dict: Dictionary): Variant {.inline.} = - new(result, variantFinalizer) - initGodotVariant(result.godotVariant[], dict.godotDictionary[]) - -proc asBool*(self: Variant): bool {.inline.} = - self.godotVariant[].asBool() - -proc asUInt*(self: Variant): uint64 = - self.godotVariant[].asUInt() - -proc asInt*(self: Variant): int64 = - self.godotVariant[].asInt() - -proc asReal*(self: Variant): cdouble = - self.godotVariant[].asReal() - -proc asString*(self: Variant): string = - var s = self.godotVariant[].asGodotString() - result = $s - s.deinit() - -proc asVector2*(self: Variant): Vector2 = - self.godotVariant[].asVector2() - -proc asRect2*(self: Variant): Rect2 = - self.godotVariant[].asRect2() - -proc asVector3*(self: Variant): Vector3 = - self.godotVariant[].asVector3() - -proc asTransform2D*(self: Variant): Transform2D = - self.godotVariant[].asTransform2D() - -proc asPlane*(self: Variant): Plane = - self.godotVariant[].asPlane() - -proc asQuat*(self: Variant): Quat = - self.godotVariant[].asQuat() - -proc asRect3*(self: Variant): Rect3 = - self.godotVariant[].asRect3() - -proc asBasis*(self: Variant): Basis = - self.godotVariant[].asBasis() - -proc asTransform*(self: Variant): Transform = - self.godotVariant[].asTransform() - -proc asColor*(self: Variant): Color = - self.godotVariant[].asColor() - -proc asNodePath*(self: Variant): NodePath = - result = newNodePath(self.godotVariant[].asNodePath()) - -proc asRID*(self: Variant): RID = - self.godotVariant[].asRID() - -proc asGodotObject*(self: Variant): ptr GodotObject = - self.godotVariant[].asGodotObject() - -proc asArray*(self: Variant): Array = - newArray(self.godotVariant[].asGodotArray()) - -proc asPoolByteArray*(self: Variant): PoolByteArray = - newPoolByteArray(self.godotVariant[].asGodotPoolByteArray()) - -proc asPoolIntArray*(self: Variant): PoolIntArray = - newPoolIntArray(self.godotVariant[].asGodotPoolIntArray()) - -proc asPoolRealArray*(self: Variant): PoolRealArray = - newPoolRealArray(self.godotVariant[].asGodotPoolRealArray()) - -proc asPoolStringArray*(self: Variant): PoolStringArray = - newPoolStringArray(self.godotVariant[].asGodotPoolStringArray()) - -proc asPoolVector2Array*(self: Variant): PoolVector2Array = - newPoolVector2Array(self.godotVariant[].asGodotPoolVector2Array()) - -proc asPoolVector3Array*(self: Variant): PoolVector3Array = - newPoolVector3Array(self.godotVariant[].asGodotPoolVector3Array()) - -proc asPoolColorArray*(self: Variant): PoolColorArray = - newPoolColorArray(self.godotVariant[].asGodotPoolColorArray()) - -proc asDictionary*(self: Variant): Dictionary {.inline.} = - newDictionary(self.godotVariant[].asGodotDictionary) +proc asArray*(self: Variant): Array {.inline.} = + newArray(self.godotVariant.asGodotArray()) proc hasMethod*(self: Variant; meth: string): bool = var s = meth.toGodotString() - result = self.godotVariant[].hasMethod(s) + result = self.godotVariant.hasMethod(s) s.deinit() proc `==`*(self, other: Variant): bool = if self.isNil and other.isNil: return true if self.isNil != other.isNil: return false - result = self.godotVariant[] == other.godotVariant[] + result = self.godotVariant == other.godotVariant proc `<`*(self, other: Variant): bool = - result = self.godotVariant[] < other.godotVariant[] + result = self.godotVariant < other.godotVariant proc hashCompare*(self, other: Variant): bool = - self.godotVariant[].hashCompare(other.godotVariant[]) + self.godotVariant.hashCompare(other.godotVariant) -proc booleanize*(self: Variant; isValid: var bool): bool = - self.godotVariant[].booleanize(isValid) +proc booleanize*(self: Variant): bool = + self.godotVariant.booleanize() diff --git a/godot/core/vector2.nim b/godot/core/vector2.nim index 7e9cb04..390f1f6 100644 --- a/godot/core/vector2.nim +++ b/godot/core/vector2.nim @@ -1,111 +1,214 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import godotbase +import math, godotbase, hashes -import "../internal/godotstrings.nim" +import internal/godotinternaltypes, internal/godotstrings +import godotcoretypes, gdnativeapi -type - Vector2* {.byref.} = object - x*: float32 - y*: float32 +const EPSILON = 0.00001'f32 -proc vec2*(x, y: float32): Vector2 {.inline.} = +{.push stackTrace: off.} + +proc vec2*(): Vector2 {.inline, noinit.} = + Vector2() + +proc vec2*(x, y: float32): Vector2 {.inline, noinit.} = Vector2(x: x, y: y) -proc toGodotString(self: Vector2): GodotString {. - importc: "godot_vector2_as_string".} +proc `$`*(self: Vector2): string {.inline, noinit.} = + $getGDNativeAPI().vector2AsString(self) -proc `$`*(self: Vector2): string {.inline.} = - $self.toGodotString() +proc hash*(self: Vector2): Hash {.inline, noinit.} = + !$(self.x.hash() !& self.y.hash()) -proc normalized*(self: Vector2): Vector2 {. - importc: "godot_vector2_normalized".} -proc length*(self: Vector2): float32 {. - importc: "godot_vector2_length".} -proc angle*(self: Vector2): float32 {. - importc: "godot_vector2_angle".} -proc lengthSquared*(self: Vector2): float32 {. - importc: "godot_vector2_length_squared".} -proc isNormalized*(self: Vector2): bool {. - importc: "godot_vector2_is_normalized".} -proc distanceTo*(self, to: Vector2): float32 {. - importc: "godot_vector2_distance_to".} -proc distanceSquaredTo*(self, to: Vector2): float32 {. - importc: "godot_vector2_distance_squared_to".} -proc angleTo*(self, to: Vector2): float32 {. - importc: "godot_vector2_angle_to".} -proc angleToPoint*(self, to: Vector2): float32 {. - importc: "godot_vector2_angle_to_point".} -proc lerp*(self, b: Vector2; t: float32): Vector2 {. - importc: "godot_vector2_linear_interpolate".} -proc cubicInterpolate*(self, b, pre_a, post_b: Vector2; t: float32): Vector2 {. - importc: "godot_vector2_cubic_interpolate".} -proc rotated*(self: Vector2; phi: float32): Vector2 {. - importc: "godot_vector2_rotated".} -proc tangent*(self: Vector2): Vector2 {. - importc: "godot_vector2_tangent".} -proc floor*(self: Vector2): Vector2 {. - importc: "godot_vector2_floor".} -proc snapped*(self: Vector2; by: Vector2): Vector2 {. - importc: "godot_vector2_snapped".} -proc aspect*(self: Vector2): float32 {. - importc: "godot_vector2_aspect".} -proc dot*(a, b: Vector2): float32 {. - importc: "godot_vector2_dot".} -proc slide*(self, n: Vector2): Vector2 {. - importc: "godot_vector2_slide".} -proc bounce*(self, n: Vector2): Vector2 {. - importc: "godot_vector2_bounce".} -proc reflect*(self, n: Vector2): Vector2 {. - importc: "godot_vector2_reflect".} -proc abs*(self: Vector2): Vector2 {. - importc: "godot_vector2_abs".} -proc clamped*(self: Vector2; length: float32): Vector2 {. - importc: "godot_vector2_clamped".} +proc `+`*(self, other: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: self.x + other.x, y: self.y + other.y) -proc `+`*(a, b: Vector2): Vector2 {. - importc: "godot_vector2_operator_add".} -proc `+=`*(a: var Vector2, b: Vector2) {.inline.} = - a += b +proc `+=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = + self.x += other.x + self.y += other.y -proc `-`*(a, b: Vector2): Vector2 {. - importc: "godot_vector2_operator_substract".} -proc `-=`*(a: var Vector2, b: Vector2) {.inline.} = - a = a - b +proc `-`*(self, other: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: self.x - other.x, y: self.y - other.y) -proc `*`*(a, b: Vector2): Vector2 {. - importc: "godot_vector2_operator_multiply_vector".} +proc `-=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = + self.x -= other.x + self.y -= other.y -proc `*=`*(a: var Vector2, b: Vector2) {.inline.} = - a = a * b +proc `*`*(self, other: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: self.x * other.x, y: self.y * other.y) -proc `*`*(self: Vector2, scalar: float32): Vector2 {. - importc: "godot_vector2_operator_multiply_scalar".} -proc `*=`*(self: var Vector2, scalar: float32) {.inline.} = - self = self * scalar +proc `*=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = + self.x *= other.x + self.y *= other.y -proc `/`*(a, b: Vector2): Vector2 {. - importc: "godot_vector2_operator_divide_vector".} -proc `/=`*(a: var Vector2, b: Vector2) {.inline.} = - a = a / b +proc `*`*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} = + Vector2(x: self.x * scalar, y: self.y * scalar) -proc `/`*(self: Vector2; scalar: float32): Vector2 {. - importc: "godot_vector2_operator_divide_scalar".} -proc `/=`*(self: var Vector2; scalar: float32) {.inline.} = +proc `*`*(scalar: float32, v: Vector2): Vector2 {.inline, noinit.} = + v * scalar + +proc `*=`*(self: var Vector2, scalar: float32) {.inline, noinit.} = + self.x *= scalar + self.y *= scalar + +proc `/`*(self, other: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: self.x / other.x, y: self.y / other.y) + +proc `/=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = + self.x /= other.x + self.y /= other.y + +proc `/`*(self: Vector2; scalar: float32): Vector2 {.inline, noinit.} = + Vector2(x: self.x / scalar, y: self.y / scalar) + +proc `/=`*(self: var Vector2; scalar: float32) {.inline, noinit.} = self = self / scalar -proc `==`*(a, b: Vector2): bool {. - importc: "godot_vector2_operator_equal".} -proc `<`*(a, b: Vector2): bool {. - importc: "godot_vector2_operator_less".} -proc `-`*(self: Vector2): Vector2 {. - importc: "godot_vector2_operator_neg".} +proc `==`*(self, other: Vector2): bool {.inline, noinit.} = + self.x == other.x and self.y == other.y -proc `x=`*(self: var Vector2; x: float32) {. - importc: "godot_vector2_set_x".} -proc `y=`*(self: var Vector2; y: float32) {. - importc: "godot_vector2_set_y".} -proc x*(self: Vector2): float32 {. - importc: "godot_vector2_get_x".} -proc y*(self: Vector2): float32 {. - importc: "godot_vector2_get_y".} +proc `<`*(self, other: Vector2): bool {.inline, noinit.} = + if self.x == other.x: + self.y < other.y + else: + self.x < other.x + +proc `>`*(self, other: Vector2): bool {.inline, noinit.} = + if self.x == other.x: + self.y > other.y + else: + self.x > other.x + +proc `-`*(self: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: -self.x, y: -self.y) + +proc length*(self: Vector2): float32 {.inline, noinit.} = + sqrt(self.x * self.x + self.y * self.y) + +proc lengthSquared*(self: Vector2): float32 {.inline, noinit.} = + self.x * self.x + self.y * self.y + +proc normalize*(self: var Vector2) {.inline.} = + var len = self.x * self.x + self.y * self.y + if len != 0: + len = sqrt(len) + self.x /= len + self.y /= len + +proc normalized*(self: Vector2): Vector2 {.inline, noinit.} = + result = self + result.normalize() + +proc angle*(self: Vector2): float32 {.inline, noinit.} = + arctan2(self.y, self.x) + +proc isNormalized*(self: Vector2): bool {.inline, noinit.} = + isEqualApprox(self.lengthSquared(), 1.0) + +proc distanceTo*(self, to: Vector2): float32 {.inline, noinit.} = + sqrt((self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y)) + +proc distanceSquaredTo*(self, to: Vector2): float32 {.inline, noinit.} = + (self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y) + +proc dot*(a, b: Vector2): float32 {.inline, noinit.} = + a.x * b.x + a.y * b.y + +proc cross*(a, b: Vector2): float32 {.inline, noinit.} = + a.x * b.y - a.y * b.x + +proc cross*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} = + Vector2(x: scalar * self.y, y: -scalar * self.x) + +proc angleTo*(self, to: Vector2): float32 {.noinit.} = + arctan2(cross(self, to), dot(self, to)) + +proc angleToPoint*(self, to: Vector2): float32 {.inline, noinit.} = + arctan2(self.y - to.y, self.x - to.x) + +proc floor*(self: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: floor(self.x), y: floor(self.y)) + +proc planeProject*(self: Vector2, d: float32, + vec: Vector2): Vector2 {.noinit.} = + vec - self * (self.dot(vec) - d) + +proc project*(self, other: Vector2): Vector2 {.noinit.} = + self * (other.dot(self) / self.dot(self)) + +proc lerp*(self, b: Vector2; t: float32): Vector2 {.inline, noinit.} = + result = self + result.x += t * (b.x - self.x) + result.y += t * (b.y - self.y) + +proc cubicInterpolate*(self, b, preA, postB: Vector2; + t: float32): Vector2 {.noinit.} = + let p0 = preA + let p1 = self + let p2 = b + let p3 = postB + + let t2 = t * t + let t3 = t2 * t + + result = 0.5'f32 * ((p1 * 2.0'f32)) + + (-p0 + p2) * t + + (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3 + +proc setRotation*(self: var Vector2, radians: float32) {.inline, noinit.} = + self.x = cos(radians) + self.y = sin(radians) + +proc rotated*(self: Vector2; phi: float32): Vector2 {.inline, noinit.} = + result.setRotation(phi) + result *= self.length() + +proc tangent*(self: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: self.y, y: -self.x) + +proc snapped*(self: Vector2; by: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: stepify(self.x, by.x), y: stepify(self.y, by.y)) + +proc aspect*(self: Vector2): float32 {.inline, noinit.} = + self.x / self.y + +proc slide*(self, n: Vector2): Vector2 {.noinit.} = + when not defined(release): + if not n.isNormalized(): + printError("Normal not normalized in slide. " & getStackTrace()) + return vec2() + result = self - n * self.dot(n) + +proc reflect*(self, n: Vector2): Vector2 {.noinit.} = + when not defined(release): + if not n.isNormalized(): + printError("Normal not normalized in bounce. " & getStackTrace()) + return vec2() + result = 2.0 * n * self.dot(n) - self + +proc bounce*(self, n: Vector2): Vector2 {.inline, noinit.} = + -self.reflect(n) + +proc abs*(self: Vector2): Vector2 {.inline, noinit.} = + Vector2(x: abs(self.x), y: abs(self.y)) + +proc clamped*(self: Vector2; length: float32): Vector2 {.noinit.} = + let len = self.length() + result = self + if len > 0 and length < len: + result /= len + result *= length + +proc moveToward*(vFrom, to: Vector2, delta: float32): Vector2 = + let + vd = to - vFrom + vLen = vd.length + + if vLen <= delta or vLen < EPSILON: + result = to + else: + result = vFrom + (vd / vLen) * delta + +{.pop.} # stackTrace: off diff --git a/godot/core/vector3.nim b/godot/core/vector3.nim index c4c614b..ed2903a 100644 --- a/godot/core/vector3.nim +++ b/godot/core/vector3.nim @@ -1,13 +1,11 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -import math -import godotbase +import math, hashes +import godotbase, godotcoretypes -type - Vector3* {.byref.} = object - x*: float32 - y*: float32 - z*: float32 +const EPSILON = 0.00001'f32 + +{.push stackTrace: off.} proc vec3*(): Vector3 {.inline.} = Vector3() @@ -25,6 +23,9 @@ proc `$`*(self: Vector3): string {.inline.} = result.add($self.z) result.add(')') +proc hash*(self: Vector3): Hash {.inline, noinit.} = + !$(self.x.hash() !& self.y.hash() !& self.z.hash()) + proc `+`*(a, b: Vector3): Vector3 {.inline.} = result.x = a.x + b.x result.y = a.y + b.y @@ -239,3 +240,15 @@ proc cubicInterpolate*(self, b, preA, postB: Vector3; (-p0 + p2) * t + (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3) + +proc moveToward*(vFrom, to: Vector3, delta: float32): Vector3 = + let + vd = to - vFrom + vLen = vd.length + + if vLen <= delta or vLen < EPSILON: + result = to + else: + result = vFrom + (vd / vLen) * delta + +{.pop.} # stackTrace: off \ No newline at end of file diff --git a/godot/gdnativeapi.nim b/godot/gdnativeapi.nim new file mode 100644 index 0000000..bb05425 --- /dev/null +++ b/godot/gdnativeapi.nim @@ -0,0 +1,3617 @@ +# Copyright 2018 Xored Software, Inc. + +import internal/godotinternaltypes, core/godotcoretypes, macros + +type + ColorData* {.byref.} = object + data: array[16, uint8] + + Vector3Data* {.byref.} = object + data: array[12, uint8] + + Vector2Data* {.byref.} = object + data: array[8, uint8] + + PlaneData* {.byref.} = object + data: array[16, uint8] + + BasisData* {.byref.} = object + data: array[36, uint8] + + QuatData* {.byref.} = object + data: array[16, uint8] + + AABBData* {.byref.} = object + data: array[24, uint8] + + Rect2Data* {.byref.} = object + data: array[16, uint8] + + Transform2DData* {.byref.} = object + data: array[24, uint8] + + TransformData* {.byref.} = object + data: array[48, uint8] + + GDNativeAPIType {.size: sizeof(cuint).} = enum + GDNativeCore, + GDNativeExtNativeScript, + GDNativeExtPluginScript, + GDNativeExtNativeARVR + + GDNativeAPIHeader = object + typ: cuint + version: GDNativeAPIVersion + next: pointer + + GDNativeNativeScriptAPI1 = object + typ: cuint + version: GDNativeAPIVersion + next: pointer + nativeScriptRegisterClass: proc (gdnativeHandle: pointer, + name, base: cstring, + createFunc: GodotInstanceCreateFunc, + destroyFunc: GodotInstanceDestroyFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterToolClass: proc (gdnativeHandle: pointer, + name, base: cstring, + createFunc: GodotInstanceCreateFunc, + destroyFunc: GodotInstanceDestroyFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterMethod: proc (gdnativeHandle: pointer, + name, functionName: cstring, + attr: GodotMethodAttributes, + meth: GodotInstanceMethod) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterProperty: proc (gdnativeHandle: pointer, + name, path: cstring, + attr: ptr GodotPropertyAttributes, + setFunc: GodotPropertySetFunc, + getFunc: GodotPropertyGetFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterSignal: proc (gdnativeHandle: pointer, name: cstring, + signal: GodotSignal) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptGetUserdata: proc (obj: ptr GodotObject): pointer + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + GDNativeCoreAPI1 = object + typ: cuint + version: GDNativeAPIVersion + next: pointer + numExtensions: cuint + extensions: ptr array[100_000, pointer] + + # Color API + colorNewRGBA: proc (dest: var Color, r, g, b, a: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorNewRGB: proc (dest: var Color, r, g, b: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetR: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetR: proc (self: var Color, r: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetG: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetG: proc (self: var Color, g: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetB: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetB: proc (self: var Color, b: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetA: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetA: proc (self: var Color, a: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetH: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetS: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetV: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorAsString: proc (self: Color): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorToRGBA32: proc (self: Color): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorAsARGB32: proc (self: Color): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGray: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorInverted: proc (self: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorContrasted: proc (self: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorLinearInterpolate: proc (self, other: Color, t: float32): ColorData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + colorBlend: proc (self, other: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorToHtml: proc (self: Color, withAlpha: bool): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorOperatorEqual: proc (self, other: Color): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorOperatorLess: proc (self, other: Color): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Vector2 API + vector2New: proc (dest: var Vector2, x, y: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2AsString: proc (self: Vector2): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Normalized: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Length: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Angle: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2LengthSquared: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2IsNormalized: proc (self: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2DistanceTo: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2DistanceSquaredTo: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2AngleTo: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2AngleToPoint: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2LinearInterpolate: proc (self, b: Vector2, t: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2CubicInterpolate: proc (self, b, preA, postB: Vector2, + t: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2Rotated: proc (self: Vector2, phi: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Tangent: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Floor: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Snapped: proc (self, by: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Aspect: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Dot: proc (self, other: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Slide: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Bounce: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Reflect: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Abs: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Clamped: proc (self: Vector2, length: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorAdd: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorSubtract: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorMultiplyVector: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorMultiplyScalar: proc (self: Vector2, scalar: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorDivideVector: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorDivideScalar: proc (self: Vector2, scalar: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorEqual: proc (self, other: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorLess: proc (self, other: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorNeg: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2SetX: pointer + vector2SetY: pointer + vector2GetX: pointer + vector2GetY: pointer + + # Quat API + quatNew: proc (dest: var Quat, x, y, z, w: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatNewWithAxisAngle: proc (dest: Quat, axis: Vector3, + angle: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetX: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetX: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetY: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetY: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetZ: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetZ: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetW: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetW: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatAsString: proc (self: Quat): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatLength: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatLengthSquared: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatNormalized: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatIsNormalized: proc (self: Quat): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatInverse: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatDot: proc (self, other: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatXform: proc (self: Quat, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSlerp: proc (self, other: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSlerpni: proc (self, other: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatCubicSlerp: proc (self, other, preA, postB: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorMultiply: proc (self: Quat, b: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorAdd: proc (self, other: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorSubtract: proc (self, other: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorDivide: proc (self: Quat, divider: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorEqual: proc (self, other: Quat): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorNeg: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Basis API + basisNewWithRows: pointer + basisNewWithAxisAndAngle: pointer + basisNewWithEuler: pointer + basisAsString: pointer + basisInverse: pointer + basisTransposed: pointer + basisOrthonormalized: pointer + basisDeterminant: pointer + basisRotated: pointer + basisScaled: pointer + basisGetScale: pointer + basisGetEuler: pointer + basisTdotx: pointer + basisTdoty: pointer + basisTdotz: pointer + basisXform: pointer + basisXformInv: pointer + basisGetOrthogonalIndex: pointer + basisNew: pointer + basisNewWithEulerQuat: pointer + basisGetElements: pointer + basisGetAxis: pointer + basisSetAxis: pointer + basisGetRow: pointer + basisSetRow: pointer + basisOperatorEqual: pointer + basisOperatorAdd: pointer + basisOperatorSubstract: pointer + basisOperatorMultiplyVector: pointer + basisOperatorMultiplyScalar: pointer + + # Vector3 API + vector3New: pointer + vector3AsString: pointer + vector3MinAxis: pointer + vector3MaxAxis: pointer + vector3Length: pointer + vector3Length_squared: pointer + vector3IsNormalized: pointer + vector3Normalized: pointer + vector3Inverse: pointer + vector3Snapped: pointer + vector3Rotated: pointer + vector3LinearInterpolate: pointer + vector3CubicInterpolate: pointer + vector3Dot: pointer + vector3Cross: pointer + vector3Outer: pointer + vector3ToDiagonalMatrix: pointer + vector3Abs: pointer + vector3Floor: pointer + vector3Ceil: pointer + vector3DistanceTo: pointer + vector3DistanceSquaredTo: pointer + vector3AngleTo: pointer + vector3Slide: pointer + vector3Bounce: pointer + vector3Reflect: pointer + vector3OperatorAdd: pointer + vector3OperatorSubstract: pointer + vector3OperatorMultiplyVector: pointer + vector3OperatorMultiplyScalar: pointer + vector3OperatorDivideVector: pointer + vector3OperatorDivideScalar: pointer + vector3OperatorEqual: pointer + vector3OperatorLess: pointer + vector3OperatorNeg: pointer + vector3SetAxis: pointer + vector3GetAxis: pointer + + # PoolByteArray API + poolByteArrayNew: proc (dest: var GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayNewCopy: proc (dest: var GodotPoolByteArray, + src: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayNewWithArray: proc (dest: var GodotPoolByteArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayAppend: proc (self: var GodotPoolByteArray, + val: byte) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayAppendArray: proc (self: var GodotPoolByteArray, + arr: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayInsert: proc (self: var GodotPoolByteArray, + idx: cint, val: byte): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayInvert: proc (self: var GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayPushBack: proc (self: var GodotPoolByteArray, val: byte) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayRemove: proc (self: var GodotPoolByteArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayResize: proc (self: var GodotPoolByteArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayRead: proc (self: GodotPoolByteArray): ptr GodotPoolByteArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWrite: proc (self: var GodotPoolByteArray): ptr GodotPoolByteArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArraySet: proc (self: var GodotPoolByteArray, idx: cint, data: byte) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayGet: proc (self: GodotPoolByteArray, idx: cint): byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArraySize: proc (self: GodotPoolByteArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayDestroy: proc (self: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolIntArray API + poolIntArrayNew: proc (dest: var GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayNewCopy: proc (dest: var GodotPoolIntArray, + src: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayNewWithArray: proc (dest: var GodotPoolIntArray, src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolIntArrayAppend: proc (self: var GodotPoolIntArray, val: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayAppendArray: proc (self: var GodotPoolIntArray, + arr: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolIntArrayInsert: proc (self: var GodotPoolIntArray, idx: cint, + val: cint): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayInvert: proc (self: var GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayPushBack: proc (self: var GodotPoolIntArray, val: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayRemove: proc (self: var GodotPoolIntArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayResize: proc (self: var GodotPoolIntArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayRead: proc (self: GodotPoolIntArray): ptr GodotPoolIntArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWrite: proc (self: var GodotPoolIntArray): ptr GodotPoolIntArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArraySet: proc (self: var GodotPoolIntArray, idx: cint, data: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayGet: proc (self: GodotPoolIntArray, idx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArraySize: proc (self: GodotPoolIntArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayDestroy: proc (self: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolRealArray API + poolRealArrayNew: proc (dest: var GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayNewCopy: proc (dest: var GodotPoolRealArray, + src: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayNewWithArray: proc (dest: var GodotPoolRealArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayAppend: proc (self: var GodotPoolRealArray, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayAppendArray: proc (self: var GodotPoolRealArray, + arr: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayInsert: proc (self: var GodotPoolRealArray, + idx: cint, val: float32): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayInvert: proc (self: var GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayPushBack: proc (self: var GodotPoolRealArray, val: float32) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayRemove: proc (self: var GodotPoolRealArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayResize: proc (self: var GodotPoolRealArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayRead: proc (self: GodotPoolRealArray): ptr GodotPoolRealArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWrite: proc (self: var GodotPoolRealArray): ptr GodotPoolRealArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArraySet: proc (self: var GodotPoolRealArray, idx: cint, + data: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayGet: proc (self: GodotPoolRealArray, idx: cint): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArraySize: proc (self: GodotPoolRealArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayDestroy: proc (self: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolStringArray API + poolStringArrayNew: proc (dest: var GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayNewCopy: proc (dest: var GodotPoolStringArray, + src: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayNewWithArray: proc (dest: var GodotPoolStringArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayAppend: proc (self: var GodotPoolStringArray, + val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayAppendArray: proc (self: var GodotPoolStringArray, + arr: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayInsert: proc (self: var GodotPoolStringArray, + idx: cint, val: GodotString): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayInvert: proc (self: var GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayPushBack: proc (self: var GodotPoolStringArray, + val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayRemove: proc (self: var GodotPoolStringArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayResize: proc (self: var GodotPoolStringArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayRead: proc (self: GodotPoolStringArray): ptr GodotPoolStringArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWrite: proc (self: var GodotPoolStringArray): ptr GodotPoolStringArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArraySet: proc (self: var GodotPoolStringArray, idx: cint, + data: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayGet: proc (self: GodotPoolStringArray, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArraySize: proc (self: GodotPoolStringArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayDestroy: proc (self: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolVector2 API + poolVector2ArrayNew: proc (dest: var GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayNewCopy: proc (dest: var GodotPoolVector2Array, + src: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayNewWithArray: proc (dest: var GodotPoolVector2Array, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayAppend: proc (self: var GodotPoolVector2Array, val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayAppendArray: proc (self: var GodotPoolVector2Array, + arr: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayInsert: proc (self: var GodotPoolVector2Array, idx: cint, + val: Vector2): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayInvert: proc (self: var GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayPushBack: proc (self: var GodotPoolVector2Array, + val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayRemove: proc (self: var GodotPoolVector2Array, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayResize: proc (self: var GodotPoolVector2Array, size: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayRead: proc (self: GodotPoolVector2Array): ptr GodotPoolVector2ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWrite: proc (self: var GodotPoolVector2Array): ptr GodotPoolVector2ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArraySet: proc (self: var GodotPoolVector2Array, idx: cint, + data: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayGet: proc (self: GodotPoolVector2Array, idx: cint): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArraySize: proc (self: GodotPoolVector2Array): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayDestroy: proc (self: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolVector3 API + poolVector3ArrayNew: proc (dest: var GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayNewCopy: proc (dest: var GodotPoolVector3Array, + src: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayNewWithArray: proc (dest: var GodotPoolVector3Array, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayAppend: proc (self: var GodotPoolVector3Array, val: Vector3) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayAppendArray: proc (self: var GodotPoolVector3Array, + arr: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayInsert: proc (self: var GodotPoolVector3Array, idx: cint, + val: Vector3): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayInvert: proc (self: var GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayPushBack: proc (self: var GodotPoolVector3Array, + val: Vector3) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayRemove: proc (self: var GodotPoolVector3Array, + idx: cint) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayResize: proc (self: var GodotPoolVector3Array, + size: cint) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayRead: proc (self: GodotPoolVector3Array): ptr GodotPoolVector3ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWrite: proc (self: var GodotPoolVector3Array): ptr GodotPoolVector3ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArraySet: proc (self: var GodotPoolVector3Array, idx: cint, + data: Vector3) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayGet: proc (self: GodotPoolVector3Array, idx: cint): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArraySize: proc (self: GodotPoolVector3Array): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayDestroy: proc (self: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolColorArray API + poolColorArrayNew: proc (dest: var GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayNewCopy: proc (dest: var GodotPoolColorArray, + src: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayNewWithArray: proc (dest: var GodotPoolColorArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayAppend: proc (self: var GodotPoolColorArray, + val: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayAppendArray: proc (self: var GodotPoolColorArray, + arr: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayInsert: proc (self: var GodotPoolColorArray, + idx: cint, val: Color): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayInvert: proc (self: var GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayPushBack: proc (self: var GodotPoolColorArray, val: Color) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayRemove: proc (self: var GodotPoolColorArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayResize: proc (self: var GodotPoolColorArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayRead: proc (self: GodotPoolColorArray): ptr GodotPoolColorArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWrite: proc (self: var GodotPoolColorArray): ptr GodotPoolColorArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArraySet: proc (self: var GodotPoolColorArray, idx: cint, + data: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayGet: proc (self: GodotPoolColorArray, idx: cint): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArraySize: proc (self: GodotPoolColorArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayDestroy: proc (self: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Pool Array Read/Write Access API + + poolByteArrayReadAccessCopy: proc (self: ptr GodotPoolByteArrayReadAccess): ptr GodotPoolByteArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessPtr: proc (self: ptr GodotPoolByteArrayReadAccess): ptr byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolByteArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessDestroy: proc (self: ptr GodotPoolByteArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolIntArrayReadAccessCopy: proc (self: ptr GodotPoolIntArrayReadAccess): ptr GodotPoolIntArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessPtr: proc (self: ptr GodotPoolIntArrayReadAccess): ptr cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolIntArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessDestroy: proc (self: ptr GodotPoolIntArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolRealArrayReadAccessCopy: proc (self: ptr GodotPoolRealArrayReadAccess): ptr GodotPoolRealArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessPtr: proc (self: ptr GodotPoolRealArrayReadAccess): ptr float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolRealArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessDestroy: proc (self: ptr GodotPoolRealArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolStringArrayReadAccessCopy: proc (self: ptr GodotPoolStringArrayReadAccess): ptr GodotPoolStringArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessPtr: proc (self: ptr GodotPoolStringArrayReadAccess): ptr GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolStringArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessDestroy: proc (self: ptr GodotPoolStringArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector2ArrayReadAccessCopy: proc (self: ptr GodotPoolVector2ArrayReadAccess): ptr GodotPoolVector2ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessPtr: proc (self: ptr GodotPoolVector2ArrayReadAccess): ptr Vector2 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolVector2ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessDestroy: proc (self: ptr GodotPoolVector2ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector3ArrayReadAccessCopy: proc (self: ptr GodotPoolVector3ArrayReadAccess): ptr GodotPoolVector3ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessPtr: proc (self: ptr GodotPoolVector3ArrayReadAccess): ptr Vector3 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolVector3ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessDestroy: proc (self: ptr GodotPoolVector3ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolColorArrayReadAccessCopy: proc (self: ptr GodotPoolColorArrayReadAccess): ptr GodotPoolColorArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessPtr: proc (self: ptr GodotPoolColorArrayReadAccess): ptr Color + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessOperatorAssign: proc (self, other: ptr GodotPoolColorArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessDestroy: proc (self: ptr GodotPoolColorArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolByteArrayWriteAccessCopy: proc (self: ptr GodotPoolByteArrayWriteAccess): ptr GodotPoolByteArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessPtr: proc (self: ptr GodotPoolByteArrayWriteAccess): ptr byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolByteArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessDestroy: proc (self: ptr GodotPoolByteArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolIntArrayWriteAccessCopy: proc (self: ptr GodotPoolIntArrayWriteAccess): ptr GodotPoolIntArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessPtr: proc (self: ptr GodotPoolIntArrayWriteAccess): ptr cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolIntArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessDestroy: proc (self: ptr GodotPoolIntArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolRealArrayWriteAccessCopy: proc (self: ptr GodotPoolRealArrayWriteAccess): ptr GodotPoolRealArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessPtr: proc (self: ptr GodotPoolRealArrayWriteAccess): ptr float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolRealArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessDestroy: proc (self: ptr GodotPoolRealArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolStringArrayWriteAccessCopy: proc (self: ptr GodotPoolStringArrayWriteAccess): ptr GodotPoolStringArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessPtr: proc (self: ptr GodotPoolStringArrayWriteAccess): ptr GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolStringArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessDestroy: proc (self: ptr GodotPoolStringArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector2ArrayWriteAccessCopy: proc (self: ptr GodotPoolVector2ArrayWriteAccess): ptr GodotPoolVector2ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessPtr: proc (self: ptr GodotPoolVector2ArrayWriteAccess): ptr Vector2 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolVector2ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessDestroy: proc (self: ptr GodotPoolVector2ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector3ArrayWriteAccessCopy: proc (self: ptr GodotPoolVector3ArrayWriteAccess): ptr GodotPoolVector3ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessPtr: proc (self: ptr GodotPoolVector3ArrayWriteAccess): ptr Vector3 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolVector3ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessDestroy: proc (self: ptr GodotPoolVector3ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolColorArrayWriteAccessCopy: proc (self: ptr GodotPoolColorArrayWriteAccess): ptr GodotPoolColorArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessPtr: proc (self: ptr GodotPoolColorArrayWriteAccess): ptr Color + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessOperatorAssign: proc (self, other: ptr GodotPoolColorArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessDestroy: proc (self: ptr GodotPoolColorArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Array API + arrayNew: proc (dest: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewCopy: proc (dest: var GodotArray, src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewPoolColorArray: proc (dest: var GodotArray, src: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolVector3Array: proc (dest: var GodotArray, + src: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolVector2Array: proc (dest: var GodotArray, + src: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolStringArray: proc (dest: var GodotArray, + src: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolRealArray: proc (dest: var GodotArray, src: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolIntArray: proc (dest: var GodotArray, src: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewPoolByteArray: proc (dest: var GodotArray, src: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arraySet: proc (self: var GodotArray, idx: cint, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayGet: proc (self: GodotArray, idx: cint): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayOperatorIndex: proc (self: var GodotArray, idx: cint): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayOperatorIndexConst: pointer + arrayAppend: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayClear: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayCount: proc (self: GodotArray, val: GodotVariant): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayEmpty: proc (self: GodotArray): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayErase: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFront: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBack: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFind: proc (self: GodotArray, what: GodotVariant, fromIdx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFindLast: proc (self: GodotArray, what: GodotVariant): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayHas: proc (self: GodotArray, val: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayHash: proc (self: GodotArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayInsert: proc (self: var GodotArray, pos: cint, val: GodotVariant): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayInvert: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPopBack: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPopFront: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPushBack: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPushFront: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayRemove: proc (self: var GodotArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayResize: proc (self: var GodotArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayRFind: proc (self: GodotArray, what: GodotVariant, fromIdx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySize: proc (self: GodotArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySort: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySortCustom: proc (self: var GodotArray, obj: ptr GodotObject, + f: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBSearch: proc (self: var GodotArray, val: ptr GodotVariant, + before: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBSearchCustom: proc (self: var GodotArray, val: ptr GodotVariant, + obj: ptr GodotObject, f: GodotString, + before: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayDestroy: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Dictionary API + dictionaryNew: proc (dest: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryNewCopy: proc (dest: var GodotDictionary, src: GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryDestroy: proc (self: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionarySize: proc (self: GodotDictionary): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryEmpty: proc (self: GodotDictionary): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryClear: proc (self: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHas: proc (self: GodotDictionary, key: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHasAll: proc (self: GodotDictionary, keys: GodotArray): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryErase: proc (self: var GodotDictionary, key: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHash: proc (self: GodotDictionary): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryKeys: proc (self: GodotDictionary): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryValues: proc (self: GodotDictionary): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryGet: proc (self: GodotDictionary, key: GodotVariant): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionarySet: proc (self: var GodotDictionary, key, value: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryOperatorIndex: proc (self: var GodotDictionary, + key: GodotVariant): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + dictionaryOperatorIndexConst: pointer + dictionaryNext: proc (self: GodotDictionary, + key: GodotVariant): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryOperatorEqual: proc (self, other: GodotDictionary): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + dictionaryToJson: proc (self: GodotDictionary): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # NodePath API + nodePathNew: proc (dest: var GodotNodePath, src: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathNewCopy: proc (dest: var GodotNodePath, src: GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathDestroy: proc (self: var GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathAsString: proc (self: GodotNodePath): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathIsAbsolute: proc (self: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetNameCount: proc (self: GodotNodePath): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetName: proc (self: GodotNodePath, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetSubnameCount: proc (self: GodotNodePath): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nodePathGetSubname: proc (self: GodotNodePath, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetConcatenatedSubnames: proc (self: GodotNodePath): GodotString + {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + nodePathIsEmpty: proc (self: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathOperatorEqual: proc (self, other: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Plane API + planeNewWithReals: proc (dest: var Plane, a, b, c, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNewWithVectors: proc (dest: var Plane, v1, v2, v3: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNewWithNormal: proc (dest: var Plane, normal: Vector3, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeAsString: proc (self: Plane): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNormalized: proc (self: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeCenter: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetAnyPoint: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIsPointOver: proc (self: Plane, point: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeDistanceTo: proc (self: Plane, point: Vector3): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeHasPoint: proc (self: Plane, point: Vector3, epsilon: float32): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeProject: proc (self: Plane, point: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersect3: proc (self: Plane, dest: var Vector3, b, c: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersectsRay: proc (self: Plane, dest: var Vector3, + point, dir: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersectsSegment: proc (self: Plane, dest: var Vector3, + segmentBegin, segmentEnd: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + planeOperatorNeg: proc (self: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeOperatorEqual: proc (self, other: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeSetNormal: proc (self: var Plane, normal: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetNormal: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetD: proc (self: Plane): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeSetD: proc (self: var Plane, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Rect2 API + rect2NewWithPositionAndSize: proc (dest: var Rect2, pos, size: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + rect2New: proc (dest: var Rect2, x, y, width, height: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2AsString: proc (self: Rect2): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetArea: proc (self: Rect2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Intersects: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Encloses: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2HasNoArea: proc (self: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Clip: proc (self, other: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Merge: proc (self, other: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2HasPoint: proc (self: Rect2, point: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Grow: proc (self: Rect2, by: float32): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Expand: proc (self: Rect2, to: Vector2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2OperatorEqual: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetPosition: proc (self: Rect2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetSize: proc (self: Rect2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2SetPosition: proc (self: var Rect2, pos: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2SetSize: proc (self: var Rect2, size: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # AABB API + aabbNew: proc (dest: var AABB, pos, size: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetPosition: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbSetPosition: proc (self: var AABB, pos: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetSize: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbSetSize: proc (self: var AABB, pos: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbAsString: proc (self: AABB): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetArea: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbHasNoArea: proc (self: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbHasNoSurface: proc (self: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersects: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbEncloses: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbMerge: proc (self, other: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersection: proc (self, other: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersectsPlane: proc (self: AABB, plane: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersectsSegment: proc (self: AABB, vFrom, vTo: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbHasPoint: proc (self: AABB, point: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetSupport: proc (self: AABB, dir: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetLongestAxis: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetLongestAxisIndex: proc (self: AABB): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetLongestAxisSize: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetShortestAxis: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetShortestAxisIndex: proc (self: AABB): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetShortestAxisSize: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbExpand: proc (self: AABB, toPoint: Vector3): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGrow: proc (self: AABB, by: float32): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetEndpoint: proc (self: AABB, idx: cint): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbOperatorEqual: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # RID API + ridNew: proc (dest: var RID) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridGetID: proc (self: RID): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridNewWithResource: proc (dest: var RID, obj: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridOperatorEqual: proc (self, other: RID): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridOperatorLess: proc (self, other: RID): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Transform API + transformNewWithAxisOrigin: proc (dest: var Transform, + xAxis, yAxis, zAxis, origin: Vector3) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformNew: proc (dest: var Transform, basis: Basis, origin: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformGetBasis: proc (self: Transform): BasisData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformSetBasis: proc (self: var Transform, basis: Basis) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformGetOrigin: proc (self: Transform): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformSetOrigin: proc (self: var Transform, v: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformAsString: proc (self: Transform): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformInverse: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformAffineInverse: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformOrthonormalized: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformRotated: proc (self: Transform, axis: Vector3, + phi: float32): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformScaled: proc (self: Transform, scale: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformTranslated: proc (self: Transform, offset: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformLookingAt: proc (self: Transform, target, up: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformPlane: proc (self: Transform, plane: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformInvPlane: proc (self: Transform, plane: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformNewIdentity: proc (dest: var Transform) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformOperatorEqual: proc (self, other: Transform): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformOperatorMultiply: proc (self, other: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformVector3: proc (self: Transform, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformInvVector3: proc (self: Transform, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformAABB: proc (self: Transform, v: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformInvAABB: proc (self: Transform, v: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Transform2D API + transform2DNew: proc (dest: var Transform2D, rot: float32, pos: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DNewAxisOrigin: proc (dest: var Transform2D, + xAxis, yAxis, origin: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DAsString: proc (self: Transform2D): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DInverse: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DAffineInverse: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DGetRotation: proc (self: Transform2D): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DGetOrigin: proc (self: Transform2D): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DGetScale: proc (self: Transform2D): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DOrthonormalized: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DRotated: proc (self: Transform2D, phi: float32): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DScaled: proc (self: Transform2D, scale: Vector2): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DTranslated: proc (self: Transform2D, offset: Vector2): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformVector2: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformInvVector2: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DBasisXformVector2: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DBasisXformInvVector2: proc (self: Transform2D, + v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DInterpolateWith: proc (self, other: Transform2D, + t: float32): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DOperatorEqual: proc (self, other: Transform2D): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DOperatorMultiply: proc (self, other: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DNewIdentity: proc (dest: var Transform2D) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformRect2: proc (self: Transform2D, v: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformInvRect2: proc (self: Transform2D, v: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Variant API + variantGetType: proc (v: GodotVariant): VariantType + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewCopy: proc (dest: var GodotVariant, src: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewNil: proc (dest: var GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewBool: proc (dest: var GodotVariant, val: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewUInt: proc (dest: var GodotVariant, val: uint64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewInt: proc (dest: var GodotVariant, val: int64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewReal: proc (dest: var GodotVariant, val: float64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewString: proc (dest: var GodotVariant, val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewVector2: proc (dest: var GodotVariant, val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewRect2: proc (dest: var GodotVariant, val: Rect2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewVector3: proc (dest: var GodotVariant, val: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewTransform2D: proc (dest: var GodotVariant, val: Transform2D) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPlane: proc (dest: var GodotVariant, val: Plane) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewQuat: proc (dest: var GodotVariant, val: Quat) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewAABB: proc (dest: var GodotVariant, val: AABB) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewBasis: proc (dest: var GodotVariant, val: Basis) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewTransform: proc (dest: var GodotVariant, val: Transform) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewColor: proc (dest: var GodotVariant, val: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewNodePath: proc (dest: var GodotVariant, val: GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewRID: proc (dest: var GodotVariant, val: RID) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewObject: proc (dest: var GodotVariant, val: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewDictionary: proc (dest: var GodotVariant, val: GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewArray: proc (dest: var GodotVariant, val: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewPoolByteArray: proc (dest: var GodotVariant, + val: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolIntArray: proc (dest: var GodotVariant, val: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolRealArray: proc (dest: var GodotVariant, + val: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolStringArray: proc (dest: var GodotVariant, + val: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolVector2Array: proc (dest: var GodotVariant, + val: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolVector3Array: proc (dest: var GodotVariant, + val: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolColorArray: proc (dest: var GodotVariant, + val: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsBool: proc (self: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsUInt: proc (self: GodotVariant): uint64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsInt: proc (self: GodotVariant): int64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsReal: proc (self: GodotVariant): float64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsString: proc (self: GodotVariant): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsVector2: proc (self: GodotVariant): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsRect2: proc (self: GodotVariant): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsVector3: proc (self: GodotVariant): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsTransform2D: proc (self: GodotVariant): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsPlane: proc (self: GodotVariant): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsQuat: proc (self: GodotVariant): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsAABB: proc (self: GodotVariant): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsBasis: proc (self: GodotVariant): BasisData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsTransform: proc (self: GodotVariant): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsColor: proc (self: GodotVariant): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsNodePath: proc (self: GodotVariant): GodotNodePath + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsRID: proc (self: GodotVariant): RID + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsObject: proc (self: GodotVariant): ptr GodotObject + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsDictionary: proc (self: GodotVariant): GodotDictionary + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsArray: proc (self: GodotVariant): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsPoolByteArray: proc (self: GodotVariant): GodotPoolByteArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolIntArray: proc (self: GodotVariant): GodotPoolIntArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolRealArray: proc (self: GodotVariant): GodotPoolRealArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolStringArray: proc (self: GodotVariant): GodotPoolStringArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolVector2Array: proc (self: GodotVariant): GodotPoolVector2Array + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolVector3Array: proc (self: GodotVariant): GodotPoolVector3Array + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolColorArray: proc (self: GodotVariant): GodotPoolColorArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantCall: proc (self: var GodotVariant, meth: GodotString, + args: ptr array[MAX_ARG_COUNT, ptr GodotVariant], + argcount: cint, + callError: var VariantCallError): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantHasMethod: proc (self: GodotVariant, meth: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantOperatorEqual: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantOperatorLess: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantHashCompare: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantBooleanize: proc (self: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantDestroy: proc (self: var GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # String API + charStringLength: proc (self: GodotCharString): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + charStringGetData: proc (self: GodotCharString): cstring + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + charStringDestroy: proc (self: var GodotCharString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringNew: proc (dest: var GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringNewCopy: proc (dest: var GodotString, src: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringNewWithWideString: pointer + stringOperatorIndex: pointer + stringOperatorIndexConst: pointer + stringWideStr: proc (self: GodotString): ptr cwchar_t + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorEqual: proc (self, other: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorLess: proc (self, other: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorPlus: proc (self, other: GodotString): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringLength: proc (self: GodotString): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringCasecmpTo: pointer + stringNocasecmpTo: pointer + stringNaturalnocasecmpTo: pointer + stringBeginsWith: pointer + stringBeginsWithCharArray: pointer + stringBigrams: pointer + stringChr: pointer + stringEndsWith: pointer + stringFind: pointer + stringFindFrom: pointer + stringFindmk: pointer + stringFindmkFrom: pointer + stringFindmkFromInPlace: pointer + stringFindn: pointer + stringFindnFrom: pointer + stringFindLast: pointer + stringFormat: pointer + stringFormatWithCustomPlaceholder: pointer + stringHexEncodeBuffer: pointer + stringHexToInt: pointer + stringHexToIntWithoutPrefix: pointer + stringInsert: pointer + stringIsNumeric: pointer + stringIsSubsequenceOf: pointer + stringIsSubsequenceOfi: pointer + stringLpad: pointer + stringLpadWithCustomCharacter: pointer + stringMatch: pointer + stringMatchn: pointer + stringMd5: pointer + stringNum: pointer + stringNumInt64: pointer + stringNumInt64Capitalized: pointer + stringNumReal: pointer + stringNumScientific: pointer + stringNumWithDecimals: pointer + stringPadDecimals: pointer + stringPadZeros: pointer + stringReplaceFirst: pointer + stringReplace: pointer + stringReplacen: pointer + stringRfind: pointer + stringRfindn: pointer + stringRfindFrom: pointer + stringRfindnFrom: pointer + stringRpad: pointer + stringRpadWithCustomCharacter: pointer + stringSimilarity: pointer + stringSprintf: pointer + stringSubstr: pointer + stringToDouble: pointer + stringToFloat: pointer + stringToInt: pointer + stringCamelcaseToUnderscore: pointer + stringCamelcaseToUnderscoreLowercased: pointer + stringCapitalize: pointer + stringCharToDouble: pointer + stringCharToInt: pointer + stringWcharToInt: pointer + stringCharToIntWithLen: pointer + stringCharToInt64WithLen: pointer + stringHexToInt64: pointer + stringHexToInt64WithPrefix: pointer + stringToInt64: pointer + stringUnicodeCharToDouble: pointer + stringGetSliceCount: pointer + stringGetSlice: pointer + stringGetSlicec: pointer + stringSplit: pointer + stringSplitAllowEmpty: pointer + stringSplitFloats: pointer + stringSplitFloatsAllowsEmpty: pointer + stringSplitFloatsMk: pointer + stringSplitFloatsMkAllowsEmpty: pointer + stringSplitInts: pointer + stringSplitIntsAllowsEmpty: pointer + stringSplitIntsMk: pointer + stringSplitIntsMkAllowsEmpty: pointer + stringSplitSpaces: pointer + stringCharLowercase: pointer + stringCharUppercase: pointer + stringToLower: pointer + stringToUpper: pointer + stringGetBasename: pointer + stringGetExtension: pointer + stringLeft: pointer + stringOrdAt: pointer + stringPlusFile: pointer + stringRight: pointer + stringStripEdges: pointer + stringStripEscapes: pointer + stringErase: pointer + stringAscii: pointer + stringAsciiExtended: pointer + stringUtf8: proc (self: GodotString): GodotCharString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringParseUtf8: pointer + stringParseUtf8WithLen: pointer + stringCharsToUtf8: proc (str: cstring): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringCharsToUtf8WithLen: proc (str: cstring, len: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringHash: pointer + stringHash64: pointer + stringHashChars: pointer + stringHashCharsWithLen: pointer + stringHashUtf8Chars: pointer + stringHashUtf8CharsWithLen: pointer + stringMd5Buffer: pointer + stringMd5Text: pointer + stringSha256Buffer: pointer + stringSha256Text: pointer + stringEmpty: pointer + stringGetBaseDir: pointer + stringGetFile: pointer + stringHumanizeSize: pointer + stringIsAbsPath: pointer + stringIsRelPath: pointer + stringIsResourceFile: pointer + stringPathTo: pointer + stringPathToFile: pointer + stringSimplifyPath: pointer + stringCEscape: pointer + stringCEscapeMultiline: pointer + stringCUnescape: pointer + stringHttpEscape: pointer + stringHttpUnescape: pointer + stringJsonEscape: pointer + stringWordWrap: pointer + stringXmlEscape: pointer + stringXmlEscapeWithQuotes: pointer + stringXmlUnescape: pointer + stringPercentDecode: pointer + stringPercentEncode: pointer + stringIsValidFloat: pointer + stringIsValidHexNumber: pointer + stringIsValidHtmlColor: pointer + stringIsValidIdentifier: pointer + stringIsValidInteger: pointer + stringIsValidIpAddress: pointer + stringDestroy: proc (self: var GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # StringName API + stringNameNew: pointer + stringNameNewData: pointer + stringNameGetName: pointer + stringNameGetHash: pointer + stringNameGetDataUniquePointer: pointer + stringNameOperatorEqual: pointer + stringNameOperatorLess: pointer + stringNameDestroy: pointer + + # Misc API + objectDestroy: proc (self: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + globalGetSingleton: proc (name: cstring): ptr GodotObject + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindGetMethod: proc (className, + methodName: cstring): ptr GodotMethodBind + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindPtrCall: proc (methodBind: ptr GodotMethodBind, + obj: ptr GodotObject, + args: ptr array[MAX_ARG_COUNT, pointer], + ret: pointer) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindCall: proc (methodBind: ptr GodotMethodBind, obj: ptr GodotObject, + args: ptr array[MAX_ARG_COUNT, ptr GodotVariant], + argCount: cint, + callError: var VariantCallError): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + getClassConstructor: proc (className: cstring): GodotClassConstructor + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + getGlobalConstants: pointer + registerNativeCallType: proc (callType: cstring, + cb: proc (procHandle: pointer, + args: ptr GodotArray): GodotVariant + {.noconv.}) {.noconv.} + alloc: proc (bytes: cint): pointer + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + realloc: proc (p: pointer, bytes: cint): pointer + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + free: proc (p: pointer) {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + printError: proc (description, function, file: cstring, line: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + printWarning: proc (description, function, file: cstring, line: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + print: proc (message: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + GDNativeAPI* = object + # Color API + colorNewRGBA*: proc (dest: var Color, r, g, b, a: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorNewRGB*: proc (dest: var Color, r, g, b: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetR*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetR*: proc (self: var Color, r: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetG*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetG*: proc (self: var Color, g: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetB*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetB*: proc (self: var Color, b: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetA*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorSetA*: proc (self: var Color, a: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetH*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetS*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGetV*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorAsString*: proc (self: Color): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorToRGBA32*: proc (self: Color): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorAsARGB32*: proc (self: Color): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorGray*: proc (self: Color): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorInverted*: proc (self: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorContrasted*: proc (self: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorLinearInterpolate*: proc (self, other: Color, t: float32): ColorData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + colorBlend*: proc (self, other: Color): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorToHtml*: proc (self: Color, withAlpha: bool): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorOperatorEqual*: proc (self, other: Color): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + colorOperatorLess*: proc (self, other: Color): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Vector2 API + vector2New*: proc (dest: var Vector2, x, y: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2AsString*: proc (self: Vector2): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Normalized*: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Length*: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Angle*: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2LengthSquared*: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2IsNormalized*: proc (self: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2DistanceTo*: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2DistanceSquaredTo*: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2AngleTo*: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2AngleToPoint*: proc (self, to: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2LinearInterpolate*: proc (self, b: Vector2, t: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2CubicInterpolate*: proc (self, b, preA, postB: Vector2, + t: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2Rotated*: proc (self: Vector2, phi: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Tangent*: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Floor*: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Snapped*: proc (self, by: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Aspect*: proc (self: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Dot*: proc (self, other: Vector2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Slide*: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Bounce*: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Reflect*: proc (self, n: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Abs*: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2Clamped*: proc (self: Vector2, length: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorAdd*: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorSubtract*: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorMultiplyVector*: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorMultiplyScalar*: proc (self: Vector2, scalar: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorDivideVector*: proc (self, other: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorDivideScalar*: proc (self: Vector2, scalar: float32): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + vector2OperatorEqual*: proc (self, other: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorLess*: proc (self, other: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + vector2OperatorNeg*: proc (self: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Quat API + quatNew*: proc (dest: var Quat, x, y, z, w: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatNewWithAxisAngle*: proc (dest: Quat, axis: Vector3, + angle: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetX*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetX*: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetY*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetY*: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetZ*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetZ*: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatGetW*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSetW*: proc (self: var Quat, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatAsString*: proc (self: Quat): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatLength*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatLengthSquared*: proc (self: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatNormalized*: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatIsNormalized*: proc (self: Quat): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatInverse*: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatDot*: proc (self, other: Quat): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatXform*: proc (self: Quat, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSlerp*: proc (self, other: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatSlerpni*: proc (self, other: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatCubicSlerp*: proc (self, other, preA, postB: Quat, t: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorMultiply*: proc (self: Quat, b: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorAdd*: proc (self, other: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorSubtract*: proc (self, other: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorDivide*: proc (self: Quat, divider: float32): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorEqual*: proc (self, other: Quat): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + quatOperatorNeg*: proc (self: Quat): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolByteArray API + poolByteArrayNew*: proc (dest: var GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayNewCopy*: proc (dest: var GodotPoolByteArray, + src: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayNewWithArray*: proc (dest: var GodotPoolByteArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayAppend*: proc (self: var GodotPoolByteArray, + val: byte) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayAppendArray*: proc (self: var GodotPoolByteArray, + arr: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayInsert*: proc (self: var GodotPoolByteArray, + idx: cint, val: byte): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayInvert*: proc (self: var GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayPushBack*: proc (self: var GodotPoolByteArray, val: byte) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolByteArrayRemove*: proc (self: var GodotPoolByteArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayResize*: proc (self: var GodotPoolByteArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayRead*: proc (self: GodotPoolByteArray): ptr GodotPoolByteArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWrite*: proc (self: var GodotPoolByteArray): ptr GodotPoolByteArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArraySet*: proc (self: var GodotPoolByteArray, idx: cint, data: byte) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayGet*: proc (self: GodotPoolByteArray, idx: cint): byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArraySize*: proc (self: GodotPoolByteArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayDestroy*: proc (self: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolIntArray API + poolIntArrayNew*: proc (dest: var GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayNewCopy*: proc (dest: var GodotPoolIntArray, + src: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayNewWithArray*: proc (dest: var GodotPoolIntArray, src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolIntArrayAppend*: proc (self: var GodotPoolIntArray, val: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayAppendArray*: proc (self: var GodotPoolIntArray, + arr: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolIntArrayInsert*: proc (self: var GodotPoolIntArray, idx: cint, + val: cint): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayInvert*: proc (self: var GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayPushBack*: proc (self: var GodotPoolIntArray, val: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayRemove*: proc (self: var GodotPoolIntArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayResize*: proc (self: var GodotPoolIntArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayRead*: proc (self: GodotPoolIntArray): ptr GodotPoolIntArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWrite*: proc (self: var GodotPoolIntArray): ptr GodotPoolIntArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArraySet*: proc (self: var GodotPoolIntArray, idx: cint, data: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayGet*: proc (self: GodotPoolIntArray, idx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArraySize*: proc (self: GodotPoolIntArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayDestroy*: proc (self: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolRealArray API + poolRealArrayNew*: proc (dest: var GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayNewCopy*: proc (dest: var GodotPoolRealArray, + src: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayNewWithArray*: proc (dest: var GodotPoolRealArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayAppend*: proc (self: var GodotPoolRealArray, val: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayAppendArray*: proc (self: var GodotPoolRealArray, + arr: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayInsert*: proc (self: var GodotPoolRealArray, + idx: cint, val: float32): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayInvert*: proc (self: var GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayPushBack*: proc (self: var GodotPoolRealArray, val: float32) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolRealArrayRemove*: proc (self: var GodotPoolRealArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayResize*: proc (self: var GodotPoolRealArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayRead*: proc (self: GodotPoolRealArray): ptr GodotPoolRealArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWrite*: proc (self: var GodotPoolRealArray): ptr GodotPoolRealArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArraySet*: proc (self: var GodotPoolRealArray, idx: cint, + data: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayGet*: proc (self: GodotPoolRealArray, idx: cint): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArraySize*: proc (self: GodotPoolRealArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayDestroy*: proc (self: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # PoolStringArray API + poolStringArrayNew*: proc (dest: var GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayNewCopy*: proc (dest: var GodotPoolStringArray, + src: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayNewWithArray*: proc (dest: var GodotPoolStringArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayAppend*: proc (self: var GodotPoolStringArray, + val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayAppendArray*: proc (self: var GodotPoolStringArray, + arr: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayInsert*: proc (self: var GodotPoolStringArray, + idx: cint, val: GodotString): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayInvert*: proc (self: var GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayPushBack*: proc (self: var GodotPoolStringArray, + val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayRemove*: proc (self: var GodotPoolStringArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayResize*: proc (self: var GodotPoolStringArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolStringArrayRead*: proc (self: GodotPoolStringArray): ptr GodotPoolStringArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWrite*: proc (self: var GodotPoolStringArray): ptr GodotPoolStringArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArraySet*: proc (self: var GodotPoolStringArray, idx: cint, + data: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayGet*: proc (self: GodotPoolStringArray, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArraySize*: proc (self: GodotPoolStringArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayDestroy*: proc (self: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolVector2 API + poolVector2ArrayNew*: proc (dest: var GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayNewCopy*: proc (dest: var GodotPoolVector2Array, + src: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayNewWithArray*: proc (dest: var GodotPoolVector2Array, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayAppend*: proc (self: var GodotPoolVector2Array, val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayAppendArray*: proc (self: var GodotPoolVector2Array, + arr: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayInsert*: proc (self: var GodotPoolVector2Array, idx: cint, + val: Vector2): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayInvert*: proc (self: var GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayPushBack*: proc (self: var GodotPoolVector2Array, + val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayRemove*: proc (self: var GodotPoolVector2Array, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayResize*: proc (self: var GodotPoolVector2Array, size: cint) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector2ArrayRead*: proc (self: GodotPoolVector2Array): ptr GodotPoolVector2ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWrite*: proc (self: var GodotPoolVector2Array): ptr GodotPoolVector2ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArraySet*: proc (self: var GodotPoolVector2Array, idx: cint, + data: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayGet*: proc (self: GodotPoolVector2Array, idx: cint): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArraySize*: proc (self: GodotPoolVector2Array): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayDestroy*: proc (self: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolVector3 API + poolVector3ArrayNew*: proc (dest: var GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayNewCopy*: proc (dest: var GodotPoolVector3Array, + src: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayNewWithArray*: proc (dest: var GodotPoolVector3Array, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayAppend*: proc (self: var GodotPoolVector3Array, val: Vector3) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayAppendArray*: proc (self: var GodotPoolVector3Array, + arr: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayInsert*: proc (self: var GodotPoolVector3Array, idx: cint, + val: Vector3): Error + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayInvert*: proc (self: var GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolVector3ArrayPushBack*: proc (self: var GodotPoolVector3Array, + val: Vector3) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayRemove*: proc (self: var GodotPoolVector3Array, + idx: cint) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayResize*: proc (self: var GodotPoolVector3Array, + size: cint) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayRead*: proc (self: GodotPoolVector3Array): ptr GodotPoolVector3ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWrite*: proc (self: var GodotPoolVector3Array): ptr GodotPoolVector3ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArraySet*: proc (self: var GodotPoolVector3Array, idx: cint, + data: Vector3) {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + poolVector3ArrayGet*: proc (self: GodotPoolVector3Array, idx: cint): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArraySize*: proc (self: GodotPoolVector3Array): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayDestroy*: proc (self: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # PoolColorArray API + poolColorArrayNew*: proc (dest: var GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayNewCopy*: proc (dest: var GodotPoolColorArray, + src: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayNewWithArray*: proc (dest: var GodotPoolColorArray, + src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayAppend*: proc (self: var GodotPoolColorArray, + val: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayAppendArray*: proc (self: var GodotPoolColorArray, + arr: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayInsert*: proc (self: var GodotPoolColorArray, + idx: cint, val: Color): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayInvert*: proc (self: var GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayPushBack*: proc (self: var GodotPoolColorArray, val: Color) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + poolColorArrayRemove*: proc (self: var GodotPoolColorArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayResize*: proc (self: var GodotPoolColorArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayRead*: proc (self: GodotPoolColorArray): ptr GodotPoolColorArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWrite*: proc (self: var GodotPoolColorArray): ptr GodotPoolColorArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArraySet*: proc (self: var GodotPoolColorArray, idx: cint, + data: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayGet*: proc (self: GodotPoolColorArray, idx: cint): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArraySize*: proc (self: GodotPoolColorArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayDestroy*: proc (self: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Pool Array Read/Write Access API + + poolByteArrayReadAccessCopy*: proc (self: ptr GodotPoolByteArrayReadAccess): ptr GodotPoolByteArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessPtr*: proc (self: ptr GodotPoolByteArrayReadAccess): ptr byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolByteArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayReadAccessDestroy*: proc (self: ptr GodotPoolByteArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolIntArrayReadAccessCopy*: proc (self: ptr GodotPoolIntArrayReadAccess): ptr GodotPoolIntArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessPtr*: proc (self: ptr GodotPoolIntArrayReadAccess): ptr cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolIntArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayReadAccessDestroy*: proc (self: ptr GodotPoolIntArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolRealArrayReadAccessCopy*: proc (self: ptr GodotPoolRealArrayReadAccess): ptr GodotPoolRealArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessPtr*: proc (self: ptr GodotPoolRealArrayReadAccess): ptr float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolRealArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayReadAccessDestroy*: proc (self: ptr GodotPoolRealArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolStringArrayReadAccessCopy*: proc (self: ptr GodotPoolStringArrayReadAccess): ptr GodotPoolStringArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessPtr*: proc (self: ptr GodotPoolStringArrayReadAccess): ptr GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolStringArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayReadAccessDestroy*: proc (self: ptr GodotPoolStringArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector2ArrayReadAccessCopy*: proc (self: ptr GodotPoolVector2ArrayReadAccess): ptr GodotPoolVector2ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessPtr*: proc (self: ptr GodotPoolVector2ArrayReadAccess): ptr Vector2 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolVector2ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayReadAccessDestroy*: proc (self: ptr GodotPoolVector2ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector3ArrayReadAccessCopy*: proc (self: ptr GodotPoolVector3ArrayReadAccess): ptr GodotPoolVector3ArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessPtr*: proc (self: ptr GodotPoolVector3ArrayReadAccess): ptr Vector3 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolVector3ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayReadAccessDestroy*: proc (self: ptr GodotPoolVector3ArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolColorArrayReadAccessCopy*: proc (self: ptr GodotPoolColorArrayReadAccess): ptr GodotPoolColorArrayReadAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessPtr*: proc (self: ptr GodotPoolColorArrayReadAccess): ptr Color + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessOperatorAssign*: proc (self, other: ptr GodotPoolColorArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayReadAccessDestroy*: proc (self: ptr GodotPoolColorArrayReadAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolByteArrayWriteAccessCopy*: proc (self: ptr GodotPoolByteArrayWriteAccess): ptr GodotPoolByteArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessPtr*: proc (self: ptr GodotPoolByteArrayWriteAccess): ptr byte + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolByteArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolByteArrayWriteAccessDestroy*: proc (self: ptr GodotPoolByteArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolIntArrayWriteAccessCopy*: proc (self: ptr GodotPoolIntArrayWriteAccess): ptr GodotPoolIntArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessPtr*: proc (self: ptr GodotPoolIntArrayWriteAccess): ptr cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolIntArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolIntArrayWriteAccessDestroy*: proc (self: ptr GodotPoolIntArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolRealArrayWriteAccessCopy*: proc (self: ptr GodotPoolRealArrayWriteAccess): ptr GodotPoolRealArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessPtr*: proc (self: ptr GodotPoolRealArrayWriteAccess): ptr float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolRealArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolRealArrayWriteAccessDestroy*: proc (self: ptr GodotPoolRealArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolStringArrayWriteAccessCopy*: proc (self: ptr GodotPoolStringArrayWriteAccess): ptr GodotPoolStringArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessPtr*: proc (self: ptr GodotPoolStringArrayWriteAccess): ptr GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolStringArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolStringArrayWriteAccessDestroy*: proc (self: ptr GodotPoolStringArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector2ArrayWriteAccessCopy*: proc (self: ptr GodotPoolVector2ArrayWriteAccess): ptr GodotPoolVector2ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessPtr*: proc (self: ptr GodotPoolVector2ArrayWriteAccess): ptr Vector2 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolVector2ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector2ArrayWriteAccessDestroy*: proc (self: ptr GodotPoolVector2ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolVector3ArrayWriteAccessCopy*: proc (self: ptr GodotPoolVector3ArrayWriteAccess): ptr GodotPoolVector3ArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessPtr*: proc (self: ptr GodotPoolVector3ArrayWriteAccess): ptr Vector3 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolVector3ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolVector3ArrayWriteAccessDestroy*: proc (self: ptr GodotPoolVector3ArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + poolColorArrayWriteAccessCopy*: proc (self: ptr GodotPoolColorArrayWriteAccess): ptr GodotPoolColorArrayWriteAccess + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessPtr*: proc (self: ptr GodotPoolColorArrayWriteAccess): ptr Color + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessOperatorAssign*: proc (self, other: ptr GodotPoolColorArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + poolColorArrayWriteAccessDestroy*: proc (self: ptr GodotPoolColorArrayWriteAccess) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Array API + arrayNew*: proc (dest: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewCopy*: proc (dest: var GodotArray, src: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewPoolColorArray*: proc (dest: var GodotArray, src: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolVector3Array*: proc (dest: var GodotArray, + src: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolVector2Array*: proc (dest: var GodotArray, + src: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolStringArray*: proc (dest: var GodotArray, + src: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolRealArray*: proc (dest: var GodotArray, src: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arrayNewPoolIntArray*: proc (dest: var GodotArray, src: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayNewPoolByteArray*: proc (dest: var GodotArray, src: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + arraySet*: proc (self: var GodotArray, idx: cint, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayGet*: proc (self: GodotArray, idx: cint): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayOperatorIndex*: proc (self: var GodotArray, idx: cint): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayAppend*: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayClear*: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayCount*: proc (self: GodotArray, val: GodotVariant): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayEmpty*: proc (self: GodotArray): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayErase*: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFront*: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBack*: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFind*: proc (self: GodotArray, what: GodotVariant, fromIdx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayFindLast*: proc (self: GodotArray, what: GodotVariant): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayHas*: proc (self: GodotArray, val: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayHash*: proc (self: GodotArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayInsert*: proc (self: var GodotArray, pos: cint, val: GodotVariant): Error + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayInvert*: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPopFront*: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPopBack*: proc (self: GodotArray): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPushBack*: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayPushFront*: proc (self: var GodotArray, val: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayRemove*: proc (self: var GodotArray, idx: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayResize*: proc (self: var GodotArray, size: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayRFind*: proc (self: GodotArray, what: GodotVariant, fromIdx: cint): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySize*: proc (self: GodotArray): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySort*: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arraySortCustom*: proc (self: var GodotArray, obj: ptr GodotObject, + f: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBSearch*: proc (self: var GodotArray, val: ptr GodotVariant, + before: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayBSearchCustom*: proc (self: var GodotArray, val: ptr GodotVariant, + obj: ptr GodotObject, f: GodotString, + before: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + arrayDestroy*: proc (self: var GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Dictionary API + dictionaryNew*: proc (dest: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryNewCopy*: proc (dest: var GodotDictionary, src: GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryDestroy*: proc (self: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionarySize*: proc (self: GodotDictionary): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryEmpty*: proc (self: GodotDictionary): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryClear*: proc (self: var GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHas*: proc (self: GodotDictionary, key: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHasAll*: proc (self: GodotDictionary, keys: GodotArray): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryErase*: proc (self: var GodotDictionary, key: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryHash*: proc (self: GodotDictionary): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryKeys*: proc (self: GodotDictionary): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryValues*: proc (self: GodotDictionary): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryGet*: proc (self: GodotDictionary, key: GodotVariant): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionarySet*: proc (self: var GodotDictionary, key, value: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryOperatorIndex*: proc (self: var GodotDictionary, + key: GodotVariant): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + dictionaryNext*: proc (self: GodotDictionary, + key: GodotVariant): ptr GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + dictionaryOperatorEqual*: proc (self, other: GodotDictionary): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + dictionaryToJson*: proc (self: GodotDictionary): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # NodePath API + nodePathNew*: proc (dest: var GodotNodePath, src: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathNewCopy*: proc (dest: var GodotNodePath, src: GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathDestroy*: proc (self: var GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathAsString*: proc (self: GodotNodePath): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathIsAbsolute*: proc (self: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetNameCount*: proc (self: GodotNodePath): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetName*: proc (self: GodotNodePath, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetSubnameCount*: proc (self: GodotNodePath): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nodePathGetSubname*: proc (self: GodotNodePath, idx: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathGetConcatenatedSubnames*: proc (self: GodotNodePath): GodotString + {.noconv, raises: [], gcsafe, + tags: [], locks: 0.} + nodePathIsEmpty*: proc (self: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + nodePathOperatorEqual*: proc (self, other: GodotNodePath): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Plane API + planeNewWithReals*: proc (dest: var Plane, a, b, c, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNewWithVectors*: proc (dest: var Plane, v1, v2, v3: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNewWithNormal*: proc (dest: var Plane, normal: Vector3, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeAsString*: proc (self: Plane): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeNormalized*: proc (self: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeCenter*: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetAnyPoint*: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIsPointOver*: proc (self: Plane, point: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeDistanceTo*: proc (self: Plane, point: Vector3): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeHasPoint*: proc (self: Plane, point: Vector3, epsilon: float32): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeProject*: proc (self: Plane, point: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersect3*: proc (self: Plane, dest: var Vector3, b, c: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersectsRay*: proc (self: Plane, dest: var Vector3, + point, dir: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeIntersectsSegment*: proc (self: Plane, dest: var Vector3, + segmentBegin, segmentEnd: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + planeOperatorNeg*: proc (self: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeOperatorEqual*: proc (self, other: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeSetNormal*: proc (self: var Plane, normal: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetNormal*: proc (self: Plane): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeGetD*: proc (self: Plane): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + planeSetD*: proc (self: var Plane, d: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Rect2 API + rect2NewWithPositionAndSize*: proc (dest: var Rect2, pos, size: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + rect2New*: proc (dest: var Rect2, x, y, width, height: float32) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2AsString*: proc (self: Rect2): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetArea*: proc (self: Rect2): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Intersects*: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Encloses*: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2HasNoArea*: proc (self: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Clip*: proc (self, other: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Merge*: proc (self, other: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2HasPoint*: proc (self: Rect2, point: Vector2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Grow*: proc (self: Rect2, by: float32): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2Expand*: proc (self: Rect2, to: Vector2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2OperatorEqual*: proc (self, other: Rect2): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetPosition*: proc (self: Rect2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2GetSize*: proc (self: Rect2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2SetPosition*: proc (self: var Rect2, pos: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + rect2SetSize*: proc (self: var Rect2, size: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # AABB API + aabbNew*: proc (dest: var AABB, pos, size: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetPosition*: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbSetPosition*: proc (self: var AABB, pos: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetSize*: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbSetSize*: proc (self: var AABB, pos: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbAsString*: proc (self: AABB): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetArea*: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbHasNoArea*: proc (self: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbHasNoSurface*: proc (self: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersects*: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbEncloses*: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbMerge*: proc (self, other: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersection*: proc (self, other: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersectsPlane*: proc (self: AABB, plane: Plane): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbIntersectsSegment*: proc (self: AABB, vFrom, vTo: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbHasPoint*: proc (self: AABB, point: Vector3): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetSupport*: proc (self: AABB, dir: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetLongestAxis*: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetLongestAxisIndex*: proc (self: AABB): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetLongestAxisSize*: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetShortestAxis*: proc (self: AABB): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetShortestAxisIndex*: proc (self: AABB): cint + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbGetShortestAxisSize*: proc (self: AABB): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + aabbExpand*: proc (self: AABB, toPoint: Vector3): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGrow*: proc (self: AABB, by: float32): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbGetEndpoint*: proc (self: AABB, idx: cint): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + aabbOperatorEqual*: proc (self, other: AABB): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # RID API + ridNew*: proc (dest: var RID) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridGetID*: proc (self: RID): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridNewWithResource*: proc (dest: var RID, obj: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridOperatorEqual*: proc (self, other: RID): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + ridOperatorLess*: proc (self, other: RID): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Transform API + transformNewWithAxisOrigin*: proc (dest: var Transform, + xAxis, yAxis, zAxis, origin: Vector3) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformNew*: proc (dest: var Transform, basis: Basis, origin: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformGetBasis*: proc (self: Transform): BasisData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformSetBasis*: proc (self: var Transform, basis: Basis) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformGetOrigin*: proc (self: Transform): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformSetOrigin*: proc (self: var Transform, v: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformAsString*: proc (self: Transform): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformInverse*: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformAffineInverse*: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformOrthonormalized*: proc (self: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformRotated*: proc (self: Transform, axis: Vector3, + phi: float32): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformScaled*: proc (self: Transform, scale: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformTranslated*: proc (self: Transform, offset: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformLookingAt*: proc (self: Transform, target, up: Vector3): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformPlane*: proc (self: Transform, plane: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformInvPlane*: proc (self: Transform, plane: Plane): PlaneData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformNewIdentity*: proc (dest: var Transform) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformOperatorEqual*: proc (self, other: Transform): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformOperatorMultiply*: proc (self, other: Transform): TransformData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformVector3*: proc (self: Transform, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformInvVector3*: proc (self: Transform, v: Vector3): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transformXformAABB*: proc (self: Transform, v: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transformXformInvAABB*: proc (self: Transform, v: AABB): AABBData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Transform2D API + transform2DNew*: proc (dest: var Transform2D, rot: float32, pos: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DNewAxisOrigin*: proc (dest: var Transform2D, + xAxis, yAxis, origin: Vector2) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DAsString*: proc (self: Transform2D): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DInverse*: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DAffineInverse*: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DGetRotation*: proc (self: Transform2D): float32 + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DGetOrigin*: proc (self: Transform2D): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DGetScale*: proc (self: Transform2D): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DOrthonormalized*: proc (self: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DRotated*: proc (self: Transform2D, phi: float32): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DScaled*: proc (self: Transform2D, scale: Vector2): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + transform2DTranslated*: proc (self: Transform2D, offset: Vector2): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformVector2*: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformInvVector2*: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DBasisXformVector2*: proc (self: Transform2D, v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DBasisXformInvVector2*: proc (self: Transform2D, + v: Vector2): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DInterpolateWith*: proc (self, other: Transform2D, + t: float32): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DOperatorEqual*: proc (self, other: Transform2D): bool + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DOperatorMultiply*: proc (self, other: Transform2D): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DNewIdentity*: proc (dest: var Transform2D) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformRect2*: proc (self: Transform2D, v: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + transform2DXformInvRect2*: proc (self: Transform2D, v: Rect2): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + + # Variant API + variantGetType*: proc (v: GodotVariant): VariantType + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewCopy*: proc (dest: var GodotVariant, src: GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewNil*: proc (dest: var GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewBool*: proc (dest: var GodotVariant, val: bool) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewUInt*: proc (dest: var GodotVariant, val: uint64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewInt*: proc (dest: var GodotVariant, val: int64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewReal*: proc (dest: var GodotVariant, val: float64) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewString*: proc (dest: var GodotVariant, val: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewVector2*: proc (dest: var GodotVariant, val: Vector2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewRect2*: proc (dest: var GodotVariant, val: Rect2) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewVector3*: proc (dest: var GodotVariant, val: Vector3) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewTransform2D*: proc (dest: var GodotVariant, val: Transform2D) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPlane*: proc (dest: var GodotVariant, val: Plane) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewQuat*: proc (dest: var GodotVariant, val: Quat) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewAABB*: proc (dest: var GodotVariant, val: AABB) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewBasis*: proc (dest: var GodotVariant, val: Basis) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewTransform*: proc (dest: var GodotVariant, val: Transform) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewColor*: proc (dest: var GodotVariant, val: Color) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewNodePath*: proc (dest: var GodotVariant, val: GodotNodePath) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewRID*: proc (dest: var GodotVariant, val: RID) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewObject*: proc (dest: var GodotVariant, val: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewDictionary*: proc (dest: var GodotVariant, val: GodotDictionary) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewArray*: proc (dest: var GodotVariant, val: GodotArray) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantNewPoolByteArray*: proc (dest: var GodotVariant, + val: GodotPoolByteArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolIntArray*: proc (dest: var GodotVariant, val: GodotPoolIntArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolRealArray*: proc (dest: var GodotVariant, + val: GodotPoolRealArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolStringArray*: proc (dest: var GodotVariant, + val: GodotPoolStringArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolVector2Array*: proc (dest: var GodotVariant, + val: GodotPoolVector2Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolVector3Array*: proc (dest: var GodotVariant, + val: GodotPoolVector3Array) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantNewPoolColorArray*: proc (dest: var GodotVariant, + val: GodotPoolColorArray) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsBool*: proc (self: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsUInt*: proc (self: GodotVariant): uint64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsInt*: proc (self: GodotVariant): int64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsReal*: proc (self: GodotVariant): float64 + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsString*: proc (self: GodotVariant): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsVector2*: proc (self: GodotVariant): Vector2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsRect2*: proc (self: GodotVariant): Rect2Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsVector3*: proc (self: GodotVariant): Vector3Data + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsTransform2D*: proc (self: GodotVariant): Transform2DData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsPlane*: proc (self: GodotVariant): PlaneData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsQuat*: proc (self: GodotVariant): QuatData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsAABB*: proc (self: GodotVariant): AABBData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsBasis*: proc (self: GodotVariant): BasisData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsTransform*: proc (self: GodotVariant): TransformData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsColor*: proc (self: GodotVariant): ColorData + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsNodePath*: proc (self: GodotVariant): GodotNodePath + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsRID*: proc (self: GodotVariant): RID + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsObject*: proc (self: GodotVariant): ptr GodotObject + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsDictionary*: proc (self: GodotVariant): GodotDictionary + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsArray*: proc (self: GodotVariant): GodotArray + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantAsPoolByteArray*: proc (self: GodotVariant): GodotPoolByteArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolIntArray*: proc (self: GodotVariant): GodotPoolIntArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolRealArray*: proc (self: GodotVariant): GodotPoolRealArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolStringArray*: proc (self: GodotVariant): GodotPoolStringArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolVector2Array*: proc (self: GodotVariant): GodotPoolVector2Array + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolVector3Array*: proc (self: GodotVariant): GodotPoolVector3Array + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantAsPoolColorArray*: proc (self: GodotVariant): GodotPoolColorArray + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + variantCall*: proc (self: var GodotVariant, meth: GodotString, + args: ptr array[MAX_ARG_COUNT, ptr GodotVariant], + argcount: cint, + callError: var VariantCallError): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantHasMethod*: proc (self: GodotVariant, meth: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantOperatorEqual*: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantOperatorLess*: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantHashCompare*: proc (self, other: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantBooleanize*: proc (self: GodotVariant): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + variantDestroy*: proc (self: var GodotVariant) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # String API + charStringLength*: proc (self: GodotCharString): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + charStringGetData*: proc (self: GodotCharString): cstring + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + charStringDestroy*: proc (self: var GodotCharString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringNew*: proc (dest: var GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringNewCopy*: proc (dest: var GodotString, src: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringWideStr*: proc (self: GodotString): ptr cwchar_t + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorEqual*: proc (self, other: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorLess*: proc (self, other: GodotString): bool + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringOperatorPlus*: proc (self, other: GodotString): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringLength*: proc (self: GodotString): cint + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringDestroy*: proc (self: var GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringUtf8*: proc (self: GodotString): GodotCharString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringCharsToUtf8*: proc (str: cstring): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + stringCharsToUtf8WithLen*: proc (str: cstring, len: cint): GodotString + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + # Misc API + objectDestroy*: proc (self: ptr GodotObject) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + globalGetSingleton*: proc (name: cstring): ptr GodotObject + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindGetMethod*: proc (className, + methodName: cstring): ptr GodotMethodBind + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindPtrCall*: proc (methodBind: ptr GodotMethodBind, + obj: ptr GodotObject, + args: ptr array[MAX_ARG_COUNT, pointer], + ret: pointer) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + methodBindCall*: proc (methodBind: ptr GodotMethodBind, obj: ptr GodotObject, + args: ptr array[MAX_ARG_COUNT, ptr GodotVariant], + argCount: cint, + callError: var VariantCallError): GodotVariant + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + getClassConstructor*: proc (className: cstring): GodotClassConstructor + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + alloc*: proc (bytes: cint): pointer + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + realloc*: proc (p: pointer, bytes: cint): pointer + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + free*: proc (p: pointer) {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + printError*: proc (description, function, file: cstring, line: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + printWarning*: proc (description, function, file: cstring, line: cint) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + print*: proc (message: GodotString) + {.noconv, raises: [], gcsafe, tags: [], locks: 0.} + + nativeScriptRegisterClass*: proc (gdnativeHandle: pointer, + name, base: cstring, + createFunc: GodotInstanceCreateFunc, + destroyFunc: GodotInstanceDestroyFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterToolClass*: proc (gdnativeHandle: pointer, + name, base: cstring, + createFunc: GodotInstanceCreateFunc, + destroyFunc: GodotInstanceDestroyFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterMethod*: proc (gdnativeHandle: pointer, + name, functionName: cstring, + attr: GodotMethodAttributes, + meth: GodotInstanceMethod) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterProperty*: proc (gdnativeHandle: pointer, + name, path: cstring, + attr: ptr GodotPropertyAttributes, + setFunc: GodotPropertySetFunc, + getFunc: GodotPropertyGetFunc) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptRegisterSignal*: proc (gdnativeHandle: pointer, name: cstring, + signal: GodotSignal) + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + nativeScriptGetUserdata*: proc (obj: ptr GodotObject): pointer + {.noconv, raises: [], gcsafe, tags: [], + locks: 0.} + +{.push stackTrace: off.} +proc toColor*(val: ColorData): Color {.inline, noinit.} = + cast[Color](val) + +proc toVector3*(val: Vector3Data): Vector3 {.inline, noinit.} = + cast[Vector3](val) + +proc toVector2*(val: Vector2Data): Vector2 {.inline, noinit.} = + cast[Vector2](val) + +proc toPlane*(val: PlaneData): Plane {.inline, noinit.} = + cast[Plane](val) + +proc toBasis*(val: BasisData): Basis {.inline, noinit.} = + cast[Basis](val) + +proc toQuat*(val: QuatData): Quat {.inline, noinit.} = + cast[Quat](val) + +proc toAABB*(val: AABBData): AABB {.inline, noinit.} = + cast[AABB](val) + +proc toRect2*(val: Rect2Data): Rect2 {.inline, noinit.} = + cast[Rect2](val) + +proc toTransform2D*(val: Transform2DData): Transform2D {.inline, noinit.} = + cast[Transform2D](val) + +proc toTransform*(val: TransformData): Transform {.inline, noinit.} = + cast[Transform](val) +{.pop.} + +macro assign(dest, src: typed, values: untyped): typed = + result = newStmtList() + for val in values: + result.add(newNimNode(nnkAsgn).add( + newNimNode(nnkDotExpr).add(dest, val), + newNimNode(nnkDotExpr).add(src, val))) + +var gdNativeAPI: GDNativeAPI + +proc getGDNativeAPI*(): ptr GDNativeAPI {.inline.} = + addr gdNativeAPI + +proc setGDNativeAPIInternal(apiStruct: pointer, initOptions: ptr GDNativeInitOptions, + foundCoreApi: var bool, foundNativeScriptApi: var bool) = + let header = cast[ptr GDNativeAPIHeader](apiStruct) + + if header.typ >= ord(low(GDNativeAPIType)).cuint and header.typ <= ord(high(GDNativeAPIType)).cuint: + let typ = GDNativeAPIType(header.typ) + case typ: + of GDNativeCore: + let coreApi = cast[ptr GDNativeCoreAPI1](apiStruct) + if coreApi[].version.major == 1 and coreApi[].version.minor == 0: + assign(gdNativeApi, coreApi[]): + # Color API + colorNewRGBA + colorNewRGB + colorGetR + colorSetR + colorGetG + colorSetG + colorGetB + colorSetB + colorGetA + colorSetA + colorGetH + colorGetS + colorGetV + colorAsString + colorToRGBA32 + colorAsARGB32 + colorGray + colorInverted + colorContrasted + colorLinearInterpolate + colorBlend + colorToHtml + colorOperatorEqual + colorOperatorLess + + # Vector 2 API + vector2New + vector2AsString + vector2Normalized + vector2Length + vector2Angle + vector2LengthSquared + vector2IsNormalized + vector2DistanceTo + vector2DistanceSquaredTo + vector2AngleTo + vector2AngleToPoint + vector2LinearInterpolate + vector2CubicInterpolate + vector2Rotated + vector2Tangent + vector2Floor + vector2Snapped + vector2Aspect + vector2Dot + vector2Slide + vector2Bounce + vector2Reflect + vector2Abs + vector2Clamped + vector2OperatorAdd + vector2OperatorSubtract + vector2OperatorMultiplyVector + vector2OperatorMultiplyScalar + vector2OperatorDivideVector + vector2OperatorDivideScalar + vector2OperatorEqual + vector2OperatorLess + vector2OperatorNeg + + # Quat API + quatNew + quatNewWithAxisAngle + quatGetX + quatSetX + quatGetY + quatSetY + quatGetZ + quatSetZ + quatGetW + quatSetW + quatAsString + quatLength + quatLengthSquared + quatNormalized + quatIsNormalized + quatInverse + quatDot + quatXform + quatSlerp + quatSlerpni + quatCubicSlerp + quatOperatorMultiply + quatOperatorAdd + quatOperatorSubtract + quatOperatorDivide + quatOperatorEqual + quatOperatorNeg + + # PoolByteArray API + poolByteArrayNew + poolByteArrayNewCopy + poolByteArrayNewWithArray + poolByteArrayAppend + poolByteArrayAppendArray + poolByteArrayInsert + poolByteArrayInvert + poolByteArrayPushBack + poolByteArrayRemove + poolByteArrayResize + poolByteArrayRead + poolByteArrayWrite + poolByteArraySet + poolByteArrayGet + poolByteArraySize + poolByteArrayDestroy + + # PoolIntArray API + poolIntArrayNew + poolIntArrayNewCopy + poolIntArrayNewWithArray + poolIntArrayAppend + poolIntArrayAppendArray + poolIntArrayInsert + poolIntArrayInvert + poolIntArrayPushBack + poolIntArrayRemove + poolIntArrayResize + poolIntArrayRead + poolIntArrayWrite + poolIntArraySet + poolIntArrayGet + poolIntArraySize + poolIntArrayDestroy + + # PoolRealArray API + poolRealArrayNew + poolRealArrayNewCopy + poolRealArrayNewWithArray + poolRealArrayAppend + poolRealArrayAppendArray + poolRealArrayInsert + poolRealArrayInvert + poolRealArrayPushBack + poolRealArrayRemove + poolRealArrayResize + poolRealArrayRead + poolRealArrayWrite + poolRealArraySet + poolRealArrayGet + poolRealArraySize + poolRealArrayDestroy + + # PoolStringArray API + poolStringArrayNew + poolStringArrayNewCopy + poolStringArrayNewWithArray + poolStringArrayAppend + poolStringArrayAppendArray + poolStringArrayInsert + poolStringArrayInvert + poolStringArrayPushBack + poolStringArrayRemove + poolStringArrayResize + poolStringArrayRead + poolStringArrayWrite + poolStringArraySet + poolStringArrayGet + poolStringArraySize + poolStringArrayDestroy + + + # PoolVector2 API + poolVector2ArrayNew + poolVector2ArrayNewCopy + poolVector2ArrayNewWithArray + poolVector2ArrayAppend + poolVector2ArrayAppendArray + poolVector2ArrayInsert + poolVector2ArrayInvert + poolVector2ArrayPushBack + poolVector2ArrayRemove + poolVector2ArrayResize + poolVector2ArrayRead + poolVector2ArrayWrite + poolVector2ArraySet + poolVector2ArrayGet + poolVector2ArraySize + poolVector2ArrayDestroy + + # PoolVector3 API + poolVector3ArrayNew + poolVector3ArrayNewCopy + poolVector3ArrayNewWithArray + poolVector3ArrayAppend + poolVector3ArrayAppendArray + poolVector3ArrayInsert + poolVector3ArrayInvert + poolVector3ArrayPushBack + poolVector3ArrayRemove + poolVector3ArrayResize + poolVector3ArrayRead + poolVector3ArrayWrite + poolVector3ArraySet + poolVector3ArrayGet + poolVector3ArraySize + poolVector3ArrayDestroy + + # PoolColorArray API + poolColorArrayNew + poolColorArrayNewCopy + poolColorArrayNewWithArray + poolColorArrayAppend + poolColorArrayAppendArray + poolColorArrayInsert + poolColorArrayInvert + poolColorArrayPushBack + poolColorArrayRemove + poolColorArrayResize + poolColorArrayRead + poolColorArrayWrite + poolColorArraySet + poolColorArrayGet + poolColorArraySize + poolColorArrayDestroy + + # Array API + arrayNew + arrayNewCopy + arrayNewPoolColorArray + arrayNewPoolVector3Array + arrayNewPoolVector2Array + arrayNewPoolStringArray + arrayNewPoolRealArray + arrayNewPoolIntArray + arrayNewPoolByteArray + arraySet + arrayGet + arrayOperatorIndex + arrayAppend + arrayClear + arrayCount + arrayEmpty + arrayErase + arrayFront + arrayBack + arrayFind + arrayFindLast + arrayHas + arrayHash + arrayInsert + arrayInvert + arrayPopFront + arrayPopBack + arrayPushBack + arrayPushFront + arrayRemove + arrayResize + arrayRFind + arraySize + arraySort + arraySortCustom + arrayBSearch + arrayBSearchCustom + arrayDestroy + + # Pool Array Read/Write Access API + + poolByteArrayReadAccessCopy + poolByteArrayReadAccessPtr + poolByteArrayReadAccessOperatorAssign + poolByteArrayReadAccessDestroy + + poolIntArrayReadAccessCopy + poolIntArrayReadAccessPtr + poolIntArrayReadAccessOperatorAssign + poolIntArrayReadAccessDestroy + + poolRealArrayReadAccessCopy + poolRealArrayReadAccessPtr + poolRealArrayReadAccessOperatorAssign + poolRealArrayReadAccessDestroy + + poolStringArrayReadAccessCopy + poolStringArrayReadAccessPtr + poolStringArrayReadAccessOperatorAssign + poolStringArrayReadAccessDestroy + + poolVector2ArrayReadAccessCopy + poolVector2ArrayReadAccessPtr + poolVector2ArrayReadAccessOperatorAssign + poolVector2ArrayReadAccessDestroy + + poolVector3ArrayReadAccessCopy + poolVector3ArrayReadAccessPtr + poolVector3ArrayReadAccessOperatorAssign + poolVector3ArrayReadAccessDestroy + + poolColorArrayReadAccessCopy + poolColorArrayReadAccessPtr + poolColorArrayReadAccessOperatorAssign + poolColorArrayReadAccessDestroy + + poolByteArrayWriteAccessCopy + poolByteArrayWriteAccessPtr + poolByteArrayWriteAccessOperatorAssign + poolByteArrayWriteAccessDestroy + + poolIntArrayWriteAccessCopy + poolIntArrayWriteAccessPtr + poolIntArrayWriteAccessOperatorAssign + poolIntArrayWriteAccessDestroy + + poolRealArrayWriteAccessCopy + poolRealArrayWriteAccessPtr + poolRealArrayWriteAccessOperatorAssign + poolRealArrayWriteAccessDestroy + + poolStringArrayWriteAccessCopy + poolStringArrayWriteAccessPtr + poolStringArrayWriteAccessOperatorAssign + poolStringArrayWriteAccessDestroy + + poolVector2ArrayWriteAccessCopy + poolVector2ArrayWriteAccessPtr + poolVector2ArrayWriteAccessOperatorAssign + poolVector2ArrayWriteAccessDestroy + + poolVector3ArrayWriteAccessCopy + poolVector3ArrayWriteAccessPtr + poolVector3ArrayWriteAccessOperatorAssign + poolVector3ArrayWriteAccessDestroy + + poolColorArrayWriteAccessCopy + poolColorArrayWriteAccessPtr + poolColorArrayWriteAccessOperatorAssign + poolColorArrayWriteAccessDestroy + + # Dictionary API + dictionaryNew + dictionaryNewCopy + dictionaryDestroy + dictionarySize + dictionaryEmpty + dictionaryClear + dictionaryHas + dictionaryHasAll + dictionaryErase + dictionaryHash + dictionaryKeys + dictionaryValues + dictionaryGet + dictionarySet + dictionaryOperatorIndex + dictionaryNext + dictionaryOperatorEqual + dictionaryToJson + + # NodePath API + nodePathNew + nodePathNewCopy + nodePathDestroy + nodePathAsString + nodePathIsAbsolute + nodePathGetNameCount + nodePathGetName + nodePathGetSubnameCount + nodePathGetSubname + nodePathGetConcatenatedSubnames + nodePathIsEmpty + nodePathOperatorEqual + + # Plane API + planeNewWithReals + planeNewWithVectors + planeNewWithNormal + planeAsString + planeNormalized + planeCenter + planeGetAnyPoint + planeIsPointOver + planeDistanceTo + planeHasPoint + planeProject + planeIntersect3 + planeIntersectsRay + planeIntersectsSegment + planeOperatorNeg + planeOperatorEqual + planeSetNormal + planeGetNormal + planeGetD + planeSetD + + # Rect2 API + rect2NewWithPositionAndSize + rect2New + rect2AsString + rect2GetArea + rect2Intersects + rect2Encloses + rect2HasNoArea + rect2Clip + rect2Merge + rect2HasPoint + rect2Grow + rect2Expand + rect2OperatorEqual + rect2GetPosition + rect2GetSize + rect2SetPosition + rect2SetSize + + # AABB API + aabbNew + aabbGetPosition + aabbSetPosition + aabbGetSize + aabbSetSize + aabbAsString + aabbGetArea + aabbHasNoArea + aabbHasNoSurface + aabbIntersects + aabbEncloses + aabbMerge + aabbIntersection + aabbIntersectsPlane + aabbIntersectsSegment + aabbHasPoint + aabbGetSupport + aabbGetLongestAxis + aabbGetLongestAxisIndex + aabbGetLongestAxisSize + aabbGetShortestAxis + aabbGetShortestAxisIndex + aabbGetShortestAxisSize + aabbExpand + aabbGrow + aabbGetEndpoint + aabbOperatorEqual + + # RID API + ridNew + ridGetID + ridNewWithResource + ridOperatorEqual + ridOperatorLess + + # Transform API + transformNewWithAxisOrigin + transformNew + transformGetBasis + transformSetBasis + transformGetOrigin + transformSetOrigin + transformAsString + transformInverse + transformAffineInverse + transformOrthonormalized + transformRotated + transformScaled + transformTranslated + transformLookingAt + transformXformPlane + transformXformInvPlane + transformNewIdentity + transformOperatorEqual + transformOperatorMultiply + transformXformVector3 + transformXformInvVector3 + transformXformAABB + transformXformInvAABB + + # Transform2D API + transform2DNew + transform2DNewAxisOrigin + transform2DAsString + transform2DInverse + transform2DAffineInverse + transform2DGetRotation + transform2DGetOrigin + transform2DGetScale + transform2DOrthonormalized + transform2DRotated + transform2DScaled + transform2DTranslated + transform2DXformVector2 + transform2DXformInvVector2 + transform2DBasisXformVector2 + transform2DBasisXformInvVector2 + transform2DInterpolateWith + transform2DOperatorEqual + transform2DOperatorMultiply + transform2DNewIdentity + transform2DXformRect2 + transform2DXformInvRect2 + + # Variant API + variantGetType + variantNewCopy + variantNewNil + variantNewBool + variantNewUInt + variantNewInt + variantNewReal + variantNewString + variantNewVector2 + variantNewRect2 + variantNewVector3 + variantNewTransform2D + + variantNewPlane + variantNewQuat + variantNewAABB + variantNewBasis + variantNewTransform + variantNewColor + variantNewNodePath + variantNewRID + variantNewObject + variantNewDictionary + variantNewArray + variantNewPoolByteArray + variantNewPoolIntArray + variantNewPoolRealArray + variantNewPoolStringArray + variantNewPoolVector2Array + variantNewPoolVector3Array + variantNewPoolColorArray + variantAsBool + variantAsUInt + variantAsInt + variantAsReal + variantAsString + variantAsVector2 + variantAsRect2 + variantAsVector3 + variantAsTransform2D + variantAsPlane + variantAsQuat + variantAsAABB + variantAsBasis + variantAsTransform + variantAsColor + variantAsNodePath + variantAsRID + variantAsObject + variantAsDictionary + variantAsArray + variantAsPoolByteArray + variantAsPoolIntArray + variantAsPoolRealArray + variantAsPoolStringArray + variantAsPoolVector2Array + variantAsPoolVector3Array + variantAsPoolColorArray + variantCall + variantHasMethod + variantOperatorEqual + variantOperatorLess + variantHashCompare + variantBooleanize + variantDestroy + + # String API + charStringLength + charStringGetData + charStringDestroy + + stringNew + stringNewCopy + stringWideStr + stringOperatorEqual + stringOperatorLess + stringOperatorPlus + stringLength + stringDestroy + stringUtf8 + stringCharsToUtf8 + stringCharsToUtf8WithLen + + # Misc API + objectDestroy + globalGetSingleton + methodBindGetMethod + methodBindPtrCall + methodBindCall + getClassConstructor + + alloc + realloc + free + + printError + printWarning + print + + foundCoreApi = true + for i in 0.cuint..= (0, 19, 0): + import compiler/lineinfos + +when (NimMajor, NimMinor, NimPatch) >= (0, 19, 0): + var gic = newIdentCache() + + proc getIdent(ident: string): PIdent = + getIdent(gic, ident) + +proc ident(ident: string): PNode = + result = PNode(kind: nkIdent, ident: getIdent(ident)) + +proc newPNode(kind: TNodeKind): PNode = + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + result = newNode(kind) + else: + result = PNode(kind: kind) + result.info.fileIndex = InvalidFileIdx + result.info.col = int16(-1) + result.info.line = uint16(0) + +proc addChain(node: PNode, others: varargs[PNode]): PNode {.discardable.} = + for other in others: + node.add(other) + result = node + +proc newIdentDefs(name, typ: PNode, + defaultVal: PNode = nil): PNode = + result = newPNode(nkIdentDefs) + result.add(name) + result.add(typ) + if defaultVal.isNil: + result.add(newPNode(nkEmpty)) + else: + result.add(defaultVal) + +proc newProc(name: PNode, params: openArray[PNode], body = newPNode(nkEmpty), + procType = nkProcDef): PNode = + result = newPNode(procType) + result.add(name) + result.add(newPNode(nkEmpty)) + result.add(newPNode(nkEmpty)) + let formalParams = newPNode(nkFormalParams) + for param in params: + formalParams.add(param) + result.add(formalParams) + result.add(newPNode(nkEmpty)) + result.add(newPNode(nkEmpty)) + result.add(body) + +proc newIfStmt(condition, body: PNode): PNode = + result = newPNode(nkIfStmt) + let branch = newPNode(nkElifBranch) + result.add(branch) + branch.add(condition) + branch.add(body) + +proc newCall(theProc: PNode, args: varargs[PNode]): PNode = + result = newPNode(nkCall) + result.add(theProc) + for arg in args: + result.add(arg) + +proc newCall(theProc: string, args: varargs[PNode]): PNode = + newCall(ident(theProc), args) + +proc newStrLit(s: string): PNode = + result = newPNode(nkStrLit) + result.strVal = s + +proc newRStrLit(s: string): PNode = + result = newPNode(nkRStrLit) + result.strVal = s + +proc newCStringLit(s: string): PNode = + newPNode(nkCallStrLit).addChain(ident("cstring"), newRStrLit(s)) + +proc newIntLit(val: BiggestInt): PNode = + result = newPNode(nkIntLit) + result.intVal = val + +proc newInt64Lit(val: BiggestInt): PNode = + result = newPNode(nkInt64Lit) + result.intVal = val + +proc newFloatLit(val: BiggestFloat): PNode = + result = newPNode(nkFloatLit) + result.floatVal = val + +proc newFloat64Lit(val: BiggestFloat): PNode = + result = newPNode(nkFloat64Lit) + result.floatVal = val + +proc newNilLit(): PNode = + result = newPNode(nkNilLit) + +proc newDotExpr(left, right: PNode): PNode = + result = newPNode(nkDotExpr) + result.add(left) + result.add(right) + +proc newCommand(left, right: PNode): PNode = + result = newPNode(nkCommand) + result.add(left) + result.add(right) + +proc infix(left, op, right: PNode): PNode = + result = newPNode(nkInfix) + result.add(op) + result.add(left) + result.add(right) + +proc postfix(left: PNode, op: string): PNode = + result = newPNode(nkPostfix) + result.add(ident(op)) + result.add(left) + +proc prefix(op: string, right: PNode): PNode = + result = newPNode(nkPrefix) + result.add(ident(op)) + result.add(right) + +proc newBracketExpr(first, bracket: PNode): PNode = + newPNode(nkBracketExpr).addChain(first, bracket) + +proc newEmptyNode(): PNode = + newPNode(nkEmpty) + +type GodotType = ref object + name: string + godotName: string + baseName: string + doc: string + derivedCount: int + isSingleton: bool + jsonNode: JsonNode + +proc findCommonRoot(typeRegistry: Table[string, GodotType], + types: seq[string]): string = + if types.len == 0: return "Object" + var chains = newSeq[seq[string]](types.len) + for idx, typ in types: + chains[idx] = newSeq[string]() + chains[idx].add(typ) + var curTyp = typeRegistry[typ] + while curTyp.baseName != "NimGodotObject": + chains[idx].add(curTyp.baseName) + curTyp = typeRegistry[curTyp.baseName] + chains[idx].reverse() + + var idx = 0 + while true: + var curType = none(string) + var allEqual = true + for chain in chains: + if idx >= chain.len: + allEqual = false + break + if curType.isNone: + curType = some(chain[idx]) + elif curType.get != chain[idx]: + allEqual = false + break + if allEqual: + result = curType.get + else: + break + inc idx + +proc incDerivedCount(types: var Table[string, GodotType], + className: string) = + let typ = types.getOrDefault(className) + if not typ.isNil: + inc typ.derivedCount + types.incDerivedCount(typ.baseName) + +proc toNimType(godotType: string): string = + result = case godotType: + of "float": "float64" + of "int": "int64" + of "String": "string" + of "File": "godottypes.File" + else: godotType + + if result.startsWith("enum."): + result = if result == "enum.Error": "Error" else: "int64" + +proc toNimType(types: Table[string, GodotType], godotType: string): string = + let origType = + if godotType.contains(','): + findCommonRoot(types, godotType.split(',')) + else: + godotType + result = toNimType(origType) + +proc toNimStyle(name: string): string = + result = newStringOfCap(name.len + 1) + var i = 0 + var makeUpperCase: bool + while i < name.len: + if name[i] == '_': + if result.len != 0: + makeUpperCase = true + elif name[i] != '/': # remove slashes + if makeUpperCase: + result.add(name[i].toUpperAscii()) + makeUpperCase = false + else: + result.add(name[i]) + inc i + + while isKeyword(getIdent(result)): + result.add(result[result.len - 1]) + + if result == "result": + result = "resultVal" + +proc newRefTypeNode(typeSection: PNode, typ, base, doc: string, + isExported = true) = + let typeDef = newPNode(nkTypeDef) + typeSection.add(typeDef) + if isExported: + typeDef.add(postfix(ident(typ), "*")) + else: + typeDef.add(ident(typ)) + + typeDef.add(newPNode(nkEmpty)) # generic + let objTy = newPNode(nkObjectTy) + let refTy = newPNode(nkRefTy) + refTy.add(objTy) + typeDef.add(refTy) + + objTy.add(newPNode(nkEmpty)) + let inherit = newPNode(nkOfInherit) + inherit.add(ident(base)) + objTy.add(inherit) + + if doc.len > 0: + let recList = newPNode(nkRecList) + let docNode = newPNode(nkCommentStmt) + docNode.comment = doc + recList.add(docNode) + objTy.add(recList) + else: + objTy.add(newPNode(nkEmpty)) + +proc makeConstSection(constObj: JsonNode): PNode = + if constObj.len == 0: + return newPNode(nkEmpty) + + result = newPNode(nkConstSection) + for field, val in constObj: + let def = newPNode(nkConstDef) + def.add(postfix(ident(field), "*")) + def.add(newPNode(nkEmpty)) # infer type + var valNode: PNode + if val.kind == JInt: + valNode = newInt64Lit(val.num) + # valNode.intVal = val.num + elif val.kind == JFloat: + valNode = newFloat64Lit(val.fnum) + elif val.kind == JBool: + valNode = ident($val.bval) + elif val.kind == JString: + valNode = newPNode(nkStrLit) + valNode.strVal = val.str + else: + raise newException(ValueError, "Unexpected constant kind: " & $val.kind) + def.add(valNode) + result.add(def) + +type + ArgKind = enum + Normal, + VarArgs + Bound + + MethodArg = object + name: string + typ: string + defaultVal: JsonNode + kind: ArgKind + + MethodInfo = ref object + name: PNode + godotName: string + typ: GodotType + args: seq[MethodArg] + returnType: Option[string] + isVirtual: bool + isBase: bool + isDiscardable: bool + +const standardTypes = toHashSet( + ["bool", "cint", "int", "uint8", "int8", "uint16", "int16", "uint32", "int32", + "uint64", "Error", + "int64", "float32", "cfloat", "float64", "GodotString", "Vector2", "Rect2", + "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform", + "Color", "RID", "NodePath", "Dictionary", "Variant", "Array", + "PoolByteArray", "PoolIntArray", "PoolRealArray", "PoolStringArray", + "PoolVector2Array", "PoolVector3Array", "PoolColorArray"]) + +const variantPrimitives = [ + "bool", "cint", "int", "uint8", "int8", "uint16", "int16", "uint32", "int32", + "uint64", "Error", + "int64", "float32", "cfloat", "float64", "GodotString", "Vector2", "Rect2", + "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform", + "Color", "RID"] + +const smallIntTypes = toHashSet(["uint8", "int8", "uint16", "int16", "uint32", + "int32", "cint", "int", "Error"]) +const int64Types = toHashSet(["uint64", "int64"]) +const intTypes = union(smallIntTypes, int64Types) +const float64Types = toHashSet(["float64", "cdouble"]) +const float32Types = toHashSet(["float32", "cfloat"]) +const floatTypes = union(float64Types, float32Types) +const arrayTypes = toHashSet(["Array", "PoolByteArray", + "PoolIntArray", "PoolRealArray", "PoolStringArray", "PoolVector2Array", + "PoolVector3Array", "PoolColorArray"]) +const wrapperTypes = union(arrayTypes, + toHashSet(["NodePath", "Dictionary", "Variant"])) + +proc getInternalPtr(varName: PNode, typ: string): PNode = + assert(typ in wrapperTypes or typ == "Object") + result = newDotExpr(varName, ident("godot" & typ)) + +proc newNilCheck(ident, toAssign: PNode): PNode = + newIfStmt(newCall("isNil", ident), + newPNode(nkAsgn).addChain(ident).addChain( + toAssign + ) + ) + +proc singletonName(typ: string): PNode = + ident("singleton" & typ) + +proc makeDefaultValue(arg: MethodArg): PNode = + result = newEmptyNode() + if not arg.defaultVal.isNil: + var failed = false + if arg.typ == "bool": + result = ident(arg.defaultVal.str.toLowerAscii()) + elif arg.typ in intTypes: + result = newInt64Lit(parseBiggestInt(arg.defaultVal.str)) + elif arg.typ == "string" or arg.typ == "NodePath": + result = newStrLit(arg.defaultVal.str) + elif arg.typ in floatTypes: + result = newFloatLit(parseFloat(arg.defaultVal.str)) + elif arg.defaultVal.str == "Null": + if arg.typ == "Variant": + result = newCall("newVariant") + else: + result = newNilLit() + elif arg.typ == "Color": + result = newCall("initColor", + arg.defaultVal.str.split(',').mapIt(newFloatLit(parseFloat(it)))) + elif arg.typ == "RID" and arg.defaultVal.str == "[RID]": + result = newCall("initRID") + elif arg.typ in arrayTypes and (arg.defaultVal.str == "[]" or + arg.defaultVal.str == "[" & arg.typ & "]"): + result = newCall("new" & arg.typ) + elif arg.typ == "Vector2" or arg.typ == "Vector3" or arg.typ == "Rect2": + let parts = arg.defaultVal.str.replace("(", "").replace(")", ""). + replace(" ", ""). + split(',').mapIt(newFloatLit(parseFloat(it))) + if arg.typ.endsWith("r2"): + result = newCall("vec2", parts) + elif arg.typ.endsWith('3'): + result = newCall("vec3", parts) + else: + result = newCall("initRect2", parts) + elif arg.defaultVal.str == "[Object:null]": + result = newNilLit() + elif arg.typ == "Transform": + let transformParts = arg.defaultVal.str.replace(" ", "").split('-') + doAssert(transformParts.len == 2) + let basisParts = transformParts[0].split(',').mapIt( + newFloatLit(parseFloat(it))) + let originParts = transformParts[1].split(',').mapIt( + newFloatLit(parseFloat(it))) + let basis = newCall("initBasis", basisParts) + let origin = newCall("vec3", originParts) + result = newCall("initTransform", basis, origin) + elif arg.typ == "Transform2D": + let parts = arg.defaultVal.str. + replace(" ", ""). + replace(")", ""). + replace("(", ""). + split(',').mapIt(newFloatLit(parseFloat(it))) + doAssert(parts.len == 6) + let xAxis = newCall("vec2", parts[0..1]) + let yAxis = newCall("vec2", parts[2..3]) + let origin = newCall("vec2", parts[4..5]) + result = newCall("initTransform2D", xAxis, yAxis, origin) + elif arg.typ == "Variant": + if arg.defaultVal.str == "0": + result = newCall("newVariant", newIntLit(0)) + elif arg.defaultVal.str == "Null": + result = newCall("newVariant") + else: + failed = true + elif arg.typ == "Dictionary": + result = newCall("newDictionary") + else: + failed = true + + if failed: + raise newException( + ValueError, + "Cannot build default value from \"$#\" ($#) - please report this at https://github.com/pragmagic/godot-nim/issues" % + [$arg.defaultVal, arg.typ]) + +proc boundArgName(idx: int): string = + "godotBoundArg" & $idx + +proc doGenerateMethod(tree: PNode, methodBindRegistry: var HashSet[string], + meth: MethodInfo, withImplementation: bool) = + var body: PNode + if not withImplementation: + body = newPNode(nkEmpty) + elif meth.godotName == "_init" and meth.typ.godotName == "Object": + # It's not real (calling it crashes) and will be removed later, + # but we use init() convention in Nim, so it needs to work. + body = newPNode(nkStmtList).addChain( + newPNode(nkDiscardStmt).addChain(newPNode(nkEmpty))) + else: + let methGodotName = if meth.godotName.startsWith('_'): + "underscore" & meth.godotName[1..^1] + else: + meth.godotName + var methodBindName = toNimStyle( + meth.typ.name & "_" & methGodotName & "_method_bind") + if methodBindName[0].isUpperAscii(): + methodBindName[0] = methodBindName[0].toLowerAscii() + if methodBindName notin methodBindRegistry: + let methodBindDecl = newPNode(nkVarSection).addChain( + newIdentDefs( + newPNode(nkPragmaExpr).addChain( + ident(methodBindName)).addChain( + newPNode(nkPragma).addChain(ident("threadvar"))), + newPNode(nkPtrTy).addChain(ident("GodotMethodBind")) + )) + tree.add(methodBindDecl) + methodBindRegistry.incl(methodBindName) + + let nilCheck = newNilCheck(ident(methodBindName), + newCall("getMethod", newCStringLit(meth.typ.godotName), + newCStringLit(meth.godotName)) + ) + let vars = newPNode(nkVarSection) + var varargsName = none(string) + var isVarargs: bool + var staticArgsLen: int + var argLenNode = newIntLit(0) + let argsName = ident("argsToPassToGodot") + if meth.args.len > 0: + for idx, arg in meth.args: + if arg.kind == ArgKind.VarArgs: + varargsName = some(arg.name) + isVarargs = true + vars.add(newIdentDefs(ident("callError"), ident("VariantCallError"))) + elif arg.kind == ArgKind.Bound: + let argName = boundArgName(idx) + vars.add(newIdentDefs( + ident(argName), newPNode(nkEmpty), arg.makeDefaultValue())) + + let argsAlloc = newPNode(nkCast).addChain( + newPNode(nkPtrTy).addChain( + newPNode(nkBracketExpr).addChain( + ident("array"), ident("MAX_ARG_COUNT"), + if isVarargs: newPNode(nkPtrTy).addChain(ident("GodotVariant")) + else: ident("pointer")))) + staticArgsLen = if varargsName.isNone: meth.args.len + else: meth.args.len - 1 + if varargsName.isSome: + argLenNode = newCall("cint", + infix(newIntLit(staticArgsLen), + ident("+"), + newDotExpr(ident(varargsName.get), ident("len")))) + argsAlloc.add(newCall("godotAlloc", newCall("cint", infix( + newCall("sizeof", newPNode(nkPtrTy).addChain(ident("GodotVariant"))), ident("*"), + newPNode(nkPar).addChain(argLenNode)))) + ) + else: + argLenNode = newCall("cint", newIntLit(staticArgsLen)) + vars.add(newIdentDefs( + ident("argsStatic"), + newPNode(nkBracketExpr).addChain( + ident("array"), newIntLit(staticArgsLen), ident("pointer")), + newPNode(nkEmpty))) + argsAlloc.add(newCommand(ident("addr"), ident("argsStatic"))) + vars.add(newIdentDefs(argsName, newPNode(nkEmpty), argsAlloc)) + + let argConversions = newPNode(nkStmtList) + let destructors = newPNode(nkStmtList) + for idx, arg in meth.args: + var argName = if arg.kind == ArgKind.Bound: ident(boundArgName(idx)) + else: ident(arg.name) + if arg.kind == ArgKind.VarArgs: + argName = newPNode(nkBracketExpr).addChain( + ident(varargsName.get), + infix(ident("idx"), ident("-"), newIntLit(staticArgsLen))) + let argIdx = if arg.kind == ArgKind.VarArgs: ident("idx") else: newIntLit(idx) + let isStandardType = arg.typ in standardTypes + let isWrappedType = arg.typ in wrapperTypes + let convArg = + if varargsName.isSome: + let isAlreadyVariant = arg.typ == "Variant" + let variantIdent = if isAlreadyVariant: getInternalPtr(argName, "Variant") + else: ident("variant" & $idx) + if not isAlreadyVariant: + argConversions.add(newPNode(nkVarSection).addChain( + newIdentDefs(variantIdent, ident("GodotVariant"), newEmptyNode()) + )) + destructors.add( + newCall("deinit", variantIdent) + ) + if arg.typ in variantPrimitives: + argConversions.add( + newCall("initGodotVariant", variantIdent, argName) + ) + elif arg.typ in wrapperTypes or arg.typ == "Object": + argConversions.add( + newCall("initGodotVariant", variantIdent, getInternalPtr(argName, arg.typ)) + ) + elif arg.typ == "string": + let stringIdent = ident("variantString" & $idx) + argConversions.addChain( + newPNode(nkVarSection).addChain( + newIdentDefs(stringIdent, ident("GodotString"), newCall("toGodotString", argName)) + ) + ).addChain( + newCall("initGodotVariant", variantIdent, stringIdent) + ) + destructors.add(newCall("deinit", stringIdent)) + else: + raise newException(ValueError, + "Non-standard type $# for varargs params of method $# of type $#" % + [arg.typ, meth.godotName, meth.typ.godotName]) + + if isAlreadyVariant: variantIdent + else: newCall("addr", variantIdent) + elif isWrappedType: getInternalPtr(argName, arg.typ) + elif isStandardType: newCall("unsafeAddr", argName) + elif arg.typ == "string": newCall("unsafeAddr", + ident("argToPassToGodot" & $idx)) + else: ident("argToPassToGodot" & $idx) # object + if not isStandardType and arg.kind == ArgKind.VarArgs: + raise newException(ValueError, + "Non-standard type $# for varargs params of method $# of type $#" % + [arg.typ, meth.godotName, meth.typ.godotName]) + if not isStandardType and varargsName.isNone: + if arg.typ == "string": + argConversions.add(newPNode(nkVarSection).addChain( + newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(), + newCall("toGodotString", argName)))) + else: + let objVal = newIfStmt( + prefix("not", newDotExpr(argName, ident"isNil")), + newDotExpr(argName, ident("godotObject")) + ).addChain(newPNode(nkElse).addChain(newNilLit())) + argConversions.add(newPNode(nkLetSection).addChain( + newIdentDefs(ident("argToPassToGodot" & $idx), newEmptyNode(), objVal))) + let argAsgn = newPNode(nkAsgn).addChain( + newPNode(nkBracketExpr).addChain( + newPNode(nkBracketExpr).addChain(argsName), argIdx), + convArg + ) + if arg.kind != ArgKind.VarArgs: + argConversions.add( + argAsgn + ) + else: + argConversions.add(newPNode(nkVarSection).addChain( + newIdentDefs(ident("idx"), newPNode(nkEmpty), + newIntLit(staticArgsLen)))) + let argLoop = newPNode(nkWhileStmt) + argConversions.add(argLoop) + argLoop.add(infix(ident("idx"), ident("<"), argLenNode) + ) + argLoop.add(newPNode(nkStmtList).addChain( + argAsgn, + newCommand(ident("inc"), ident("idx")))) + + let retName = if isVarargs: "callRet" else: "ptrCallRet" + let theCall = newCall( + newDotExpr(ident(methodBindName), + ident(if isVarargs: "call" else: "ptrCall")), + newDotExpr(ident("self"), ident("godotObject")), + if meth.args.len > 0: argsName else: newPNode(nkNilLit), + argLenNode, + if not isVarargs: ident(retName) else: ident("callError") + ) + if not isVarargs: + theCall.sons.delete(3) + let freeCall = newCall("godotFree", argsName) + body = newPNode(nkStmtList) + if meth.typ.isSingleton: + let varName = singletonName(meth.typ.name) + body.add(newNilCheck(varName, newCall( + newBracketExpr(ident("getSingleton"), ident(meth.typ.name))))) + body.add(newPNode(nkLetSection).addChain(newIdentDefs( + ident("self"), newPNode(nkEmpty), varName + ))) + body.add(nilCheck) + body.add(vars) + body.add(argConversions) + if not isVarargs: + let retPtrDecl = newPNode(nkVarSection).addChain( + newIdentDefs(ident(retName), ident("pointer"), newEmptyNode()) + ) + body.add(retPtrDecl) + var isVariantRet: bool + var isConversionRet: bool + var isObjRet: bool + var isStringRet: bool + var isWrapperRet: bool + let retValIdent = if not isVarargs: ident("ptrCallVal") else: ident(retName) + if meth.returnType.isSome and not isVarargs: + let returnType = meth.returnType.get + var addrToAssign = newCall("addr", retValIdent) + if returnType in smallIntTypes: + isConversionRet = true + body.add(newPNode(nkVarSection).addChain(newIdentDefs( + retValIdent, ident("int64"), + ))) + elif returnType in float32Types: + isConversionRet = true + body.add(newPNode(nkVarSection).addChain(newIdentDefs( + retValIdent, ident("float64"), + ))) + elif returnType in wrapperTypes: + isWrapperRet = true + body.add(newPNode(nkVarSection).addChain(newIdentDefs( + retValIdent, ident("Godot" & returnType), + ))) + if returnType != "NodePath": + body.add(newCall("initGodot" & returnType, retValIdent)) + elif returnType in standardTypes: + addrToAssign = newCall("addr", ident("result")) + elif returnType == "string": + isStringRet = true + body.add(newPNode(nkVarSection).addChain(newIdentDefs( + retValIdent, ident("GodotString"), + ))) + elif returnType != "void": + isObjRet = true + body.add(newPNode(nkVarSection).addChain(newIdentDefs( + retValIdent, newPNode(nkPtrTy).addChain(ident("GodotObject")), + ))) + body.add(newPNode(nkAsgn).addChain(ident(retName), addrToAssign)) + + if not isVarargs: + body.add(theCall) + else: + if meth.returnType.isSome: + isVariantRet = true + let callStmt = newPNode(nkLetSection).addChain( + newIdentDefs( + newPNode(nkPragmaExpr).addChain( + ident(retName), newPNode(nkPragma).addChain(ident("used"))), + newPNode(nkEmpty), theCall)) + body.add(callStmt) + + if varargsName.isNone: + for idx, arg in meth.args: + if arg.typ == "string": + body.add(newCall("deinit", ident("argToPassToGodot" & $idx))) + + if varargsName.isSome: + if meth.args.len > 0: + body.add(freeCall) + body.add(destructors) + let errCheck = newIfStmt( + infix(newDotExpr(ident("callError"), ident("error")), ident("!="), + newDotExpr(ident("VariantCallErrorType"), ident("OK"))), + newPNode(nkRaiseStmt).addChain( + newCall("newCallError", ident("callError"))) + ) + body.add(errCheck) + if isVariantRet: + let convErrDef = newPNode(nkLetSection).addChain( + newIdentDefs(ident("convErr"), newPNode(nkEmpty), + newCall("fromVariant", ident("result"), + newCall("newVariant", retValIdent)))) + let convCheck = newIfStmt( + infix(ident("convErr"), ident("!="), + newDotExpr(ident("ConversionResult"), ident("OK"))), + newPNode(nkRaiseStmt).addChain( + newCall("newConversionError", ident("convErr"))) + ) + body.add(convErrDef) + body.add(convCheck) + if isStringRet: + body.add(newPNode(nkAsgn).addChain( + ident("result"), prefix("$", retValIdent))) + body.add(newCall("deinit", retValIdent)) + elif isConversionRet: + body.add(newPNode(nkAsgn).addChain( + ident("result"), + newCall(meth.returnType.get, retValIdent))) + elif isWrapperRet: + body.add(newPNode(nkAsgn).addChain( + ident("result"), + newCall("new" & meth.returnType.get, retValIdent))) + elif isObjRet: + body.add(newPNode(nkAsgn).addChain(ident("result"), + newCall(newBracketExpr(ident("asNimGodotObject"), + newCall("type", ident("result"))), + retValIdent, ident("false"), ident("true")))) + elif isStringRet: + body.add(newPNode(nkAsgn).addChain(ident("result"), + newCall("$", retValIdent))) + + let procType = if meth.isVirtual: nkMethodDef + else: nkProcDef + var params = newSeqOfCap[PNode](meth.args.len + 2) + if meth.returnType.isSome: + params.add(ident(meth.returnType.get)) + else: + params.add(newPNode(nkEmpty)) + if not meth.typ.isSingleton: + params.add(newIdentDefs(ident("self"), ident(toNimType(meth.typ.name)))) + + for arg in meth.args: + case arg.kind: + of ArgKind.Normal: + let defaultValue = arg.makeDefaultValue() + params.add(newIdentDefs(ident(arg.name), ident(arg.typ), defaultValue)) + of ArgKind.VarArgs: + params.add(newIdentDefs(ident(arg.name), + newPNode(nkBracketExpr).addChain(ident("varargs"), ident(arg.typ)))) + of ArgKind.Bound: + discard + + let procDecl = newProc(if not withImplementation: postfix(meth.name, "*") + else: meth.name, + params, body, procType) + if not withImplementation: + let pragma = newPNode(nkPragma) + pragma.add(ident("gcsafe")) + pragma.add(newPNode(nkExprColonExpr).addChain(ident("locks"), + newIntLit(0))) + if meth.isVirtual and meth.isBase and meth.typ.name != "PhysicsBody": + # Nim doesn't like `base` on PhysicsBody methods - wtf + pragma.add(ident("base")) + if meth.isDiscardable and meth.returnType.isSome: + pragma.add(ident("discardable")) + procDecl.sons[4] = pragma + tree.add(procDecl) + +proc generateMethod(tree: PNode, methodBindRegistry: var HashSet[string], + meth: MethodInfo, withImplementation: bool) = + doGenerateMethod(tree, methodBindRegistry, meth, withImplementation) + +proc getMethodInfo(methodObj: JsonNode, types: Table[string, GodotType], + typ: GodotType): MethodInfo = + var origArgs = methodObj["arguments"] + var isBase = methodObj["is_virtual"].bval + if methodObj["is_virtual"].bval: + proc getMethod(typNode: JsonNode, methName: string): JsonNode = + for meth in typNode["methods"]: + if meth["is_virtual"].bval and + meth["name"].str == methName: return meth + var curTyp = types.getOrDefault(typ.baseName) + while not curTyp.isNil: + let meth = curTyp.jsonNode.getMethod(methodObj["name"].str) + if not meth.isNil: + origArgs = meth["arguments"] + isBase = false + curTyp = types.getOrDefault(curTyp.baseName) + + var args = newSeqOfCap[MethodArg](methodObj["arguments"].len + 1) + for arg in origArgs: + let typ = toNimType(types, arg["type"].str) + let defaultVal = if arg["has_default_value"].bval: arg["default_value"] + else: nil + args.add(MethodArg( + name: toNimStyle(arg["name"].str), typ: typ, + defaultVal: defaultVal)) + if methodObj["has_varargs"].bval: + args.add(MethodArg(name: "variantArgs", typ: "Variant", kind: ArgKind.VarArgs)) + + let godotName = methodObj["name"].str + var nimName = toNimStyle(godotName) + if not godotName.startsWith('_'): + for meth in typ.jsonNode["methods"]: + if meth["name"].str == '_' & godotName: + nimName = nimName & "Impl" + + let returnType = if methodObj["return_type"].str != "void": + some(toNimType(types, methodObj["return_type"].str)) + else: none(string) + const discardableMethods = toHashSet(["emit_signal"]) + result = MethodInfo( + name: ident(nimName), + typ: typ, + godotName: methodObj["name"].str, + args: args, + returnType: returnType, + isVirtual: methodObj["is_virtual"].bval, + isBase: isBase, + isDiscardable: typ.godotName == "Object" and + methodObj["name"].str in discardableMethods + ) + +proc findMethod(obj: JsonNode, methName: string): JsonNode = + for meth in obj["methods"]: + if meth["name"].str == methName: + return meth + +proc makeProperty(types: Table[string, GodotType], tree: PNode, + methodBindRegistry: var HashSet[string], + typ: GodotType, propertyObj: JsonNode, obj: JsonNode, + withImplementation: bool) = + for meth in obj["methods"]: + if meth["name"].str == '_' & propertyObj["name"].str: + # Don't generate properties if there is a name clash - otherwise + # using the property would not compile due to ambiguity. + return + let getterNameStr = toNimStyle(propertyObj["name"].str) + let getterName = ident(getterNameStr) + let setterName = newPNode(nkAccQuoted).addChain(ident(getterNameStr & "=")) + + let getter = findMethod(obj, propertyObj["getter"].str) + let nimType = if getter.isNil: toNimType(types, propertyObj["type"].str) + else: getMethodInfo(getter, types, typ).returnType.get("void") + let getterInfo = MethodInfo( + name: getterName, + typ: typ, + godotName: propertyObj["getter"].str, + args: newSeq[MethodArg](), + returnType: some(nimType) + ) + let setterInfo = MethodInfo( + name: setterName, + typ: typ, + godotName: propertyObj["setter"].str, + args: @[MethodArg(name: "val", typ: nimType)] + ) + if "index" in propertyObj and propertyObj["index"] != newJInt(-1): + getterInfo.args = + @[MethodArg(defaultVal: newJString($propertyObj["index"]), + typ: "int", kind: ArgKind.Bound)] & getterInfo.args + setterInfo.args = + @[MethodArg(defaultVal: newJString($propertyObj["index"]), + typ: "int", kind: ArgKind.Bound)] & setterInfo.args + generateMethod(tree, methodBindRegistry, getterInfo, withImplementation) + generateMethod(tree, methodBindRegistry, setterInfo, withImplementation) + +proc makeMethod(types: Table[string, GodotType], tree: PNode, + methodBindRegistry: var HashSet[string], + typ: GodotType, methodObj: JsonNode, + withImplementation: bool) = + if not typ.isSingleton: + # for singletons we don't generate Nim setters/getters, + # but use plain procedures instead. That's because setter syntax is + # supposed to be used on an object (have at least 2 params). + for prop in typ.jsonNode["properties"]: + if prop["getter"].str == methodObj["name"].str or + prop["setter"].str == methodObj["name"].str: + var hasDuplicateMethod = false + for meth in typ.jsonNode["methods"]: + if meth["name"].str == '_' & prop["name"].str: + hasDuplicateMethod = true + break + if not hasDuplicateMethod: + return + + let methodInfo = getMethodInfo(methodObj, types, typ) + + generateMethod(tree, methodBindRegistry, methodInfo, withImplementation) + +proc addAttributeToDoc(doc: var string, propName, propValue: string) = + if doc.len > 0: + doc.add("\n") + doc.add(propName & ": " & propValue) + +const classAttributes = ["singleton", "instanciable", "is_reference"] + +proc typeNameToModuleName(name: string): string = + var wasUpperOrDigit = true + result = newStringOfCap(name.len + 10) + for idx, c in name: + if c.isUpperAscii() or c.isDigit(): + if not wasUpperOrDigit or idx > 0 and idx < name.len - 1 and + name[idx + 1].isLowerAscii(): + result.add('_') + result.add(c.toLowerAscii()) + wasUpperOrDigit = true + else: + result.add(c) + wasUpperOrDigit = false + if result == "object": + # keyword + result = "objects" + if result == "os": + # to avoid clash with stdlib + result = "gd_os" + +proc newRegisterClassNode(typ: GodotType): PNode = + newCall("registerClass", + ident(typ.name), + newStrLit(typ.godotName), + ident("true") # isNative + ) + +proc genSingletonDecl(typ: string): PNode = + result = newPNode(nkVarSection) + let name = singletonName(typ) + let threadvar = newPNode(nkPragma).addChain(ident("threadvar")) + result.add(newIdentDefs(newPNode(nkPragmaExpr).addChain(name, threadvar), + ident(typ))) + +proc shouldExport(typ: GodotType, types: Table[string, GodotType]): bool = + var curTyp = typ + while not curTyp.isNil and not curTyp.isSingleton: + curTyp = types.getOrDefault(curTyp.baseName) + result = curTyp.isNil + +proc sortByDerivedCount(types: Table[string, GodotType]): seq[GodotType] = + result = toSeq(types.values()) + result.sort do (x, y: GodotType) -> int: + cmp(y.derivedCount, x.derivedCount) + +proc genTypeFile(types: Table[string, GodotType], targetDir: string) = + let sortedTypes = sortByDerivedCount(types) + + let godotApiTypesTree = newPNode(nkStmtList) + godotApiTypesTree.add(newPNode(nkImportStmt).addChain(ident("godot"))) + let typeSection = newPNode(nkTypeSection) + godotApiTypesTree.add(typeSection) + + for typ in sortedTypes: + if not typ.shouldExport(types): continue + newRefTypeNode(typeSection, typ.name, typ.baseName, typ.doc) + + for typ in sortedTypes: + if not typ.shouldExport(types): continue + let regNode = newCall("registerClass", + ident(typ.name), + newStrLit(typ.godotName), + ident("true") # isNative + ) + godotApiTypesTree.add(regNode) + + writeFile(targetDir / "godottypes.nim", renderTree(godotApiTypesTree)) + +proc genSingletonWithDerived(tree: PNode, typ: GodotType, + types: Table[string, GodotType]) = + let sortedTypes = sortByDerivedCount(types) + + var parents = initHashSet[string]() + parents.incl(typ.name) + + let typeDecl = newPNode(nkTypeSection) + tree.add(typeDecl) + proc genDecl(typ: GodotType) = + newRefTypeNode(typeDecl, typ.name, typ.baseName, typ.doc, + isExported = false) + tree.add(newRegisterClassNode(typ)) + + genDecl(typ) + for otherType in sortedTypes: + if otherType.baseName in parents: + parents.incl(otherType.name) + genDecl(otherType) + + tree.add(genSingletonDecl(typ.name)) + +proc genApi*(targetDir: string, apiJsonFile: string) = + ## Generates .nim files in the ``targetDir`` based on the ``apiJsonFile``. + ## The JSON file can be generated by executing Godot with + ## ``--gdnative-generate-json-api `` parameters. + let apiJson = parseJson(newFileStream(apiJsonFile), + apiJsonFile.extractFilename()) + var megaImport = newStringOfCap(64 * 1024) + + var types = initTable[string, GodotType]() + for obj in apiJson: + let godotClassName = obj["name"].str + let className = godotClassName.replace("_", "") + var baseClassName = obj["base_class"].str + baseClassName = toNimType(baseClassName.replace("_", "")) + if baseClassName.len == 0: + baseClassName = "NimGodotObject" + var doc = "" + for attr in classAttributes: + if attr in obj: + addAttributeToDoc(doc, attr, $obj[attr]) + types[className] = GodotType( + name: className, + godotName: godotClassName, + baseName: baseClassName, + doc: doc, + jsonNode: obj, + isSingleton: obj["singleton"].bval + ) + + for typ in types.values(): + types.incDerivedCount(typ.baseName) + + for typ in types.values(): + let moduleName = typeNameToModuleName(typ.name) + echo "Generating ", moduleName, ".nim..." + let tree = newPNode(nkStmtList) + let importStmt = newPNode(nkImportStmt) + importStmt.add(ident("godot")) + importStmt.add(ident("godottypes")) + importStmt.add(ident("godotinternal")) + tree.add(importStmt) + let exportStmt = newPNode(nkExportStmt) + exportStmt.add(ident("godottypes")) + tree.add(exportStmt) + + var methodBindRegsitry = initHashSet[string]() + let obj = typ.jsonNode + if typ.baseName != "NimGodotObject": + let baseModule = typeNameToModuleName(typ.baseName) + let baseModuleNode = if getIdent(baseModule).isKeyword: + newStrLit(baseModule & ".nim") + else: + ident(baseModule) + importStmt.add(baseModuleNode) + exportStmt.add(baseModuleNode) + let constSection = makeConstSection(obj["constants"]) + if constSection.kind != nkEmpty: + # renderer doesn't properly render empty stmt after type section + tree.add(makeConstSection(obj["constants"])) + + if typ.isSingleton: + genSingletonWithDerived(tree, typ, types) + + if "enums" in obj: + # Quite often Godot enums are flags that need to be bitwise ORed + # Nim's enums don't serve well for that purpose, so we just generate + # integer constants. The only enum used in API is Error. + for enumDef in obj["enums"]: + let uniqueConstants = newJObject() + for k, v in enumDef["values"]: + if k notin obj["constants"]: + uniqueConstants[k] = v + if uniqueConstants.len > 0: + tree.add(makeConstSection(uniqueConstants)) + + # first, generate declarations only for ease of + # human readability of the file + if not typ.isSingleton: + for property in obj["properties"]: + makeProperty(types, tree, methodBindRegsitry, typ, property, + obj, withImplementation = false) + for meth in obj["methods"]: + makeMethod(types, tree, methodBindRegsitry, typ, + meth, withImplementation = false) + + if not typ.isSingleton: + for property in obj["properties"]: + makeProperty(types, tree, methodBindRegsitry, typ, + property, obj, withImplementation = true) + for meth in obj["methods"]: + makeMethod(types, tree, methodBindRegsitry, typ, meth, + withImplementation = true) + + writeFile(targetDir / moduleName & ".nim", renderTree(tree)) + + megaImport.add("import \"" & moduleName & "\"\n") + + genTypeFile(types, targetDir) + + writeFile(targetDir / "godotall.nim", megaImport) + writeFile(targetDir / splitPath(targetDir)[1] & ".nimble", "") + +when isMainModule: + import os + + const usage = """Tool for wrapping Godot API into Nim + godotapigen [godot binary path] [target directory]""" + + proc main() = + if paramCount() < 2: + echo usage + quit(-1) + let godotBin = paramStr(1) + let targetDir = paramStr(2) + + if not dirExists(targetDir): + echo "The specified directory does not exist" + quit(-1) + if not fileExists(godotBin): + echo "Invalid godot binary path" + quit(-1) + + let jsonFile = targetDir / "api.json" + if fileExists(jsonFile) and + godotBin.getLastModificationTime() <= jsonFile.getLastModificationTime(): + echo "api.json is up to date - doing nothing." + return + + discard execShellCmd( + "\"" & godotBin & "\" --gdnative-generate-json-api \"" & jsonFile & "\"") + if not fileExists(jsonFile): + echo "Failed to generate api.json" + quit(-1) + + genApi(targetDir, jsonFile) + + main() \ No newline at end of file diff --git a/godot/godotinternal.nim b/godot/godotinternal.nim index f2652ec..207d76f 100644 --- a/godot/godotinternal.nim +++ b/godot/godotinternal.nim @@ -1,262 +1,85 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. -import internal / [ - godotinternaltypes, godotarrays, godotnodepaths, godotpoolarrays, - godotstrings, godotvariants, godotdictionaries] +import internal/godotinternaltypes, internal/godotarrays, + internal/godotnodepaths, internal/godotpoolarrays, internal/godotstrings, + internal/godotvariants, internal/godotdictionaries +import gdnativeapi export godotinternaltypes, godotarrays, godotnodepaths, godotpoolarrays, godotstrings, godotvariants, godotdictionaries -const MAX_ARG_COUNT* = 128 +proc getMethod*(className: cstring; + methodName: cstring): ptr GodotMethodBind {.inline.} = + getGDNativeAPI().methodBindGetMethod(className, methodName) -# MethodBind API - -type GodotMethodBind* = object - -proc getMethod*(className: cstring; methodName: cstring): ptr GodotMethodBind {. - importc: "godot_method_bind_get_method".} proc ptrCall*(methodBind: ptr GodotMethodBind; instance: ptr GodotObject; args: ptr array[MAX_ARG_COUNT, pointer]; - ret: pointer) {. - importc: "godot_method_bind_ptrcall".} + ret: pointer) {.inline.} = + getGDNativeAPI().methodBindPtrCall(methodBind, instance, args, ret) + proc call*(methodBind: ptr GodotMethodBind; instance: ptr GodotObject; args: ptr array[MAX_ARG_COUNT, ptr GodotVariant]; argCount: cint; - callError: var VariantCallError): GodotVariant {. - importc: "godot_method_bind_call".} + callError: var VariantCallError): GodotVariant {.inline.} = + getGDNativeAPI().methodBindCall( + methodBind, instance, args, argCount, callError) -# Script API +proc nativeScriptRegisterClass*(libHandle: pointer; name, base: cstring; + createFunc: GodotInstanceCreateFunc; + destroyFunc: GodotInstanceDestroyFunc) + {.inline.} = + getGDNativeAPI().nativeScriptRegisterClass( + libHandle, name, base, createFunc, destroyFunc) -type - GodotNativeInitOptions* = object - inEditor*: bool - coreApiHash*: uint64 - editorApiHash*: uint64 - noApiHash*: uint64 - gdNativeLibrary*: ptr GodotObject +proc nativeScriptRegisterToolClass*(libHandle: pointer; name, base: cstring; + createFunc: GodotInstanceCreateFunc; + destroyFunc: GodotInstanceDestroyFunc) + {.inline.} = + getGDNativeAPI().nativeScriptRegisterToolClass( + libHandle, name, base, createFunc, destroyFunc) - GodotNativeTerminateOptions* = object - inEditor*: bool +proc nativeScriptRegisterMethod*(libHandle: pointer; + name: cstring; function_name: cstring; + attr: GodotMethodAttributes; + meth: GodotInstanceMethod) {.inline.} = + getGDNativeAPI().nativeScriptRegisterMethod( + libHandle, name, functionName, attr, meth) - GodotMethodRPCMode* {.size: sizeof(cint), pure.} = enum - Disabled, - Remote, - Sync, - Master, - Slave +proc nativeScriptRegisterProperty*(libHandle: pointer; + name, path: cstring; + attr: ptr GodotPropertyAttributes; + setFunc: GodotPropertySetFunc; + getFunc: GodotPropertyGetFunc) {.inline.} = + getGDNativeAPI().nativeScriptRegisterProperty( + libHandle, name, path, attr, setFunc, getFunc) - GodotMethodAttributes* = object - rpcMode*: GodotMethodRPCMode +proc nativeScriptRegisterSignal*(libHandle: pointer; name: cstring; + signal: GodotSignal) {.inline.} = + getGDNativeAPI().nativeScriptRegisterSignal(libHandle, name, signal) - GodotPropertyHint* {.size: sizeof(cint), pure.} = enum - None, ## no hint provided. - Range, ## hint_text = "min,max,step,slider; // slider is optional" - ExpRange, ## hint_text = "min,max,step", exponential edit - Enum, ## hint_text= "val1,val2,val3,etc" - ExpEasing, ## exponential easing funciton (Math::ease) - Length, ## hint_text= "length" (as integer) - SpriteFrame, - KeyAccel, ## hint_text= "length" (as integer) - Flags, ## hint_text= "flag1,flag2,etc" (as bit flags) - Layers2DRender, - Layers2DPhysics, - Layers3DRender, - Layers3DPhysics, - File, ## a file path must be passed, hint_text (optionally) - ## is a filter "*.png,*.wav,*.doc," - Dir, ## a directort path must be passed - GlobalFile, ## a file path must be passed, hint_text (optionally) is a - ## filter "*.png,*.wav,*.doc," - GlobalDir, ## a directort path must be passed - ResourceType, ## a resource object type - MultilineText, ## used for string properties that can contain multiple lines - ColorNoAlpha, ## used for ignoring alpha component when editing a color - ImageCompressLossy, - ImageCompressLossless, - ObjectId, - TypeString, ## a type string, the hint is the base type to choose - NodePathToEditedNode, ## so something else can provide this - ## (used in scripts) - MethodOfVariantType, ## a method of a type - MethodOfBaseType, ## a method of a base type - MethodOfInstance, ## a method of an instance - MethodOfScript, ## a method of a script & base - PropertyOfVariantType, ## a property of a type - PropertyOfBaseType, ## a property of a base type - PropertyOfInstance, ## a property of an instance - PropertyOfScript, ## a property of a script & base - PropertyHintMax +proc getUserdata*(instance: ptr GodotObject): pointer {.inline.} = + getGDNativeAPI().nativeScriptGetUserdata(instance) -const - GODOT_PROPERTY_USAGE_STORAGE_VALUE = 1.cint - GODOT_PROPERTY_USAGE_EDITOR_VALUE = 2.cint - GODOT_PROPERTY_USAGE_NETWORK_VALUE = 4.cint - GODOT_PROPERTY_USAGE_EDITOR_HELPER_VALUE = 8.cint - GODOT_PROPERTY_USAGE_CHECKABLE_VALUE = 16.cint - GODOT_PROPERTY_USAGE_CHECKED_VALUE = 32.cint - GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE = 64.cint - GODOT_PROPERTY_USAGE_GROUP_VALUE = 128.cint - GODOT_PROPERTY_USAGE_CATEGORY_VALUE = 256.cint - GODOT_PROPERTY_USAGE_STORE_IF_NONZERO_VALUE = 512.cint - GODOT_PROPERTY_USAGE_STORE_IF_NONONE_VALUE = 1024.cint - GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE_VALUE = 2048.cint - GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED_VALUE = 4096.cint - GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE_VALUE = 8192.cint - GODOT_PROPERTY_USAGE_STORE_IF_NULL_VALUE = 16384.cint - GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER_VALUE = 32768.cint - GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED_VALUE = 65536.cint +proc getClassConstructor*(className: cstring): GodotClassConstructor + {.inline.} = + getGDNativeAPI().getClassConstructor(className) - GODOT_PROPERTY_USAGE_DEFAULT_VALUE: cint = - GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_EDITOR_VALUE or - GODOT_PROPERTY_USAGE_NETWORK_VALUE - GODOT_PROPERTY_USAGE_DEFAULT_INTL_VALUE: cint = - GODOT_PROPERTY_USAGE_STORAGE_VALUE or - GODOT_PROPERTY_USAGE_EDITOR_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE or - GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE - GODOT_PROPERTY_USAGE_NOEDITOR_VALUE: cint = - GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE - -type - GodotPropertyUsageFlags* {.size: sizeof(cint), pure.} = enum - Storage = GODOT_PROPERTY_USAGE_STORAGE_VALUE - Editor = GODOT_PROPERTY_USAGE_EDITOR_VALUE - Network = GODOT_PROPERTY_USAGE_NETWORK_VALUE - NoEditor = GODOT_PROPERTY_USAGE_NOEDITOR_VALUE - Default = GODOT_PROPERTY_USAGE_DEFAULT_VALUE - EditorHelper = GODOT_PROPERTY_USAGE_EDITOR_HELPER_VALUE - Checkable = GODOT_PROPERTY_USAGE_CHECKABLE_VALUE - ## used for editing global variables - Checked = GODOT_PROPERTY_USAGE_CHECKED_VALUE - ## used for editing global variables - Internationalized = GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE - ## hint for internationalized strings - DefaultIntl = GODOT_PROPERTY_USAGE_DEFAULT_INTL_VALUE - Group = GODOT_PROPERTY_USAGE_GROUP_VALUE - ## used for grouping props in the editor - Category = GODOT_PROPERTY_USAGE_CATEGORY_VALUE - NonZero = GODOT_PROPERTY_USAGE_STORE_IF_NONZERO_VALUE - ## only store if nonzero - NonOne = GODOT_PROPERTY_USAGE_STORE_IF_NONONE_VALUE - ## only store if false - NoInstanceState = GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE_VALUE - RestartIfChanged = GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED_VALUE - ScriptVariable = GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE_VALUE - StoreIfNull = GODOT_PROPERTY_USAGE_STORE_IF_NULL_VALUE - AnimateAsTrigger = GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER_VALUE - UpdateAllIfModified = GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED_VALUE - - GodotPropertyAttributes* {.bycopy.} = object - rsetType*: GodotMethodRPCMode - typ*: cint - hint*: GodotPropertyHint - hintString*: GodotString - usage*: GodotPropertyUsageFlags - defaultValue*: GodotVariant - - GodotInstanceCreateFunc* {.bycopy.} = object - createFunc*: - proc (obj: ptr GodotObject; methodData: pointer): pointer {.noconv.} - ## returns user data - methodData*: pointer - freeFunc*: proc (a2: pointer) {.noconv.} - - GodotInstanceDestroyFunc* {.bycopy.} = object - destroyFunc*: - proc (obj: ptr GodotObject; methodData: pointer; - userData: pointer) {.noconv.} - methodData*: pointer - freeFunc*: proc (a2: pointer) {.noconv.} - -proc godotScriptRegisterClass*(libHandle: pointer; name, base: cstring; - create_func: GodotInstanceCreateFunc; - destroy_func: GodotInstanceDestroyFunc) {. - importc: "godot_nativescript_register_class".} -proc godotScriptRegisterToolClass*(libHandle: pointer; name, base: cstring; - createFunc: GodotInstanceCreateFunc; - destroyFunc: GodotInstanceDestroyFunc) {. - importc: "godot_nativescript_register_tool_class".} -type - GodotInstanceMethod* {.bycopy.} = object - meth*: - proc (obj: ptr GodotObject; methodData: pointer; - userData: pointer; numArgs: cint; - args: var array[MAX_ARG_COUNT, ptr GodotVariant]): - GodotVariant {.noconv.} - methodData*: pointer - freeFunc*: proc (a2: pointer) {.noconv.} - -proc godotScriptRegisterMethod*(libHandle: pointer; - name: cstring; function_name: cstring; - attr: GodotMethodAttributes; - meth: GodotInstanceMethod) {. - importc: "godot_nativescript_register_method".} -type - GodotPropertySetFunc* {.bycopy.} = object - setFunc*: proc (obj: ptr GodotObject; methodData: pointer; - userData: pointer; value: GodotVariant) {.noconv.} - methodData*: pointer - freeFunc*: proc (a2: pointer) {.noconv.} - - GodotPropertyGetFunc* {.bycopy.} = object - getFunc*: proc (obj: ptr GodotObject; methodData: pointer; - userData: pointer): GodotVariant {.noconv.} - methodData*: pointer - freeFunc*: proc (a2: pointer) {.noconv.} - -proc godotScriptRegisterProperty*(libHandle: pointer; - name: cstring; path: cstring; - attr: var GodotPropertyAttributes; - setFunc: GodotPropertySetFunc; - getFunc: GodotPropertyGetFunc) {. - importc: "godot_nativescript_register_property".} - -type - GodotSignalArgument* {.bycopy.} = object - name*: GodotString - typ*: cint - hint*: GodotPropertyHint - hintString*: GodotString - usage*: GodotPropertyUsageFlags - defaultValue*: GodotVariant - - GodotSignal* = object - name*: GodotString - numArgs*: cint - args*: ptr GodotSignalArgument - numDefaultArgs*: cint - defaultArgs*: ptr GodotVariant - - -proc godotScriptRegisterSignal*(libHandle: pointer; name: cstring; - signal: GodotSignal) {. - importc: "godot_nativescript_register_signal".} - -proc getUserdata*(instance: ptr GodotObject): pointer {. - importc: "godot_nativescript_get_userdata".} - -type ClassConstructor = proc (): ptr GodotObject {.noconv.} -proc getClassConstructor*(className: cstring): ClassConstructor {. - importc: "godot_get_class_constructor".} - -proc godotStackBottom*(): pointer {. - importc: "godot_get_stack_bottom".} - -proc deinit*(o: ptr GodotObject) {. - importc: "godot_object_destroy".} +proc deinit*(o: ptr GodotObject) {.inline.} = + getGDNativeAPI().objectDestroy(o) # print using Godot's error handler list -proc godotPrintError*(description: cstring; function: cstring; file: cstring; - line: cint) {. - importc: "godot_print_error".} +proc godotPrintError*(description, function, file: cstring; + line: cint) {.inline.} = + getGDNativeAPI().printError(description, function, file, line) -proc godotPrintWarning*(description: cstring; function: cstring; - file: cstring; line: cint) {. - importc: "godot_print_warning".} +proc godotPrintWarning*(description, function, file: cstring; + line: cint) {.inline.} = + getGDNativeAPI().printWarning(description, function, file, line) -proc godotPrint*(message: GodotString) {. - importc: "godot_print".} +proc godotPrint*(message: GodotString) {.inline.} = + getGDNativeAPI().print(message) var getClassMethodBind: ptr GodotMethodBind proc getClassName*(o: ptr GodotObject): string = @@ -269,3 +92,31 @@ proc getClassName*(o: ptr GodotObject): string = if result.len > 2 and result[^2] == 'S' and result[^1] == 'W': # There are physics type not known by ClassDB result = result[0..result.len-3] + +proc getClassNameRaw*(o: ptr GodotObject): GodotString = + if getClassMethodBind.isNil: + getClassMethodBind = getMethod(cstring"Object", cstring"get_class") + getClassMethodBind.ptrCall(o, nil, addr result) + +proc getGodotSingleton*(name: cstring): ptr GodotObject {.inline.} = + getGDNativeAPI().globalGetSingleton(name) + +# System Functions + +proc godotAlloc*(bytes: cint): pointer {.inline.} = + ## Allocates the specified number of bytes. + ## Using this instead of stdlib proc will help Godot track how much memory + ## is in use in debug mode. + getGDNativeAPI().alloc(bytes) + +proc godotRealloc*(p: pointer; bytes: cint): pointer {.inline.} = + ## Reallocates the pointer for the specified number of bytes. + ## Using this instead of stdlib proc will help Godot track how much memory + ## is in use in debug mode. + getGDNativeAPI().realloc(p, bytes) + +proc godotFree*(p: pointer) {.inline.} = + ## Frees the memory pointed to by the pointer. + ## Using this instead of stdlib proc will help Godot track how much memory + ## is in use in debug mode. + getGDNativeAPI().free(p) diff --git a/godot/internal/backwardcompat.inc.nim b/godot/internal/backwardcompat.inc.nim new file mode 100644 index 0000000..9d31844 --- /dev/null +++ b/godot/internal/backwardcompat.inc.nim @@ -0,0 +1,19 @@ +# Copyright 2019 Xored Software, Inc. + +when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + import macros, sets + + proc strVal(n: NimNode): string {.used.} = + case n.kind + of nnkIdent: + $n.ident + of nnkSym: + $n.symbol + else: + macros.strVal(n) + + proc toHashSet[A](keys: openArray[A]): HashSet[A] {.inline, used.} = + toSet(keys) + + proc initHashSet[A](): HashSet[A] {.inline, used.} = + initSet[A]() diff --git a/godot/internal/godotarrays.nim b/godot/internal/godotarrays.nim index c74a9ff..c7e451d 100644 --- a/godot/internal/godotarrays.nim +++ b/godot/internal/godotarrays.nim @@ -1,115 +1,162 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. + +import godotinternaltypes, gdnativeapi, core/godotcoretypes + +proc len*(self: GodotArray): cint {.inline.} = + getGDNativeAPI().arraySize(self) import hashes -import godotinternaltypes, godotpoolarrays, godotvariants, godotstrings -proc initGodotArray*(dest: var GodotArray) {. - importc: "godot_array_new".} -proc initGodotArray*(dest: var GodotArray; pca: GodotPoolColorArray) {. - importc: "godot_array_new_pool_coloarray".} -proc initGodotArray*(dest: var GodotArray; pv3a: GodotPoolVector3Array) {. - importc: "godot_array_new_pool_vector3_array".} -proc initGodotArray*(dest: var GodotArray; pv2a: GodotPoolVector2Array) {. - importc: "godot_array_new_pool_vector2_array".} -proc initGodotArray*(dest: var GodotArray; psa: GodotPoolStringArray) {. - importc: "godot_array_new_pool_string_array".} -proc initGodotArray*(dest: var GodotArray; pra: GodotPoolRealArray) {. - importc: "godot_array_new_pool_real_array".} -proc initGodotArray*(dest: var GodotArray; pia: GodotPoolIntArray) {. - importc: "godot_array_new_pool_int_array".} -proc initGodotArray*(dest: var GodotArray; pba: GodotPoolByteArray) {. - importc: "godot_array_new_pool_byte_array".} -proc iniGodotArray*(dest: var GodotArray; src: GodotArray) {. - importc: "godot_array_new_copy".} +proc initGodotArray*(dest: var GodotArray) {.inline.} = + getGDNativeAPI().arrayNew(dest) -proc deinit*(self: var GodotArray) {.importc: "godot_array_destroy".} +proc initGodotArray*(dest: var GodotArray; + pca: GodotPoolColorArray) {.inline.} = + getGDNativeAPI().arrayNewPoolColorArray(dest, pca) -proc `[]=`*(self: var GodotArray; idx: cint; - value: GodotVariant) {. - noSideEffect, - importc: "godot_array_set".} -proc `[]`*(self: GodotArray; idx: cint): GodotVariant {. - noSideEffect, - importc: "godot_array_get".} -proc mget*(self: var GodotArray; idx: cint): ptr GodotVariant {. - importc: "godot_array_operator_index".} +proc initGodotArray*(dest: var GodotArray; + pv3a: GodotPoolVector3Array) {.inline.} = + getGDNativeAPI().arrayNewPoolVector3Array(dest, pv3a) + +proc initGodotArray*(dest: var GodotArray; + pv2a: GodotPoolVector2Array) {.inline.} = + getGDNativeAPI().arrayNewPoolVector2Array(dest, pv2a) + +proc initGodotArray*(dest: var GodotArray; + psa: GodotPoolStringArray) {.inline.} = + getGDNativeAPI().arrayNewPoolStringArray(dest, psa) + +proc initGodotArray*(dest: var GodotArray; + pra: GodotPoolRealArray) {.inline.} = + getGDNativeAPI().arrayNewPoolRealArray(dest, pra) + +proc initGodotArray*(dest: var GodotArray; + pia: GodotPoolIntArray) {.inline.} = + getGDNativeAPI().arrayNewPoolIntArray(dest, pia) + +proc initGodotArray*(dest: var GodotArray; + pba: GodotPoolByteArray) {.inline.} = + getGDNativeAPI().arrayNewPoolByteArray(dest, pba) + +proc initGodotArray*(dest: var GodotArray; src: GodotArray) {.inline.} = + getGDNativeAPI().arrayNewCopy(dest, src) + +proc deinit*(self: var GodotArray) {.inline.} = + getGDNativeAPI().arrayDestroy(self) + +proc `[]=`*(self: var GodotArray; idx: cint; value: GodotVariant) {.inline.} = + getGDNativeAPI().arraySet(self, idx, value) + +proc `[]`*(self: GodotArray; idx: cint): GodotVariant {.inline.} = + getGDNativeAPI().arrayGet(self, idx) + +proc mget*(self: var GodotArray; idx: cint): ptr GodotVariant {.inline.} = + getGDNativeAPI().arrayOperatorIndex(self, idx) + +proc add*(self: var GodotArray; value: GodotVariant) {.inline.} = + getGDNativeAPI().arrayPushBack(self, value) + +proc clear*(self: var GodotArray) {.inline.} = + getGDNativeAPI().arrayClear(self) + +proc count*(self: GodotArray; value: GodotVariant): cint {.inline.} = + getGDNativeAPI().arrayCount(self, value) + +proc isEmpty*(self: GodotArray): bool {.inline.} = + getGDNativeAPI().arrayEmpty(self) + +proc erase*(self: var GodotArray; value: GodotVariant) {.inline.} = + getGDNativeAPI().arrayErase(self, value) + +proc first*(self: GodotArray): GodotVariant {.inline.} = + getGDNativeAPI().arrayFront(self) + +proc last*(self: GodotArray): GodotVariant {.inline.} = + getGDNativeAPI().arrayBack(self) -proc add*(self: var GodotArray; value: GodotVariant) {. - noSideEffect, - importc: "godot_array_append".} -proc clear*(self: var GodotArray) {.importc: "godot_array_clear".} -proc count*(self: GodotArray; value: GodotVariant): cint {. - noSideEffect, - importc: "godot_array_count".} -proc isEmpty*(self: GodotArray): bool {. - noSideEffect, - importc: "godot_array_empty".} -proc erase*(self: var GodotArray; value: GodotVariant) {. - importc: "godot_array_erase".} -proc first*(self: GodotArray): GodotVariant {. - noSideEffect, - importc: "godot_array_front".} -proc last*(self: GodotArray): GodotVariant {. - noSideEffect, - importc: "godot_array_back".} proc find*(self: GodotArray; what: GodotVariant; - f: cint): cint {. - noSideEffect, - importc: "godot_array_find".} -proc findLast*(self: GodotArray; what: GodotVariant): cint {. - noSideEffect, - importc: "godot_array_find_last".} -proc contains*(self: GodotArray; value: GodotVariant): bool {. - noSideEffect, - importc: "godot_array_has".} + fromIdx: cint): cint {.inline.} = + getGDNativeAPI().arrayFind(self, what, fromIdx) + +proc findLast*(self: GodotArray; what: GodotVariant): cint {.inline.} = + getGDNativeAPI().arrayFindLast(self, what) + +proc contains*(self: GodotArray; value: GodotVariant): bool {.inline.} = + getGDNativeAPI().arrayHas(self, value) + +proc godotHash*(self: GodotArray): cint {.inline.} = + getGDNativeAPI().arrayHash(self) -proc godotHash*(self: GodotArray): cint {. - noSideEffect, - importc: "godot_array_hash".} proc hash*(self: GodotArray): Hash {.inline.} = hash(godotHash(self)) proc insert*(self: var GodotArray; pos: cint; - value: GodotVariant) {. - importc: "godot_array_insert".} -proc reverse*(self: var GodotArray) {.importc: "godot_array_invert".} -proc popLast*(self: var GodotArray): GodotVariant {. - importc: "godot_array_pop_back".} -proc popFirst*(self: var GodotArray): GodotVariant {. - importc: "godot_array_pop_front".} -proc addLast*(self: var GodotArray; value: GodotVariant) {. - importc: "godot_array_push_back".} -proc addFirst*(self: var GodotArray; value: GodotVariant) {. - importc: "godot_array_push_front".} + value: GodotVariant): Error {.discardable, inline.} = + getGDNativeAPI().arrayInsert(self, pos, value) + +proc reverse*(self: var GodotArray) {.inline.} = + getGDNativeAPI().arrayInvert(self) + +proc popLast*(self: var GodotArray): GodotVariant {.inline.} = + getGDNativeAPI().arrayPopBack(self) + +proc popFirst*(self: var GodotArray): GodotVariant {.inline.} = + getGDNativeAPI().arrayPopFront(self) + +proc addLast*(self: var GodotArray; value: GodotVariant) {.inline.} = + getGDNativeAPI().arrayPushBack(self, value) + +proc addFirst*(self: var GodotArray; value: GodotVariant) {.inline.} = + getGDNativeAPI().arrayPushFront(self, value) + +proc delete*(self: var GodotArray; idx: cint) {.inline.} = + getGDNativeAPI().arrayRemove(self, idx) + +proc setLen*(self: var GodotArray; size: cint) {.inline.} = + getGDNativeAPI().arrayResize(self, size) -proc delete*(self: var GodotArray; idx: cint) {. - importc: "godot_array_remove".} -proc setLen*(self: var GodotArray; size: cint) {. - importc: "godot_array_resize".} proc rfind*(self: GodotArray; what: GodotVariant; - f: cint): cint {. - noSideEffect, - importc: "godot_array_rfind".} -proc len*(self: GodotArray): cint {. - noSideEffect, - importc: "godot_array_size".} -proc sort*(self: var GodotArray) {.importc: "godot_array_sort".} -proc sortCustom*(self: var GodotArray; obj: var GodotObject; - funcName: GodotString) {. - importc: "godot_array_sort_custom".} + fromIdx: cint): cint {.inline.} = + getGDNativeAPI().arrayRFind(self, what, fromIdx) -iterator items*(arr: GodotArray): GodotVariant = - for i in 0.. 1: + result.add(", ") + result.add($item) + result.add(']') diff --git a/godot/internal/godotdictionaries.nim b/godot/internal/godotdictionaries.nim index 715b030..447647a 100644 --- a/godot/internal/godotdictionaries.nim +++ b/godot/internal/godotdictionaries.nim @@ -1,48 +1,56 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. -type - GodotDictionary* {.byref.} = object - p: pointer +import godotinternaltypes, gdnativeapi -import godotinternaltypes, godotarrays, godotvariants, godotstrings +proc initGodotDictionary*(dest: var GodotDictionary) {.inline.} = + getGDNativeAPI().dictionaryNew(dest) -proc initGodotDictionary*(dest: var GodotDictionary; src: GodotDictionary) {. - importc: "godot_dictionary_new_copy".} +proc initGodotDictionary*(dest: var GodotDictionary; + src: GodotDictionary) {.inline.} = + getGDNativeAPI().dictionaryNewCopy(dest, src) -proc deinit*(self: var GodotDictionary) {. - importc: "godot_dictionary_destroy".} +proc deinit*(self: var GodotDictionary) {.inline.} = + getGDNativeAPI().dictionaryDestroy(self) -proc initGodotDictionary*(dest: var GodotDictionary) {. - importc: "godot_dictionary_new".} +proc len*(self: GodotDictionary): cint {.inline.} = + getGDNativeAPI().dictionarySize(self) -proc len*(self: GodotDictionary): cint {. - importc: "godot_dictionary_size".} -proc isEmpty*(self: GodotDictionary): bool {. - importc: "godot_dictionary_empty".} -proc clear*(self: var GodotDictionary) {. - importc: "godot_dictionary_clear".} -proc contains*(self: GodotDictionary; key: GodotVariant): bool {. - importc: "godot_dictionary_has".} -proc contains*(self: GodotDictionary; keys: GodotArray): bool {. - importc: "godot_dictionary_has_all".} -proc del*(self: var GodotDictionary; key: GodotVariant) {. - importc: "godot_dictionary_erase".} +proc isEmpty*(self: GodotDictionary): bool {.inline.} = + getGDNativeAPI().dictionaryEmpty(self) -proc godotHash*(self: GodotDictionary): cint {. - importc: "godot_dictionary_hash".} -proc keys*(self: GodotDictionary): GodotArray {. - importc: "godot_dictionary_keys".} -proc values*(self: GodotDictionary): GodotArray {. - importc: "godot_dictionary_values".} -proc `[]`*(self: GodotDictionary; key: GodotVariant): GodotVariant {. - importc: "godot_dictionary_get".} -proc `[]=`*(self: var GodotDictionary; key, value: GodotVariant) {. - importc: "godot_dictionary_set".} -proc mget*(self: var GodotDictionary; key: GodotVariant): ptr GodotVariant {. - importc: "godot_dictionary_operator_index".} +proc clear*(self: var GodotDictionary) {.inline.} = + getGDNativeAPI().dictionaryClear(self) -proc `==`*(self, other: GodotDictionary): bool {. - importc: "godot_dictionary_operator_equal".} +proc contains*(self: GodotDictionary; key: GodotVariant): bool {.inline.} = + getGDNativeAPI().dictionaryHas(self, key) -proc toJson*(self: GodotDictionary): GodotString {. - importc: "godot_dictionary_to_json".} +proc contains*(self: GodotDictionary; keys: GodotArray): bool {.inline.} = + getGDNativeAPI().dictionaryHasAll(self, keys) + +proc del*(self: var GodotDictionary; key: GodotVariant) {.inline.} = + getGDNativeAPI().dictionaryErase(self, key) + +proc godotHash*(self: GodotDictionary): cint {.inline.} = + getGDNativeAPI().dictionaryHash(self, ) + +proc keys*(self: GodotDictionary): GodotArray {.inline.} = + getGDNativeAPI().dictionaryKeys(self) + +proc values*(self: GodotDictionary): GodotArray {.inline.} = + getGDNativeAPI().dictionaryValues(self) + +proc `[]`*(self: GodotDictionary; key: GodotVariant): GodotVariant {.inline.} = + getGDNativeAPI().dictionaryGet(self, key) + +proc `[]=`*(self: var GodotDictionary; key, value: GodotVariant) {.inline.} = + getGDNativeAPI().dictionarySet(self, key, value) + +proc mget*(self: var GodotDictionary; + key: GodotVariant): ptr GodotVariant {.inline.} = + getGDNativeAPI().dictionaryOperatorIndex(self, key) + +proc `==`*(self, other: GodotDictionary): bool {.inline.} = + getGDNativeAPI().dictionaryOperatorEqual(self, other) + +proc toJson*(self: GodotDictionary): GodotString {.inline.} = + getGDNativeAPI().dictionaryToJson(self) diff --git a/godot/internal/godotinternaltypes.nim b/godot/internal/godotinternaltypes.nim index 8ccbc06..a2910c9 100644 --- a/godot/internal/godotinternaltypes.nim +++ b/godot/internal/godotinternaltypes.nim @@ -1,8 +1,313 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. + +const MAX_ARG_COUNT* = 256 type - GodotObject* = object GodotArray* {.byref.} = object - p: pointer + data: array[sizeof(int), byte] + + GodotDictionary* {.byref.} = object + data: array[sizeof(int), byte] + + GodotNodePath* {.byref.} = object + data: array[sizeof(int), byte] + + GodotObject* = object + + GodotPoolByteArray* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolByteArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolByteArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolIntArray* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolIntArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolIntArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolRealArray* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolRealArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolRealArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolStringArray* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolStringArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolStringArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolVector2Array* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolVector2ArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolVector2ArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolVector3Array* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolVector3ArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolVector3ArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotPoolColorArray* {.byref.} = object + data: array[sizeof(int), byte] + GodotPoolColorArrayReadAccess* {.byref.} = object + data: array[1, byte] + GodotPoolColorArrayWriteAccess* {.byref.} = object + data: array[1, byte] + + GodotString* {.byref.} = object + data: array[sizeof(int), byte] + + cwchar_t* {.importc: "wchar_t", nodecl.} = object + + GodotCharString* {.byref.} = object + data: array[sizeof(int), byte] + + VariantType* {.size: sizeof(cint), pure.} = enum + Nil, ## atomic types + Bool, + Int, + Real, + String, + # math types + Vector2, ## 5 + Rect2, + Vector3, + Transform2D, + Plane, + Quat, ## 10 + AABB, + Basis, + Transform, ## misc types + Color, + NodePath, ## 15 + RID, + Object, + Dictionary, + Array, ## 20 + # arrays + PoolByteArray, + PoolIntArray, + PoolRealArray, + PoolStringArray, + PoolVector2Array, ## 25 + PoolVector3Array, + PoolColorArray + + VariantCallErrorType* {.size: sizeof(cint), pure.} = enum + OK, + InvalidMethod, + InvalidArgument, + TooManyArguments, + TooFewArguments, + InstanceIsNull + + VariantCallError* = object + error*: VariantCallErrorType + argument*: cint + expected*: VariantType + GodotVariant* {.byref.} = object - data: array[24, byte] \ No newline at end of file + data: array[2, int64] + data2: int + +type GodotMethodBind* = object + +type + GDNativeAPIVersion* = object + major*: cuint + minor*: cuint + + GDNativeInitOptions* = object + inEditor*: bool + coreApiHash*: uint64 + editorApiHash*: uint64 + noApiHash*: uint64 + reportVersionMismatch*: proc (library: ptr GodotObject, extension: cstring, + want: GDNativeAPIVersion, have: GDNativeAPIVersion) {.noconv.} + reportLoadingError*: proc (library: ptr GodotObject, what: cstring) {.noconv.} + gdNativeLibrary*: ptr GodotObject + gdNativeAPIStruct*: pointer + activeLibraryPath*: ptr GodotString + + GDNativeTerminateOptions* = object + inEditor*: bool + + GodotMethodRPCMode* {.size: sizeof(cint), pure.} = enum + Disabled, + Remote, + Sync, + Master, + Slave + + GodotMethodAttributes* = object + rpcMode*: GodotMethodRPCMode + + GodotPropertyHint* {.size: sizeof(cint), pure.} = enum + None, ## no hint provided. + Range, ## hint_text = "min,max,step,slider; // slider is optional" + ExpRange, ## hint_text = "min,max,step", exponential edit + Enum, ## hint_text= "val1,val2,val3,etc" + ExpEasing, ## exponential easing funciton (Math::ease) + Length, ## hint_text= "length" (as integer) + SpriteFrame, + KeyAccel, ## hint_text= "length" (as integer) + Flags, ## hint_text= "flag1,flag2,etc" (as bit flags) + Layers2DRender, + Layers2DPhysics, + Layers3DRender, + Layers3DPhysics, + File, ## a file path must be passed, hint_text (optionally) + ## is a filter "*.png,*.wav,*.doc," + Dir, ## a directort path must be passed + GlobalFile, ## a file path must be passed, hint_text (optionally) is a + ## filter "*.png,*.wav,*.doc," + GlobalDir, ## a directort path must be passed + ResourceType, ## a resource object type + MultilineText, ## used for string properties that can contain multiple lines + ColorNoAlpha, ## used for ignoring alpha component when editing a color + ImageCompressLossy, + ImageCompressLossless, + ObjectId, + TypeString, ## a type string, the hint is the base type to choose + NodePathToEditedNode, ## so something else can provide this + ## (used in scripts) + MethodOfVariantType, ## a method of a type + MethodOfBaseType, ## a method of a base type + MethodOfInstance, ## a method of an instance + MethodOfScript, ## a method of a script & base + PropertyOfVariantType, ## a property of a type + PropertyOfBaseType, ## a property of a base type + PropertyOfInstance, ## a property of an instance + PropertyOfScript, ## a property of a script & base + PropertyHintMax + +const + GODOT_PROPERTY_USAGE_STORAGE_VALUE = 1.cint + GODOT_PROPERTY_USAGE_EDITOR_VALUE = 2.cint + GODOT_PROPERTY_USAGE_NETWORK_VALUE = 4.cint + GODOT_PROPERTY_USAGE_EDITOR_HELPER_VALUE = 8.cint + GODOT_PROPERTY_USAGE_CHECKABLE_VALUE = 16.cint + GODOT_PROPERTY_USAGE_CHECKED_VALUE = 32.cint + GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE = 64.cint + GODOT_PROPERTY_USAGE_GROUP_VALUE = 128.cint + GODOT_PROPERTY_USAGE_CATEGORY_VALUE = 256.cint + GODOT_PROPERTY_USAGE_STORE_IF_NONZERO_VALUE = 512.cint + GODOT_PROPERTY_USAGE_STORE_IF_NONONE_VALUE = 1024.cint + GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE_VALUE = 2048.cint + GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED_VALUE = 4096.cint + GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE_VALUE = 8192.cint + GODOT_PROPERTY_USAGE_STORE_IF_NULL_VALUE = 16384.cint + GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER_VALUE = 32768.cint + GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED_VALUE = 65536.cint + + GODOT_PROPERTY_USAGE_DEFAULT_VALUE: cint = + GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_EDITOR_VALUE or + GODOT_PROPERTY_USAGE_NETWORK_VALUE + GODOT_PROPERTY_USAGE_DEFAULT_INTL_VALUE: cint = + GODOT_PROPERTY_USAGE_STORAGE_VALUE or + GODOT_PROPERTY_USAGE_EDITOR_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE or + GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE + GODOT_PROPERTY_USAGE_NOEDITOR_VALUE: cint = + GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE + +type + GodotPropertyUsage* {.size: sizeof(cint), pure.} = enum + Storage = GODOT_PROPERTY_USAGE_STORAGE_VALUE + Editor = GODOT_PROPERTY_USAGE_EDITOR_VALUE + Network = GODOT_PROPERTY_USAGE_NETWORK_VALUE + NoEditor = GODOT_PROPERTY_USAGE_NOEDITOR_VALUE + Default = GODOT_PROPERTY_USAGE_DEFAULT_VALUE + EditorHelper = GODOT_PROPERTY_USAGE_EDITOR_HELPER_VALUE + Checkable = GODOT_PROPERTY_USAGE_CHECKABLE_VALUE + ## used for editing global variables + Checked = GODOT_PROPERTY_USAGE_CHECKED_VALUE + ## used for editing global variables + Internationalized = GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE + ## hint for internationalized strings + DefaultIntl = GODOT_PROPERTY_USAGE_DEFAULT_INTL_VALUE + Group = GODOT_PROPERTY_USAGE_GROUP_VALUE + ## used for grouping props in the editor + Category = GODOT_PROPERTY_USAGE_CATEGORY_VALUE + NonZero = GODOT_PROPERTY_USAGE_STORE_IF_NONZERO_VALUE + ## only store if nonzero + NonOne = GODOT_PROPERTY_USAGE_STORE_IF_NONONE_VALUE + ## only store if false + NoInstanceState = GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE_VALUE + RestartIfChanged = GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED_VALUE + ScriptVariable = GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE_VALUE + StoreIfNull = GODOT_PROPERTY_USAGE_STORE_IF_NULL_VALUE + AnimateAsTrigger = GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER_VALUE + UpdateAllIfModified = GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED_VALUE + + GodotPropertyAttributes* {.bycopy.} = object + rsetType*: GodotMethodRPCMode + typ*: cint + hint*: GodotPropertyHint + hintString*: GodotString + usage*: cint + defaultValue*: GodotVariant + + GodotInstanceCreateFunc* {.bycopy.} = object + createFunc*: + proc (obj: ptr GodotObject; methodData: pointer): pointer {.noconv.} + ## returns user data + methodData*: pointer + freeFunc*: proc (a2: pointer) {.noconv.} + + GodotInstanceDestroyFunc* {.bycopy.} = object + destroyFunc*: + proc (obj: ptr GodotObject; methodData: pointer; + userData: pointer) {.noconv.} + methodData*: pointer + freeFunc*: proc (a2: pointer) {.noconv.} + + GodotInstanceMethod* {.bycopy.} = object + meth*: + proc (obj: ptr GodotObject; methodData: pointer; + userData: pointer; numArgs: cint; + args: var array[MAX_ARG_COUNT, ptr GodotVariant]): + GodotVariant {.noconv.} + methodData*: pointer + freeFunc*: proc (a2: pointer) {.noconv.} + + GodotPropertySetFunc* {.bycopy.} = object + setFunc*: proc (obj: ptr GodotObject; methodData: pointer; + userData: pointer; value: GodotVariant) {.noconv.} + methodData*: pointer + freeFunc*: proc (a2: pointer) {.noconv.} + + GodotPropertyGetFunc* {.bycopy.} = object + getFunc*: proc (obj: ptr GodotObject; methodData: pointer; + userData: pointer): GodotVariant {.noconv.} + methodData*: pointer + freeFunc*: proc (a2: pointer) {.noconv.} + + GodotSignalArgument* {.bycopy.} = object + name*: GodotString + typ*: cint + hint*: GodotPropertyHint + hintString*: GodotString + usage*: cint + defaultValue*: GodotVariant + + GodotSignal* = object + name*: GodotString + numArgs*: cint + args*: ptr GodotSignalArgument + numDefaultArgs*: cint + defaultArgs*: ptr GodotVariant + + GodotClassConstructor* = proc (): ptr GodotObject {. + noconv, gcsafe, locks: 0, raises: [], tags: [].} + +template offset*[T](p: ptr T, offset: int): ptr T = + cast[ptr T](cast[ByteAddress](p) +% (offset * sizeof(T))) \ No newline at end of file diff --git a/godot/internal/godotnodepaths.nim b/godot/internal/godotnodepaths.nim index d05e175..b4578c0 100644 --- a/godot/internal/godotnodepaths.nim +++ b/godot/internal/godotnodepaths.nim @@ -1,32 +1,40 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. -import godotstrings +import godotinternaltypes, gdnativeapi -type - GodotNodePath* {.byref.} = object - p: pointer +proc initGodotNodePath*(dest: var GodotNodePath; s: GodotString) {.inline.} = + getGDNativeAPI().nodePathNew(dest, s) -proc initGodotNodePath*(dest: var GodotNodePath; s: GodotString) {. - importc: "godot_node_path_new".} -proc deinit*(self: var GodotNodePath) {. - importc: "godot_node_path_destroy".} -proc toGodotString*(self: GodotNodePath): GodotString {. - importc: "godot_node_path_as_string".} +proc initGodotNodePath*(dest: var GodotNodePath; + src: GodotNodePath) {.inline.} = + getGDNativeAPI().nodePathNewCopy(dest, src) -proc isAbsolute*(self: GodotNodePath): bool {. - noSideEffect, importc: "godot_node_path_is_absolute".} -proc nameCount*(self: GodotNodePath): cint {. - noSideEffect, importc: "godot_node_path_get_name_count".} -proc getName*(self: GodotNodePath; idx: cint): GodotString {. - noSideEffect, importc: "godot_node_path_get_name".} -proc subnameCount*(self: GodotNodePath): cint {. - noSideEffect, importc: "godot_node_path_get_subname_count".} -proc getSubname*(self: GodotNodePath; idx: cint): GodotString {. - noSideEffect, importc: "godot_node_path_get_subname".} -proc property*(self: GodotNodePath): GodotString {. - noSideEffect, importc: "godot_node_path_get_property".} -proc isEmpty*(self: GodotNodePath): bool {. - noSideEffect, importc: "godot_node_path_is_empty".} +proc deinit*(self: var GodotNodePath) {.inline.} = + getGDNativeAPI().nodePathDestroy(self) -proc `==`*(a, b: GodotNodePath): bool {. - noSideEffect, importc: "godot_node_path_operator_equal".} +proc toGodotString*(self: GodotNodePath): GodotString {.inline.} = + getGDNativeAPI().nodePathAsString(self) + +proc isAbsolute*(self: GodotNodePath): bool {.inline.} = + getGDNativeAPI().nodePathIsAbsolute(self) + +proc nameCount*(self: GodotNodePath): cint {.inline.} = + getGDNativeAPI().nodePathGetNameCount(self) + +proc getName*(self: GodotNodePath; idx: cint): GodotString {.inline.} = + getGDNativeAPI().nodePathGetName(self, idx) + +proc subnameCount*(self: GodotNodePath): cint {.inline.} = + getGDNativeAPI().nodePathGetSubnameCount(self) + +proc getSubname*(self: GodotNodePath; idx: cint): GodotString {.inline.} = + getGDNativeAPI().nodePathGetSubname(self, idx) + +proc getConcatenatedSubnames*(self: GodotNodePath): GodotString {.inline.} = + getGDNativeAPI().nodePathGetConcatenatedSubnames(self) + +proc isEmpty*(self: GodotNodePath): bool {.inline.} = + getGDNativeAPI().nodePathIsEmpty(self) + +proc `==`*(a, b: GodotNodePath): bool {.inline.} = + getGDNativeAPI().nodePathOperatorEqual(a, b) diff --git a/godot/internal/godotpoolarrays.nim b/godot/internal/godotpoolarrays.nim index da7ca4c..119848f 100644 --- a/godot/internal/godotpoolarrays.nim +++ b/godot/internal/godotpoolarrays.nim @@ -1,376 +1,269 @@ -# Copyright (c) 2017 Xored Software, Inc. +# Copyright (c) 2018 Xored Software, Inc. +import godotinternaltypes, gdnativeapi +import core/godotcoretypes -import godotinternaltypes, godotstrings -import "../core/godotbase.nim", "../core/colors.nim", - "../core/vector2.nim", "../core/vector3.nim" +template genPoolArrayAPI(ArrayT, initIdent, DataT, + newProc, newCopyProc, newWithArrayProc, appendProc, + appendArrayProc, insertProc, invertProc, pushBackProc, + removeProc, resizeProc, setProc, getProc, sizeProc, + destroyProc, readProc, writeProc, + readAccessPtrProc, writeAccessPtrProc, + readAccessDestroyProc, writeAccessDestroyProc) = + proc initIdent*(dest: var ArrayT) {.inline.} = + getGDNativeAPI().newProc(dest) -type - GodotPoolByteArray* {.byref.} = object - p: pointer - GodotPoolIntArray* {.byref.} = object - p: pointer - GodotPoolRealArray* {.byref.} = object - p: pointer - GodotPoolStringArray* {.byref.} = object - p: pointer - GodotPoolVector2Array* {.byref.} = object - p: pointer - GodotPoolVector3Array* {.byref.} = object - p: pointer - GodotPoolColorArray* {.byref.} = object - p: pointer + proc initIdent*(dest: var ArrayT; src: ArrayT) {.inline.} = + getGDNativeAPI().newCopyProc(dest, src) -# byte + proc initIdent*(dest: var ArrayT; arr: GodotArray) {.inline.} = + getGDNativeAPI().newWithArrayProc(dest, arr) -proc initGodotPoolByteArray*(dest: var GodotPoolByteArray) {. - importc: "godot_pool_byte_array_new".} -proc initGodotPoolByteArray*(dest: var GodotPoolByteArray; - src: GodotPoolByteArray) {. - importc: "godot_pool_byte_array_new_copy".} -proc initGodotPoolByteArray*(dest: var GodotPoolByteArray; arr: GodotArray) {. - importc: "godot_pool_byte_array_new_with_array".} + proc deinit*(self: var ArrayT) {.inline.} = + getGDNativeAPI().destroyProc(self) -proc deinit*(self: var GodotPoolByteArray) {. - importc: "godot_pool_byte_array_destroy".} + proc add*(self: var ArrayT; data: DataT) {.inline.} = + getGDNativeAPI().pushBackProc(self, data) -proc add*(self: var GodotPoolByteArray; - data: uint8) {. - importc: "godot_pool_byte_array_append".} -proc addFirst*(self: var GodotPoolByteArray, data: uint8) {. - importc: "godot_pool_byte_array_push_back".} -proc add*(self: var GodotPoolByteArray; - arr: GodotPoolByteArray) {. - importc: "godot_pool_byte_array_append_array".} -proc insert*(self: var GodotPoolByteArray; idx: cint; - data: uint8): Error {. - importc: "godot_pool_byte_array_insert".} -proc delete*(self: var GodotPoolByteArray; idx: cint) {. - importc: "godot_pool_byte_array_remove".} + proc add*(self: var ArrayT; arr: ArrayT) {.inline.} = + getGDNativeAPI().appendArrayProc(self, arr) -proc reverse*(self: var GodotPoolByteArray) {. - importc: "godot_pool_byte_array_invert".} -proc setLen*(self: var GodotPoolByteArray; size: cint) {. - importc: "godot_pool_byte_array_resize".} + proc insert*(self: var ArrayT; idx: cint; + data: DataT): Error {.inline.} = + getGDNativeAPI().insertProc(self, idx, data) -proc `[]=`*(self: var GodotPoolByteArray; idx: cint; data: uint8) {. - importc: "godot_pool_byte_array_set".} -proc `[]`*(self: GodotPoolByteArray; idx: cint): uint8 {. - noSideEffect, - importc: "godot_pool_byte_array_get".} -proc len*(self: GodotPoolByteArray): cint {. - noSideEffect, - importc: "godot_pool_byte_array_size".} + proc delete*(self: var ArrayT; idx: cint) {.inline.} = + getGDNativeAPI().removeProc(self, idx) -iterator items*(arr: GodotPoolByteArray): byte = - for i in 0..= ownLen: + let instInfo = instantiationInfo() + getGDNativeAPI().printError( + cstring"Invalid subarray begin index", cstring"subarray", instInfo.filename, instInfo.line.cint) + return + if actualIdxTo < 0 or actualIdxTo >= ownLen: + let instInfo = instantiationInfo() + getGDNativeAPI().printError( + cstring"Invalid subarray end index", cstring"subarray", instInfo.filename, instInfo.line.cint) + return + let span = actualIdxTo - actualIdxFrom + 1 + result.setLen(span) + let readAccess = getGDNativeAPI().readProc(self) + let writeAccess = getGDNativeAPI().writeProc(result) + let readPtr = getGDNativeAPI().readAccessPtrProc(readAccess).offset(actualIdxFrom) + copyMem(getGDNativeAPI().writeAccessPtrProc(writeAccess), readPtr, span) + getGDNativeAPI().readAccessDestroyProc(readAccess) + getGDNativeAPI().writeAccessDestroyProc(writeAccess) -iterator items*(arr: GodotPoolRealArray): float32 = - for i in 0..`_: + ## + ## .. code-block:: nim + ## import godot, editor_plugin + ## + ## gdobj(MyTool of EditorPlugin, tool): + ## method enterTree*() = + ## print("MyTool initialized!") + ## + ## Objects can be instantiated by invoking + ## `gdnew `_ or by using + ## `load `_ or any other way + ## that you can find in `Godot API `_. + let typeDef = parseType(ast) result = genType(typeDef) diff --git a/godot/nim/godotnim.nim b/godot/nim/godotnim.nim index 7c6aa7e..7f3ed96 100644 --- a/godot/nim/godotnim.nim +++ b/godot/nim/godotnim.nim @@ -1,24 +1,52 @@ -# Copyright 2017 Xored Software, Inc. +# Copyright 2018 Xored Software, Inc. -import tables, typetraits, macros -import "../core/godotbase.nim" -import "../core/vector2.nim", "../core/rect2.nim", - "../core/vector3.nim", "../core/transform2d.nim", - "../core/planes.nim", "../core/quats.nim", "../core/rect3.nim", - "../core/basis.nim", "../core/transforms.nim", "../core/colors.nim", - "../core/nodepaths.nim", "../core/rids.nim", "../core/dictionaries.nim", - "../core/arrays.nim", "../core/poolarrays.nim", "../core/variants.nim" -import "../godotinternal.nim" +import tables, typetraits, macros, unicode, strutils, sets, options +import gdnativeapi +import core/godotcoretypes, core/godotbase +import core/vector2, core/rect2, + core/vector3, core/transform2d, + core/planes, core/quats, core/aabb, + core/basis, core/transforms, core/colors, + core/nodepaths, core/rids, core/dictionaries, + core/arrays, core/poolarrays, core/variants +import godotinternal -## Definition of NimGodotObject and converters for built-in types. +## This module defines ``NimGodotObject`` and ``toVariant``/``fromVariant`` +## converters for Nim types. The converters are used by +## `gdobj `_ macro to import/export +## values from/to Godot (editor, GDScript). +## +## You can also allow conversion of any custom type ``MyType`` by implementing: +## +## .. code-block:: nim +## proc godotTypeInfo*(T: typedesc[MyType]): GodotTypeInfo +## proc toVariant*(self: MyType): Variant +## proc fromVariant*(self: var MyType, val: Variant): ConversionResult +## +## Implementing ``godotTypeInfo`` is optional and is necessary only if you want +## the type to be editable from the editor. type NimGodotObject* = ref object of RootObj + ## The base type all Godot types inherit from. + ## Manages lifecycle of the wrapped ``GodotObject``. godotObject: ptr GodotObject - isExternalRef: bool - isOwn: bool + linkedObjectPtr: pointer + ## Wrapper around native object that is the container of the Nim "script" + ## This is needed for `of` checks and `as` conversions to work as + ## expected. For example, Nim type may inherit from ``Spatial``, but the + ## script is attached to ``Particles``. In this case conversion to + ## ``Particles`` is valid, but Nim type system is not aware of that. + ## This works in both directions - for linked native object this + ## reference points to Nim object. + ## This is stored as a raw pointer to avoid reference cycles and therefore + ## improve GC performance. + isRef*: bool + isFinalized: bool + isNative: bool ConversionResult* {.pure.} = enum + ## Conversion result to return from ``fromVariant`` procedure. OK, TypeError, ## Type mismatch @@ -31,7 +59,7 @@ type SomeFloat = float32 or float64 or cfloat SomeGodot = bool or Vector2 or Rect2 or Vector3 or - Transform2D or Plane or Quat or Rect3 or + Transform2D or Plane or Quat or AABB or Basis or Transform or Color or NodePath or RID or GodotObject or Dictionary or Array or PoolByteArray or PoolIntArray or PoolRealArray or @@ -41,7 +69,11 @@ type SomeGodotOrNum = SomeGodot or SomeSignedInt or SomeUnsignedInt or SomeFloat CallError* = object of Exception + ## Raised by wrappers in case of an incorrect dynamic invocation. + ## For example, if incorrect number of arguments were passed or they had + ## unexpected types. err*: VariantCallError + ## The error as returned by Godot ObjectInfo = object constructor: proc(): NimGodotObject {.gcsafe, nimcall.} @@ -49,34 +81,81 @@ type isNative: bool isRef: bool -template printWarning*(warn: typed) = - let (filename, line) = instantiationInfo() - godotPrintWarning(cstring($warn), nil, cstring(filename), line.cint) + GodotTypeInfo* = object + ## Type information provided to Godot editor + variantType*: VariantType + hint*: GodotPropertyHint + hintStr*: string + ## Format depends on the type and the hint. + ## For example, for Enum ``hint`` this is a comma separated list of + ## values. + ## See documentation of ``GodotPropertyHint`` for description of formats. -template printError*(err: typed) = - let (filename, line) = instantiationInfo() - godotPrintError(cstring($err), nil, cstring(filename), line.cint) + FNV1Hash = uint32 -proc print*(message: string) {.inline.} = - var s = message.toGodotString() - godotPrint(s) - s.deinit() +include "internal/backwardcompat.inc.nim" -proc print*(message: cstring) {.inline.} = - var s = message.toGodotString() - godotPrint(s) - s.deinit() +proc isFinalized*(obj: NimGodotObject): bool {.inline.} = + obj.isFinalized -var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo] -var classRegistryStatic {.compileTime.}: TableRef[cstring, ObjectInfo] +var classRegistry {.threadvar.}: TableRef[FNV1Hash, ObjectInfo] +var classRegistryStatic* {.compileTime.}: TableRef[FNV1Hash, ObjectInfo] + ## Compile-time variable used for implementation of several procedures + ## and macros static: - classRegistryStatic = newTable[cstring, ObjectInfo]() + classRegistryStatic = newTable[FNV1Hash, ObjectInfo]() -static: - import sets, strutils var nativeClasses {.compileTime.} = newSeq[string]() var refClasses* {.compileTime.} = newSeq[string]() +template initFNV1Hash(hash: var FNV1Hash) = + hash = 0x811c9dc5'u32 + +template appendFNV1Hash(hash: var FNV1Hash, val: uint8) = + block: + let u64hash = hash.uint64 + hash = (( + u64hash + + (u64hash shl 1'u64) + + (u64hash shl 4'u64) + + (u64hash shl 7'u64) + + (u64hash shl 8'u64) + + (u64hash shl 24'u64)) and 0xFFFFFFFF'u32).uint32 xor val + +{.push stackTrace:off.} +proc lsb(c: ptr cwchar_t): char {.noinit, inline.} = + {.emit: [result, " = (char)(", c[]," & 0xFF);"]} +{.pop.} + +proc fnv1Hash(godotClassName: GodotString): FNV1Hash = + var charsCount = godotClassName.len + let charsPtr = godotClassName.dataPtr + if charsCount > 2 and + charsPtr.offset(charsCount - 2).lsb == 'S' and + charsPtr.offset(charsCount - 1).lsb == 'W': + charsCount -= 2 + + initFNV1Hash(result) + for i in 0..= charsCount: + break + let firstByte = uint8(rune.uint64 and 0xFF'u64) + appendFNV1Hash(result, firstByte) + # We don't really need to calculate hash of other bytes, + # since we only use hashes of ASCII strings + inc i + proc getClassName*(o: NimGodotObject): string = o.godotObject.getClassName() @@ -88,11 +167,18 @@ proc unreference(o: ptr GodotObject): bool = unreferenceMethodBind.ptrCall(o, nil, addr(result)) var referenceMethodBind {.threadvar.}: ptr GodotMethodBind -proc reference(o: ptr GodotObject) = +proc reference(o: ptr GodotObject): bool {.discardable.} = if isNil(referenceMethodBind): referenceMethodBind = getMethod(cstring"Reference", cstring"reference") - referenceMethodBind.ptrCall(o, nil, nil) + referenceMethodBind.ptrCall(o, nil, addr result) + +var initRefMethodBind {.threadvar.}: ptr GodotMethodBind +proc initRef(o: ptr GodotObject): bool {.discardable.} = + if isNil(initRefMethodBind): + initRefMethodBind = getMethod(cstring"Reference", + cstring"init_ref") + initRefMethodBind.ptrCall(o, nil, addr result) proc deinit*(obj: NimGodotObject) = ## Destroy the object. You only need to call this for objects not inherited @@ -101,11 +187,15 @@ proc deinit*(obj: NimGodotObject) = obj.godotObject.deinit() obj.godotObject = nil -proc godotFinalizer[T: NimGodotObject](obj: T) = - if obj.godotObject.isNil: return - if obj.isExternalRef and obj.godotObject.unreference(): - obj.deinit() - elif obj.isOwn: +proc linkedObject(obj: NimGodotObject): NimGodotObject {.inline.} = + cast[NimGodotObject](obj.linkedObjectPtr) + +proc nimGodotObjectFinalizer*[T: NimGodotObject](obj: T) = + if obj.godotObject.isNil or obj.isNative: return + # important to set it before so that ``unreference`` is aware + obj.isFinalized = true + if (obj.isRef or not obj.linkedObject.isNil and obj.linkedObject.isRef) and + obj.godotObject.unreference(): obj.deinit() macro baseNativeType(T: typedesc): cstring = @@ -119,34 +209,40 @@ macro baseNativeType(T: typedesc): cstring = if typeName == "NimGodotObject": break t = getType(t[1][1]) - if baseT.isNil: + if baseT.len == 0: result = newNilLit() else: let rStr = newNimNode(nnkRStrLit) rStr.strVal = baseT result = newNimNode(nnkCallStrLit).add(ident("cstring"), rStr) -macro isReference(T: typedesc): bool = - var isRef = false - var t = getType(T) +proc inherits(t: NimNode, parent: string): bool {.compileTime.} = + var curT = t while true: - let typeName = ($t[1][1]).split(':')[0] - if typeName == "Reference": - isRef = true - break + let typeName = ($curT[1][1]).split(':')[0] + if typeName == parent: + return true if typeName == "NimGodotObject": break - t = getType(t[1][1]) - result = if isRef: ident("true") + curT = getType(curT[1][1]) + +macro isReference(T: typedesc): bool = + result = if inherits(getType(T), "Reference"): ident("true") else: ident("false") -template registerClass*(T: typedesc; godotClassName: cstring, - isNativeParam: bool) = +macro isResource(T: typedesc): bool = + result = if inherits(getType(T), "Resource"): ident("true") + else: ident("false") + +template registerClass*(T: typedesc; godotClassName: string or cstring, + native: bool) = + ## Registers the specified Godot type. + ## Used by ``gdobj`` macro and `godotapigen `_. if classRegistry.isNil: - classRegistry = newTable[cstring, ObjectInfo]() + classRegistry = newTable[FNV1Hash, ObjectInfo]() let constructor = proc(): NimGodotObject = var t: T - new(t, godotFinalizer[T]) + new(t, nimGodotObjectFinalizer[T]) result = t const base = baseNativeType(T) @@ -154,95 +250,128 @@ template registerClass*(T: typedesc; godotClassName: cstring, let objInfo = ObjectInfo( constructor: constructor, baseNativeClass: base, - isNative: isNativeParam, + isNative: native, isRef: isRef ) - classRegistry[godotClassName] = objInfo + classRegistry[fnv1Hash($godotClassName)] = objInfo static: let objInfoStatic = ObjectInfo( baseNativeClass: base, - isNative: isNativeParam, - isRef: isRef + isNative: native, + isRef: isRef, ) - classRegistryStatic[godotClassName] = objInfoStatic + let nameHash = fnv1Hash($godotClassName) + if not classRegistryStatic.contains(nameHash): + classRegistryStatic[nameHash] = objInfoStatic + elif not endsWith($godotClassName, "SW"): + # For simplicity we assume that all class names must have + # different hashes + # If this exception is ever raised, I guess, we should + # implement a proper collision resolving + raise newException(Exception, "Hash collision " & $godotClassName) when isRef: static: refClasses.add(T.name) - when isNativeParam: + when native: static: nativeClasses.add(T.name) proc newNimGodotObject[T: NimGodotObject]( - godotObject: ptr GodotObject, godotClassName: cstring): T = + godotObject: ptr GodotObject, godotClassName: GodotString, noRef: bool): T = assert(not classRegistry.isNil) assert(not godotObject.isNil) - let objInfo = classRegistry.getOrDefault(godotClassName) + let objInfo = classRegistry.getOrDefault(fnv1Hash(godotClassName)) if objInfo.constructor.isNil: printError("Nim constructor not found for class " & $godotClassName) else: result = T(objInfo.constructor()) result.godotObject = godotObject - if objInfo.isRef: - result.isExternalRef = true + result.isRef = objInfo.isRef + if not noRef and objInfo.isRef: result.godotObject.reference() -proc asNimGodotObject*[T: NimGodotObject](godotObject: ptr GodotObject): T = +proc asNimGodotObject*[T: NimGodotObject]( + godotObject: ptr GodotObject, forceNativeObject, noRef: bool = false): T = + ## Wraps ``godotObject`` into Nim type ``T``. + ## This is used by `godotapigen `_ and should rarely be + ## used by anything else. if godotObject.isNil: return nil let userDataPtr = godotObject.getUserData() - if not userDataPtr.isNil: + if not userDataPtr.isNil and not forceNativeObject: result = cast[T](userDataPtr) if result.godotObject != godotObject: # Could be data from other bindings result = nil if result.isNil: + var classNameStr = godotObject.getClassNameRaw() result = newNimGodotObject[T]( - godotObject, cstring(godotObject.getClassName())) + godotObject, classNameStr, + forceNativeObject or noRef) + deinit(classNameStr) proc newVariant*(obj: NimGodotObject): Variant {.inline.} = newVariant(obj.godotObject) proc asObject*[T: NimGodotObject](v: Variant): T {.inline.} = + ## Converts ``v`` to object of type ``T``. + ## Returns ``nil`` if the conversion cannot be performed + ## (``v``'s type is not an Object or it's an object of an incompatible type) asNimGodotObject[T](v.asGodotObject()) proc asObject*(v: Variant, T: typedesc[NimGodotObject]): T {.inline.} = + ## Converts ``v`` to object of type ``T``. + ## Returns ``nil`` if the conversion cannot be performed + ## (``v``'s type is not an Object or it's an object of an incompatible type) asNimGodotObject[T](v.asGodotObject()) proc `as`*[T: NimGodotObject](obj: NimGodotObject, t: typedesc[T]): T = ## Converts the ``obj`` into the specified type. ## Returns ``nil`` if the conversion cannot be performed ## (the ``obj`` is not of the type ``T``) - if obj.isNil or not (obj of T): - when not defined(release): - if not obj.isNil: - printError("Failed to cast object to " & - t.name & "\n" & getStackTrace()) - result = nil - else: + ## + ## This can be used either in dot notation (``node.as(Button)``) or + ## infix notation (``node as Button``). + if obj.isNil: return nil + if system.`of`(obj, T): result = T(obj) + elif not obj.linkedObject.isNil and system.`of`(obj.linkedObject, T): + result = T(obj.linkedObject) + else: + result = nil -proc getSingletonGodot*(name: cstring): ptr GodotObject {. - importc: "godot_global_get_singleton".} +proc `of`*[T1, T2: NimGodotObject](obj: T1, t: typedesc[T2]): bool {.inline.} = + ## Godot-specific inheritance check. + not obj.isNil and (system.`of`(obj, T2) or system.`of`(obj.linkedObject, T2)) proc newRStrLit(s: string): NimNode {.compileTime.} = result = newNimNode(nnkRStrLit) result.strVal = s -static: - import strutils -macro toGodotName(T: typedesc): cstring = - let nameStr: string = (($T.getType()[1][1].symbol).split(':')[0]) - let godotName = case nameStr: - of "File", "Directory", "Thread", "Mutex", "Semaphore": - "_" & nameStr +macro toGodotName(T: typedesc): untyped = + if T is GodotString or T is string: + newStrLitNode"String" + elif T is SomeFloat: + newStrLitNode"float" + elif T is SomeUnsignedInt or T is SomeSignedInt: + newStrLitNode"int" else: - nameStr + let nameStr = ((T.getType()[1][1].strVal).split(':')[0]) + case nameStr: + of "File", "Directory", "Thread", "Mutex", "Semaphore": + newStrLitNode("_" & nameStr) + else: + newStrLitNode(nameStr) +macro asCString(s: static[string]): cstring = result = newNimNode(nnkCallStrLit).add( - ident("cstring"), newRStrLit(godotName)) + ident("cstring"), newRStrLit(s)) proc getSingleton*[T: NimGodotObject](): T = - const godotName = toGodotName(T) - let singleton = getSingletonGodot(godotName) + ## Returns singleton of type ``T``. Normally, this should not be used, + ## because `godotapigen `_ wraps singleton methods so that + ## singleton objects don't have to be provided as parameters. + const godotName = asCString(toGodotName(T)) + let singleton = getGodotSingleton(godotName) if singleton.isNil: printError("Tried to get non-existing singleton of type " & $godotName) else: @@ -282,16 +411,29 @@ proc newOwnObj[T: NimGodotObject](name: cstring): T = "but it returned: " & $ret.getType()) else: result = asNimGodotObject[T](ret.asGodotObject()) + if result.isRef: + result.isFinalized = true + result.godotObject.reference() + result.isFinalized = false ret.deinit() proc gdnew*[T: NimGodotObject](): T = + ## Instantiates new object of type ``T``. const godotName = toGodotName(T) - const objInfo = classRegistryStatic[godotName] - result = when objInfo.isNative: - asNimGodotObject[T](getClassConstructor(godotName)()) - else: newOwnObj[T](godotName) + const cGodotName = asCString(godotName) + const objInfo = classRegistryStatic[fnv1Hash(godotName)] + when objInfo.isNative: + let godotObject = getClassConstructor(cGodotName)() + new(result, nimGodotObjectFinalizer[T]) + result.godotObject = godotObject + when objInfo.isRef: + godotObject.initRef() + result.isRef = true + else: + result = newOwnObj[T](cGodotName) proc newCallError*(err: VariantCallError): ref CallError = + ## Instantiates ``CallError`` from Godot ``err``. let msg = case err.error: of VariantCallErrorType.OK, VariantCallErrorType.InvalidMethod, @@ -307,6 +449,8 @@ proc newCallError*(err: VariantCallError): ref CallError = result.err = err proc newConversionError*(err: ConversionResult): ref ValueError = + ## Instantiates error raised by `godotapigen `_ + ## generated code in case of a conversion error. let msg = case err: of ConversionResult.TypeError: "Failed to convert the return value into Nim type" @@ -317,29 +461,54 @@ proc newConversionError*(err: ConversionResult): ref ValueError = result = newException(ValueError, msg) -proc removeGodotObject*(nimObj: NimGodotObject) {.inline.} = - ## Used from destructor - nimObj.godotObject = nil - proc setGodotObject*(nimObj: NimGodotObject, obj: ptr GodotObject) {.inline.} = + ## Used from Godot constructor produced by ``gdobj`` macro. Do not call. assert(not obj.isNil) assert(nimObj.godotObject.isNil) # reassignment is not allowed nimObj.godotObject = obj -proc setOwn*(nimObj: NimGodotObject) {.inline.} = - nimObj.isOwn = true +proc setNativeObject*(nimObj: NimGodotObject, + nativeObj: NimGodotObject) {.inline.} = + ## Used from Godot constructor produced by ``gdobj`` macro. Do not call. + GC_ref(nativeObj) + nimObj.linkedObjectPtr = cast[pointer](nativeObj) + nativeObj.linkedObjectPtr = cast[pointer](nimObj) + nativeObj.isNative = true + +proc removeGodotObject*(nimObj: NimGodotObject) {.inline.} = + ## Used from Godot destructor produced by ``gdobj`` macro. Do not call. + GC_unref(nimObj.linkedObject) + nimObj.godotObject = nil + nimObj.linkedObject.godotObject = nil + nimObj.linkedObjectPtr = nil + +proc `==`*(self, other: NimGodotObject): bool {.inline.} = + ## Compares objects by referential equality. + if self.isNil and other.isNil: return true + if self.isNil != other.isNil: return false + result = (self.godotObject == other.godotObject) proc godotObject*(nimObj: NimGodotObject): ptr GodotObject {.inline.} = + ## Returns raw poitner to ``GodotObject``. Use only if you know what + ## you are doing. nimObj.godotObject -proc godotVariantType*(T: typedesc[NimGodotObject]): VariantType {.inline.} = - VariantType.Object +proc godotTypeInfo*(T: typedesc[NimGodotObject]): GodotTypeInfo {.inline.} = + GodotTypeInfo( + variantType: VariantType.Object, + hint: when isResource(T): GodotPropertyHint.ResourceType + else: GodotPropertyHint.None, + hintStr: toGodotName(T) + ) -proc toGodot*(self: NimGodotObject): Variant {.inline.} = - newVariant(self.godotObject) +proc toVariant*(self: NimGodotObject): Variant {.inline.} = + if self.isNil: + newVariant() + else: + newVariant(self.godotObject) -proc fromGodot*[T: NimGodotObject](self: var T, - val: Variant): ConversionResult = +proc fromVariant*[T: NimGodotObject](self: var T, + val: Variant): ConversionResult = if val.getType() == VariantType.Object: let objPtr = val.asGodotObject() self = asNimGodotObject[T](objPtr) @@ -350,109 +519,144 @@ proc fromGodot*[T: NimGodotObject](self: var T, else: result = ConversionResult.TypeError -proc godotVariantType*(T: typedesc[enum]): VariantType {.inline.} = - VariantType.Int - -proc toGodot*[T: enum](self: T): Variant {.inline.} = - newVariant(int64(ord(self))) - -proc fromGodot*[T: enum](self: var T, - val: Variant): ConversionResult {.inline.} = - if val.getType() == VariantType.Int: - self = T(val.asInt()) +proc toVariant*(self: Variant): Variant {.inline.} = + if self.isNil: + newVariant() else: - result = ConversionResult.TypeError + newVariant(self) -proc toGodot*(self: Variant): Variant {.inline.} = - self - -proc fromGodot*(self: var Variant, - val: Variant): ConversionResult {.inline.} = +proc fromVariant*(self: var Variant, + val: Variant): ConversionResult {.inline.} = self = newVariant(val) -proc godotVariantType*(T: typedesc[SomeGodotOrNum]): VariantType {.inline.} = - when T is SomeSignedInt or T is SomeUnsignedInt: - VariantType.Int - elif T is bool: - VariantType.Bool - elif T is SomeFloat: - VariantType.Real - elif T is string or T is GodotString: - VariantType.String - elif T is Vector2: - VariantType.Vector2 - elif T is Rect2: - VariantType.Rect2 - elif T is Vector3: - VariantType.Vector3 - elif T is Transform2D: - VariantType.Transform2D - elif T is Plane: - VariantType.Plane - elif T is Quat: - VariantType.Quat - elif T is Rect3: - VariantType.Rect3 - elif T is Basis: - VariantType.Basis - elif T is Transform: - VariantType.Transform - elif T is Color: - VariantType.Color - elif T is RID: - VariantType.RID - elif T is ptr GodotObject: - VariantType.Object - elif T is NodePath: - VariantType.NodePath - elif T is Dictionary: - VariantType.Dictionary - elif T is Array: - VariantType.Array - elif T is PoolByteArray: - VariantType.PoolByteArray - elif T is PoolIntArray: - VariantType.PoolIntArray - elif T is PoolRealArray: - VariantType.PoolRealArray - elif T is PoolStringArray: - VariantType.PoolStringArray - elif T is PoolVector2Array: - VariantType.PoolVector2Array - elif T is PoolVector3Array: - VariantType.PoolVector3Array - elif T is PoolColorArray: - VariantType.PoolColorArray +proc godotTypeInfo*(T: typedesc[SomeGodotOrNum]): GodotTypeInfo {.inline.} = + result.variantType = + when T is SomeSignedInt or T is SomeUnsignedInt: + VariantType.Int + elif T is bool: + VariantType.Bool + elif T is SomeFloat: + VariantType.Real + elif T is string or T is GodotString: + VariantType.String + elif T is Vector2: + VariantType.Vector2 + elif T is Rect2: + VariantType.Rect2 + elif T is Vector3: + VariantType.Vector3 + elif T is Transform2D: + VariantType.Transform2D + elif T is Plane: + VariantType.Plane + elif T is Quat: + VariantType.Quat + elif T is AABB: + VariantType.AABB + elif T is Basis: + VariantType.Basis + elif T is Transform: + VariantType.Transform + elif T is Color: + VariantType.Color + elif T is RID: + VariantType.RID + elif T is ptr GodotObject: + VariantType.Object + elif T is NodePath: + VariantType.NodePath + elif T is Dictionary: + VariantType.Dictionary + elif T is Array: + VariantType.Array + elif T is PoolByteArray: + VariantType.PoolByteArray + elif T is PoolIntArray: + VariantType.PoolIntArray + elif T is PoolRealArray: + VariantType.PoolRealArray + elif T is PoolStringArray: + VariantType.PoolStringArray + elif T is PoolVector2Array: + VariantType.PoolVector2Array + elif T is PoolVector3Array: + VariantType.PoolVector3Array + elif T is PoolColorArray: + VariantType.PoolColorArray + else: + VariantType.Nil + +proc godotTypeInfo*(T: typedesc[range]): VariantType {.inline.} = + GodotTypeInfo( + variantType: VariantType.Int, + hint: GodotPropertyHint.Range, + hintStr: $low(T) & "," & $high(T) & ",1" + ) + +proc toVariant*[T: SomeGodotOrNum](val: T): Variant {.inline.} = + when val is ref: + if val.isNil: + newVariant() + else: + newVariant(val) else: - VariantType.Nil + newVariant(val) -proc toGodot*[T: SomeGodotOrNum](val: T): Variant {.inline.} = - newVariant(val) - -proc fromGodot*[T: SomeSignedInt or SomeUnsignedInt]( +proc fromVariant*[T: SomeSignedInt or SomeUnsignedInt]( self: var T, val: Variant): ConversionResult = - if val.getType() != VariantType.Int: - result = ConversionResult.TypeError - else: + if val.getType() == VariantType.Nil: + self = 0 + elif val.getType() == VariantType.Int or val.getType() == VariantType.Real: + # Real is allowed, because that's what the editor sets for Int values var intVal: (when T is SomeSignedInt: int64 else: uint64) intVal = when T is SomeSignedInt: val.asInt() else: val.asUint() - if intVal > high(T) or intVal < low(T): + const highT = when T is SomeSignedInt: high(T).int64 + else: high(T).uint64 + const lowT = when T is SomeSignedInt: low(T).int64 + else: low(T).uint64 + if intVal > highT or intVal < lowT: result = ConversionResult.RangeError else: self = T(intVal) - -proc fromGodot*[T: SomeFloat](self: var T, val: Variant): ConversionResult = - if val.getType() == VariantType.Real: - self = T(val.asReal()) - elif val.getType() == VariantType.Int: - self = T(val.asInt()) else: result = ConversionResult.TypeError -proc fromGodot*[T: SomeGodot](self: var T, val: Variant): ConversionResult = - if godotVariantType(T) != val.getType(): +proc godotTypeInfo*(T: typedesc[enum]): GodotTypeInfo = + result = GodotTypeInfo( + variantType: VariantType.Int, + hint: GodotPropertyHint.Enum, + hintStr: "" + ) + for val in T: + if result.hintStr.len > 0: + result.hintStr.add(',') + result.hintStr.add($val) + +proc toVariant*[T: enum](self: T): Variant {.inline.} = + newVariant(int64(ord(self))) + +proc fromVariant*[T: enum](self: var T, + val: Variant): ConversionResult {.inline.} = + var intConv: int64 + result = fromVariant(intConv, val) + if result == ConversionResult.OK: + self = T(intConv) + +proc fromVariant*[T: SomeFloat](self: var T, val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + self = 0 + elif val.getType() == VariantType.Real or val.getType() == VariantType.Int: + self = T(val.asReal()) + else: + result = ConversionResult.TypeError + +proc fromVariant*[T: SomeGodot](self: var T, val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + return + const typeInfo = godotTypeInfo(T) + if typeInfo.variantType != val.getType(): return ConversionResult.TypeError when self is bool: self = val.asBool() @@ -468,8 +672,8 @@ proc fromGodot*[T: SomeGodot](self: var T, val: Variant): ConversionResult = self = val.asPlane() elif self is Quat: self = val.asQuat() - elif self is Rect3: - self = val.asRect3() + elif self is AABB: + self = val.asAABB() elif self is Basis: self = val.asBasis() elif self is Transform: @@ -506,144 +710,248 @@ proc fromGodot*[T: SomeGodot](self: var T, val: Variant): ConversionResult = # mustn't reach this result = ConversionError.TypeError -proc godotVariantType*(T: typedesc[string]): VariantType {.inline.} = - VariantType.String +proc godotTypeInfo*(T: typedesc[string]): GodotTypeInfo {.inline.} = + result.variantType = VariantType.String -proc toGodot*(s: string): Variant {.inline.} = +proc toVariant*(s: string): Variant {.inline.} = newVariant(s) -proc fromGodot*(s: var string, val: Variant): ConversionResult = +proc fromVariant*(s: var string, val: Variant): ConversionResult = if val.getType() == VariantType.String: s = val.asString() elif val.getType() == VariantType.Nil: - s = nil + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + s = nil + else: + s = "" else: result = ConversionResult.TypeError -proc godotVariantType*(T: typedesc[seq]): VariantType = - VariantType.Array +template arrTypeInfo(T) = + result.variantType = VariantType.Array + mixin godotTypeInfo + type ItemT = type(( + block: + var s: T; + when T is seq: s[0] else: s[low(s)])) + when compiles(godotTypeInfo(ItemT)): + let itemTypeInfo = godotTypeInfo(ItemT) + result.hintStr = $ord(itemTypeInfo.variantType) + result.hintStr.add('/') + result.hintStr.add($ord(itemTypeInfo.hint)) + result.hintStr.add(':') + if not itemTypeInfo.hintStr.isNil: + result.hintStr.add(itemTypeInfo.hintStr) -proc godotVariantType*(T: typedesc[array]): VariantType = - VariantType.Array +proc godotTypeInfo*(T: typedesc[seq]): GodotTypeInfo = + arrTypeInfo(T) -proc toGodot*[T](s: openarray[T]): Variant = +proc godotTypeInfo*(T: typedesc[array]): GodotTypeInfo = + arrTypeInfo(T) + +template arrayToVariant(s: untyped): Variant = var arr = newArray() - mixin toGodot + mixin toVariant for item in s: - arr.add(toGodot(item)) - result = newVariant(arr) + arr.add(toVariant(item)) + newVariant(arr) -proc fromGodot*[T](s: var seq[T], val: Variant): ConversionResult = - if val.getType() != VariantType.Array: - result = ConversionResult.TypeError - else: +proc toVariant*[T](s: seq[T]): Variant = + if s.isNil: + return newVariant() + result = arrayToVariant(s) + +proc toVariant*[I, T](s: array[I, T]): Variant = + result = arrayToVariant(s) + +proc fromVariant*[T](s: var seq[T], val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + s = nil + elif val.getType() == VariantType.Array: let arr = val.asArray() - s = newSeq[T](arr.len) + var newS = newSeq[T](arr.len) for idx, item in arr: - mixin fromGodot - let convResult = fromGodot(s[idx], item) + mixin fromVariant + let convResult = fromVariant(newS[idx], item) if convResult != ConversionResult.OK: - s = nil return convResult - -proc fromGodot*[T: array](s: var T, val: Variant): ConversionResult = - if val.getType() != VariantType.Array: - result = ConversionResult.TypeError + shallowCopy(s, newS) else: + result = ConversionResult.TypeError + +proc fromVariant*[T: array](s: var T, val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + discard + elif val.getType() == VariantType.Array: let arr = val.asArray() if s.len != arr.len: return ConversionResult.TypeError - for idx, item in arr: - mixin fromGodot - let convResult = fromGodot(s[idx], item) + var nimIdx = low(s) # may not start from 0 and may even be an enum + for item in arr: + mixin fromVariant + let convResult = fromVariant(s[nimIdx], item) if convResult != ConversionResult.OK: return convResult + if nimIdx != high(s): + inc nimIdx + else: + result = ConversionResult.TypeError -proc godotVariantType*(T: typedesc[Table|TableRef]): VariantType {.inline.} = - VariantType.Dictionary +proc godotTypeInfo*[T](OptT: typedesc[Option[T]]): GodotTypeInfo = + when compiles(godotTypeInfo(T)): + result.variantType = godotTypeInfo(T) + else: + result.variantType = VariantType.Nil -proc toGodot*[T: Table or TableRef](t: T): Variant = +proc toVariant*[T](option: Option[T]): Variant = + if option.isSome(): + result = toVariant(option.unsafeGet()) + else: + result = newVariant() + +proc fromVariant*[T](option: var Option[T], val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + option = none(T) + else: + var v: T + result = fromVariant(v, val) + if result == ConversionResult.OK: + option = some(result) + +proc godotTypeInfo*(T: typedesc[Table|TableRef|OrderedTable|OrderedTableRef]): GodotTypeInfo {.inline.} = + result.variantType = VariantType.Dictionary + +proc toVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: T): Variant = + when t is ref: + if t.isNil: + return newVariant() var dict = newDictionary() - mixin toGodot + mixin toVariant for k, v in t.pairs(): - dict[toGodot(k)] = toGodot(v) + dict[toVariant(k)] = toVariant(v) result = newVariant(dict) -proc fromGodot*[T: Table or TableRef](t: var T, val: Variant): ConversionResult = - if val.getType() != VariantType.Dictionary: - result = ConversionResult.TypeError - else: +proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: var T, + val: Variant): ConversionResult = + if val.getType() == VariantType.Nil: + when t is ref: + t = nil + elif val.getType() == VariantType.Dictionary: let dict = val.asDictionary() - mixin fromGodot + mixin fromVariant when t is Table: t = initTable[type(t.keys()), type(t.values())]() - else: + elif t is TableRef: t = newTable[type(t.keys()), type(t.values())]() + elif t is OrderedTable: + t = initOrderedTable[type(t.keys()), type(t.values())]() + else: + t = newOrderedTable[type(t.keys()), type(t.values())]() for k, v in dict: var nimKey: type(t.keys()) var nimVal: type(t.values()) - let keyResult = fromGodot(nimKey, k) + let keyResult = fromVariant(nimKey, k) if keyResult != ConversionResult.OK: when t is ref: t = nil return keyResult - let valResult = fromGodot(nimVal, v) + let valResult = fromVariant(nimVal, v) if valResult != ConversionResult.OK: when t is ref: t = nil return valResult t[nimKey] = nimVal - -proc godotToNim*[T](val: Variant): (T, ConversionResult) = - mixin fromGodot - result[1] = fromGodot(result[0], val) - -proc nimToGodot*[T](val: T): Variant = - mixin toGodot - when compiles(toGodot(val)): - result = toGodot(val) else: - printError("Failed to convert Nim value of type " & T.name & - " into Variant") - initNilVariant(result) + result = ConversionResult.TypeError -{.emit: """/*TYPESECTION*/ -void NimMain(void); -N_NOINLINE(void, setStackBottom)(void* thestackbottom); -""".} +when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """/*TYPESECTION*/ + N_LIB_EXPORT N_CDECL(void, NimMain)(void); + N_NOINLINE(void, setStackBottom)(void* thestackbottom); + """.} var nativeLibHandle: pointer proc getNativeLibHandle*(): pointer = + ## Returns NativeScript library handle used to register type information + ## in Godot. return nativeLibHandle proc godot_nativescript_init(handle: pointer) {. cdecl, exportc, dynlib.} = nativeLibHandle = handle - let stackBottom = godotStackBottom() + var stackBottom {.volatile.}: pointer + stackBottom = addr(stackBottom) {.emit: """ NimMain(); - setStackBottom(`stackBottom`); """.} + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """ + setStackBottom((void*)(&`stackBottom`)); + """.} + else: + nimGC_setStackBottom(stackBottom) GC_fullCollect() GC_disable() -proc godot_gdnative_init(options: ptr GodotNativeInitOptions) {. +proc godot_gdnative_init(options: ptr GDNativeInitOptions) {. cdecl, exportc, dynlib.} = gdNativeLibraryObj = options.gdNativeLibrary + setGDNativeAPI(options.gdNativeAPIStruct, options) -proc godot_gdnative_terminate(options: ptr GodotNativeTerminateOptions) {. +proc godot_gdnative_terminate(options: ptr GDNativeTerminateOptions) {. cdecl, exportc, dynlib.} = - deallocHeap(runFinalizers = not options[].inEditor, allowGcAfterwards = false) + if not options[].inEditor or not compileOption("threads"): + deallocHeap(runFinalizers = not options[].inEditor, allowGcAfterwards = false) -proc godot_nativescript_thread_enter() {. - cdecl, exportc, dynlib.} = +const nimGcStepLengthUs {.intdefine.} = 2000 + +var idleCallbacks {.threadvar.}: seq[proc () {.closure.}] +idleCallbacks = newSeq[proc () {.closure.}]() + +var isMainThread {.threadvar.}: bool +isMainThread = true + +proc registerFrameCallback*(cb: proc () {.closure.}) = + # Registers a callback to be called on the main thread at the end + # of each frame. + if not isMainThread: + const err = cstring"registerFrameIdleCallback is called from non-main thread. Ignoring." + godotPrintError(err, cstring"registerFrameCallback", + cstring"godotnim.nim", 0) + else: + idleCallbacks.add(cb) + +{.push stackTrace: off.} + +proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} = + var stackBottom {.volatile.}: pointer + stackBottom = addr(stackBottom) + when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): + {.emit: """ + setStackBottom((void*)(&`stackBottom`)); + """.} + else: + nimGC_setStackBottom(stackBottom) + for cb in idleCallbacks: + cb() + GC_step(nimGcStepLengthUs, true, 0) + +when not defined(release): + onUnhandledException = proc(errorMsg: string) = + printError("Unhandled Nim exception: " & errorMsg) + +proc godot_nativescript_thread_enter() {.cdecl, exportc, dynlib.} = when compileOption("threads"): setupForeignThreadGc() else: - print(cstring"A foreign thread is created, but app is compiled without --threads:on. Bad things will happen if Nim code is invoked from this thread.") + const err = cstring"A foreign thread is created, but app is compiled without --threads:on. Bad things will happen if Nim code is invoked from this thread. If you see this warning when running the editor and you don't actually use threads, ignore it." + var s = err.toGodotString() + godotPrint(s) + s.deinit() -proc godot_nativescript_thread_exit() {. - cdecl, exportc, dynlib.} = +proc godot_nativescript_thread_exit() {.cdecl, exportc, dynlib.} = when compileOption("threads"): teardownForeignThreadGc() + +{.pop.} # stackTrace: off diff --git a/godot/nim/nim.cfg b/godot/nim/nim.cfg new file mode 100644 index 0000000..add9a4d --- /dev/null +++ b/godot/nim/nim.cfg @@ -0,0 +1,2 @@ +--path:"$projectdir/../" +-d:useRealtimeGc \ No newline at end of file diff --git a/godot/nimdoc.cfg b/godot/nimdoc.cfg new file mode 100644 index 0000000..d4e8565 --- /dev/null +++ b/godot/nimdoc.cfg @@ -0,0 +1,5 @@ +doc.item.seesrc = """  Source +Edit +""" \ No newline at end of file diff --git a/godot/nimruntime.nim b/godot/nimruntime.nim deleted file mode 100644 index 4429508..0000000 --- a/godot/nimruntime.nim +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2017 Xored Software, Inc. - -import asyncdispatch -import godot, node - -gdobj NimRuntime of Node: - method process*(delta: float64) = - if asyncdispatch.hasPendingOperations(): - poll(0) - GC_step(2000, false, 0) - -when not defined(release): - onUnhandledException = proc(errorMsg: string) = - printError("Unhandled Nim exception: " & errorMsg)