Compare commits

..

139 commits

Author SHA1 Message Date
Ruslan Mustakov
4175dbb3e5 Bump version to 0.8.2 2021-05-03 23:18:50 +07:00
7eadb07820 Move template below arrays import
Fixes #81 

Alternate workaround for https://github.com/nim-lang/Nim/issues/16462 without changing VariantType.
2021-05-03 23:17:18 +07:00
Jason
00d8ac2691 Support nim case insensitivy in pragmas 2021-03-12 11:09:55 +07:00
Arun Dilipan
388bea9205 Added moveToward for vectors. 2020-12-13 12:13:41 +07:00
ShalokShalom
f25c3c7a5d Clarify version compability
One guy in the chat just asked me, if this binding is for 3.0 only, or also for 3.2.3
2020-10-17 13:22:31 +07:00
Ruslan Mustakov
d3e5f91b40 Fix wrapping methods with Array return types 2020-08-14 01:44:48 +07:00
Ruslan Mustakov
3f46e3c648 Break reference cycle in NimGodotObject 2020-06-05 16:53:34 +07:00
Ruslan Mustakov
87707a86b4 Remove Travis badge from README
Need to fix the CI script.
2020-06-03 18:06:18 +07:00
Ruslan Mustakov
031774f54f More efficient and GC-safe conversions in API generator 2020-06-03 17:58:47 +07:00
Ruslan Mustakov
ed9ede5cb3 Up version to 0.7.27 2020-02-05 12:34:44 +07:00
Konstantin Zaitsev
a49fcbdac7 Fix variant size for 32bit platform with memory alignment 2020-02-05 11:36:42 +07:00
zetashift
157a90e4a0
add gensym in hygienic template fix thanks to demotohiro (#55)
Add gensym in hygienic template fix thanks to demotohiro
2020-02-05 11:35:50 +07:00
Ruslan Mustakov
d1b82d351c Fix unsigned int conversion to/from Variant 2019-12-23 20:53:13 +07:00
Ruslan Mustakov
78d3626fa3 Do not log error when casting fails
This allows not to perform unnecessary 'of' check before
casting, if cast failure is expected.
2019-12-04 23:58:13 +07:00
Ruslan Mustakov
1b8e7ccd98 Add variant conversion for Option[T] 2019-10-02 15:26:41 +07:00
Ruslan Mustakov
c2db807da4 Up version to 0.7.23 2019-09-20 09:20:50 +07:00
Dwana Games
7dd1b1ed5f Add self to field initialization 2019-09-20 09:20:27 +07:00
Ruslan Mustakov
2f3f4034cf Fix newVariant for nil strings and older Nim 2019-09-18 13:27:31 +07:00
Ruslan Mustakov
19b0c23d62 Finalize support for Nim 0.20
Closes #32, closes #41.
2019-09-15 20:11:15 +07:00
Dwana Games
0fecfdb3b8 Updated to work with nim 0.20
- Attempt to fix deprecated this:self pragma by injecting self to methods and properties (needs more testing)
- Changed import headers to use / (slash) instead of . (period)
- Fixed object branch in godotapigen.nim
- Fixed deprecated nimNode.ident with nimNode.strVal

Fix toGodotName function

Consider procCall calls as special cases, otherwise it gives problems in _init function

Fix infinite recursive call in Godot 3.2
2019-09-15 15:34:09 +07:00
zetashift
34fda99def Small changes to add 0.18.0 compatibility
Change toGodotName back to macro because that got fixed in devel

change isSome to isNone in godotapigen
2019-09-15 15:33:59 +07:00
Fabian Keller
3a935b9308 attempt to make 0.19 compatible
workaround for nim/macro/typedesc issue

work-around for nim-lang/Nim#7375

fixed more isNil usages

fixed new name of setStackBottom
2019-09-15 15:33:44 +07:00
Konstantin Zaitsev
f45281f5a0 Fix possible double free memory on exit 2019-09-12 18:59:11 +07:00
Ruslan Mustakov
db4bb91765 Fix editor crash in multithreaded mode 2019-07-09 13:48:54 +07:00
Ruslan Mustakov
e9d73d8ec4 Fix GDNative API procedure declarations
Earlier signature mismatch caused problems on macOS with Godot 3.1.
2018-10-11 19:06:05 +07:00
Ruslan Mustakov
859f9f04fb OrderedTable to Variant conversion support 2018-09-21 16:34:09 +07:00
Evgeny Zuev
ceaf66a34c Make classRegistry use hashes instead of strings as keys for faster lookup
Up version to 0.7.16
2018-08-29 13:44:37 +07:00
Ruslan Mustakov
fd5f77e7c2 Fix gdobj to properly handle var block 2018-08-14 17:59:24 +07:00
Evgeny Zuev
8d68051f23 Fix system.of being preferred over godot.of in some cases
Fix `as` fails when argument `obj` is not convertible to `T`
Up version to 0.7.14
2018-06-21 17:53:01 +07:00
Ruslan Mustakov
13f5aba3fe Up version to 0.7.13 2018-06-04 17:26:26 +07:00
Ruslan Mustakov
b3ad6134d9 Fix doc generation 2018-06-04 16:24:52 +07:00
Ruslan Mustakov
1e8ccfea2b Fix handling of Error as an argument in Godot API 2018-06-04 14:28:14 +07:00
Ruslan Mustakov
9e61030817 Up version to 0.7.12 2018-06-04 11:50:37 +07:00
Ruslan Mustakov
66c939b9e6 Fix for latest Nim
Closes #23.
2018-06-04 11:50:37 +07:00
Ruslan Mustakov
76de026b4f Implement hash proc for Godot types 2018-06-04 11:50:37 +07:00
Ruslan Mustakov
4eb771e9be Support all the default values 2018-06-04 11:50:37 +07:00
Ruslan Mustakov
2dd0130c78 Avoid name clashes between properties and methods
Fixes #19.
2018-06-04 11:50:37 +07:00
Ruslan Mustakov
651c2d823c Handle nil object references properly
Fixes #26.
2018-06-04 11:50:37 +07:00
Ruslan Mustakov
8b1ac6d835 Fix compilation with C++ backend. Fixes #25. 2018-06-04 11:50:37 +07:00
Jon Renner
21ca9a088b export Vector2 normalize proc 2018-05-19 14:30:02 +07:00
Ruslan Mustakov
96dfc7de90 Fix for latest Nim 2018-05-16 15:06:57 +07:00
Ruslan Mustakov
a1d1481967 Add a remark to thread enter warning 2018-05-14 21:15:11 +07:00
Ruslan Mustakov
6e014bbc01 Make godotapigen use getter return type for property types
Fixes #20.
2018-04-24 11:12:49 +07:00
Ruslan Mustakov
dc6ebaf575 Fix GDNative API version check
Fixes #18.
2018-03-31 17:45:50 +07:00
Ruslan Mustakov
be6f01e3b7 More pool array features: subarray, mitems, mpairs 2018-02-22 18:55:52 +07:00
Ruslan Mustakov
d11856377e Implement Vector2 and Rect2 procs
This allows compiler to inline/optimize them, which cannot be done if
these procs are invoked via GDNative API.
2018-02-17 23:44:07 +07:00
Ruslan Mustakov
0aab6e17ef Update license year and fix doc to have Godot 3.0 download URL 2018-01-31 20:52:15 +07:00
Ruslan Mustakov
5ccf351b5a Fix Variant export 2018-01-31 20:30:13 +07:00
Ruslan Mustakov
f05eb090f7 Update after GDNative API changes 2018-01-25 17:52:58 +07:00
Ruslan Mustakov
e3216f09d0 Update ref types not to be var in parameters 2018-01-25 17:39:01 +07:00
Ruslan Mustakov
ae3171cb98 Fix Vector2 += 2018-01-15 11:01:48 +07:00
Ruslan Mustakov
d4ab8a5524 Update after recent GDNative API changes 2018-01-12 23:22:50 +07:00
Ruslan Mustakov
09326f5104 Fix Reference leak and improve gdnew performance 2018-01-11 16:52:41 +07:00
Ruslan Mustakov
d89073bac8 Do not depend on asyncdispatch
Instead, allow to register frame callbacks.
2017-12-29 11:52:00 +07:00
Ruslan Mustakov
e2feb06468 Add indexed property support 2017-12-18 17:22:12 +07:00
Ruslan Mustakov
4d19140d7c Update for latest GDNative API changes 2017-12-18 13:48:01 +07:00
Ruslan Mustakov
72dd992e66 Fix docbuild 2017-12-08 21:23:32 +07:00
Ruslan Mustakov
50835baca8 Fix travis 2017-12-08 16:50:08 +07:00
Ruslan Mustakov
c06792df8d Add vec2(). Closes #12 2017-12-08 16:07:23 +07:00
Ruslan Mustakov
8d6972f729 Fix doc generation 2017-12-08 13:21:01 +07:00
Ruslan Mustakov
0d21c361d0 Use setStackBottom for methods called from outside 2017-11-28 12:04:07 +07:00
Ruslan Mustakov
3e1e8f1073 Repair Travis build 2017-11-22 17:35:56 +07:00
Ruslan Mustakov
e2049ff1a7 Update for latest Nim 2017-11-22 16:38:28 +07:00
Ruslan Mustakov
4e24244c48 Update for latest Godot 2017-11-22 12:28:54 +07:00
Ruslan Mustakov
a1c378301a Update for latest Godot 2017-11-21 02:44:32 +07:00
Ruslan Mustakov
bf5bd54356 Rename Rect3 to AABB to sync with Godot 2017-11-20 06:52:37 +07:00
Ruslan Mustakov
cc6bfa0045 Update for latest GDNative API changes 2017-11-13 10:18:25 +07:00
Ruslan Mustakov
a93dcd1d4d Update for latest Nim 2017-11-08 11:39:07 +07:00
Ruslan Mustakov
e494dc914a Update GDNative API struct 2017-11-08 11:14:48 +07:00
Ruslan Mustakov
26570707aa Fix poll loop 2017-10-18 11:47:20 +07:00
Ruslan Mustakov
d2b86a2b94 Perform poll(0) in a loop
Temporary workaround for https://github.com/nim-lang/Nim/issues/6523
2017-10-17 16:32:07 +07:00
Ruslan Mustakov
1b47dac4e9 Fix thread_enter not to use GC 2017-10-16 20:10:16 +07:00
Ruslan Mustakov
7f73a89878 Fix $ for core types 2017-10-12 21:26:36 +07:00
Ruslan Mustakov
c5d7680e53 Change GodotClassConstructor to a safe signature 2017-10-12 20:55:45 +07:00
Ruslan Mustakov
f5abff05e6 Extend GDNative API according to the latest update 2017-10-09 14:47:28 +07:00
Ruslan Mustakov
54d962afd4 Fix void return type in godotapigen 2017-10-05 18:55:51 +07:00
Ruslan Mustakov
b62db02d8f Use GDNative API struct 2017-10-05 18:28:12 +07:00
Evgeny Zuev
cf75723fa1 Fix crash when passing nil seq to godot
Up version to 0.5.10
2017-09-19 18:26:55 +07:00
Ruslan Mustakov
178192651f Update docs regarding Nim version 2017-09-14 11:11:03 +07:00
Ruslan Mustakov
77a8cf7815 Replace ~ with of 2017-09-14 11:04:34 +07:00
Ruslan Mustakov
99934854d0 Fix Reference handling 2017-09-14 10:49:43 +07:00
Ruslan Mustakov
ee53768c13 Export generated init 2017-09-04 20:28:34 +07:00
Ruslan Mustakov
b5fd4295e6 Always generate init with super call 2017-09-04 19:29:59 +07:00
Ruslan Mustakov
e3c014a359 Up version to 0.5.6 2017-09-04 15:21:25 +07:00
Konstantin Zaitsev
2db2e413a9 Fix transform xform methods for rect3 2017-09-04 12:22:35 +07:00
Ruslan Mustakov
7e23048048 Up version to 0.5.5 2017-08-23 13:30:24 +07:00
Ruslan Mustakov
2c226b90e2 Support of enums in API generator 2017-08-23 13:30:08 +07:00
Ruslan Mustakov
fda800fd26 Avoid using godot_get_stack_bottom
It's not reliable on Android.
2017-08-23 13:29:35 +07:00
Ruslan Mustakov
3349fe2321 Up version to v0.5.4 2017-08-17 18:41:24 +07:00
Ruslan Mustakov
7a96e33f74 Treat process and fixed process as multilevel calls 2017-08-17 17:47:27 +07:00
Ruslan Mustakov
f54de5cd46 Remove wrong assertion (false for references) 2017-08-17 16:52:11 +07:00
Ruslan Mustakov
3d9839ceed Fix genSingletonWithDerived 2017-08-16 18:00:07 +07:00
Ruslan Mustakov
8d49c0b910 Register singleton-derived types. Fixes #8 2017-08-15 10:45:57 +07:00
Ruslan Mustakov
c5f6d47f3e Mark emitSignal as discardable 2017-08-14 20:22:08 +07:00
Ruslan Mustakov
6da07cada0 Up version to 0.5.1 2017-08-11 12:32:58 +07:00
Ruslan Mustakov
72e6e774a7 Remove debug code from gdobj 2017-08-11 12:30:12 +07:00
Konstantin Zaitsev
d43b10bc76 Fix nil pointer exception for variant from arrays 2017-08-11 12:22:16 +07:00
Ruslan Mustakov
53f0f230da Up version to 0.5.0 2017-08-09 17:05:29 +07:00
Ruslan Mustakov
e8ea5fbe27 Rename noExport -> noGdExport 2017-08-09 17:03:48 +07:00
Ruslan Mustakov
34753b7a27 Fix string returns in godotapigen 2017-08-09 16:34:28 +07:00
Ruslan Mustakov
fcc10071fb Fix toVariant for nil values 2017-08-08 21:58:17 +07:00
Ruslan Mustakov
a7d9aaef95 Fix initTransform 2017-08-08 21:58:03 +07:00
Ruslan Mustakov
4b6c76e776 Dont add base pragma for PhysicsBody methods 2017-08-08 19:13:51 +07:00
Ruslan Mustakov
daa56270e5 Fix object property export 2017-08-08 17:23:45 +07:00
Ruslan Mustakov
4cc9711d2f Handle nil in == 2017-08-07 22:13:42 +07:00
Ruslan Mustakov
8ef554501f Add nil check to tilde 2017-08-07 20:59:32 +07:00
Ruslan Mustakov
327cd0e18f Proper inheritance checks and conversion 2017-08-06 19:22:38 +07:00
Ruslan Mustakov
643c445f87 Allow conversion from Real to int types 2017-08-06 14:21:48 +07:00
Ruslan Mustakov
6549d90c3b Remove commented code from poolarrays 2017-08-06 13:59:33 +07:00
Ruslan Mustakov
6aaeed4dca Add missing $ to standard types 2017-08-06 13:58:54 +07:00
Ruslan Mustakov
72b706d7fe Allow to omit type when default value is present 2017-08-06 13:43:11 +07:00
Ruslan Mustakov
f91a0d0364 Allow gdExport without Nim export 2017-08-05 23:02:48 +07:00
Ruslan Mustakov
fd40716b58 print can be used similar to echo 2017-08-05 22:55:27 +07:00
Ruslan Mustakov
64a8aefeb8 Delete nimruntime 2017-08-05 22:33:51 +07:00
Ruslan Mustakov
3b89eeb9a7 Support default values 2017-08-05 22:33:21 +07:00
Ruslan Mustakov
c1c1852203 Provide type hints for standard types 2017-08-05 21:08:28 +07:00
Ruslan Mustakov
afa48455f6 Add -d:useRealtimeGc in Travis build 2017-08-04 13:23:20 +07:00
Ruslan Mustakov
fedd04229a Add varargs and openarray constructors for Array 2017-08-04 12:21:22 +07:00
Ruslan Mustakov
0062568dbc Add nativescript frame callback, deprecate NimRuntime 2017-08-04 12:02:55 +07:00
Ruslan Mustakov
e587fdf382 Add Travis status and doc link to README 2017-08-03 12:14:19 +07:00
Ruslan Mustakov
c34a2174fa Fix Travis PR check 2017-08-03 11:24:08 +07:00
Ruslan Mustakov
4d14f624b4 Add a bit of output to docpublish 2017-08-03 08:55:50 +07:00
Ruslan Mustakov
988b9e1f11 Documentation & Travis & Refactoring 2017-08-02 22:14:41 +07:00
Ruslan Mustakov
ec707ea776 Stub moved to separate repo 2017-08-01 22:50:26 +07:00
Ruslan Mustakov
294c057ff9 Suppress false warning 2017-08-01 21:06:20 +07:00
Ruslan Mustakov
0af5eb3b7f Print godotapigen progress (closes #3) 2017-08-01 20:59:34 +07:00
Ruslan Mustakov
7131cd0748 Fix GodotVariant size for 32-bit platforms 2017-08-01 20:52:56 +07:00
Ruslan Mustakov
a91fe1f713 Temporary solution for multilevel calls 2017-08-01 20:50:10 +07:00
Ruslan Mustakov
692fbe892b Support tool specifier 2017-08-01 18:25:24 +07:00
Ruslan Mustakov
0fd0101432 Rename simple -> stub 2017-07-31 22:22:40 +07:00
Ruslan Mustakov
31bd5ff4c6 NimRuntime only works during idle time 2017-07-31 21:22:25 +07:00
Ruslan Mustakov
be02bdfd9c Put internal types in their modules 2017-07-31 19:00:15 +07:00
Ruslan Mustakov
728e3012c6 Export exported fields in gdobj 2017-07-31 18:44:52 +07:00
Ruslan Mustakov
fb8c42a2cc Fix circular imports 2017-07-31 18:16:42 +07:00
Ruslan Mustakov
3b8b12833a Rename apigen/apigen.nim to godotapigen.nim 2017-07-31 15:55:52 +07:00
Ruslan Mustakov
7185682025 Dont import with '..' 2017-07-31 13:52:16 +07:00
Ruslan Mustakov
25a21072be Move alloc procs to godotinternal module 2017-07-29 22:00:21 +07:00
Ruslan Mustakov
360be5759e Define Variant and Array in their own modules 2017-07-29 21:50:11 +07:00
Ruslan Mustakov
f30df6d81b Remove redundant imports from the sample 2017-07-28 23:41:48 +07:00
75 changed files with 8572 additions and 3891 deletions

12
.gitignore vendored
View file

@ -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

53
.travis.yml Normal file
View file

@ -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

View file

@ -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
}

View file

@ -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,

View file

@ -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.
Copyright (c) 2018 Xored Software, Inc.

161
docs/docbuild.nim Normal file
View file

@ -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 & " <godotapi/" & moduleHtml & ">`_\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)

97
docs/docpublish.nim Normal file
View file

@ -0,0 +1,97 @@
# Copyright 2018 Xored Software, Inc.
import os, pegs, strutils
import docbuild
const indexTemplate = """<html>
<head><title>godot-nim docs index</title></head>
<body>
<h1>Documentation of Nim bindings for Godot Engine (<a href="https://github.com/$REPO_SLUG">GitHub</a>)</h1><br/>
$VERSION_LIST
</body>
</html>
"""
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("<a href='$1/index.html'>$1</a><br/>" % 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)

12
docs/godotapi.rst Normal file
View file

@ -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

173
docs/index.rst Normal file
View file

@ -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 <https://godotengine.org/>`_ with
`Nim programming language <https://nim-lang.org/>`_. 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 <https://nim-lang.org/docs/tut1.html>`_.
`VSCode <https://code.visualstudio.com/>`_ is the recommended editor for
working with Nim code. It is cross-platform and has the excellent
`nim plugin <https://marketplace.visualstudio.com/items?itemName=kosz78.nim>`_
that supports most of the features you would expect from an IDE.
It also has `godot-tools plugin <https://marketplace.visualstudio.com/items?itemName=geequlim.godot-tools>`_
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
<https://github.com/pragmagic/godot-nim-stub>`_ 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 <godotmacros.html>`_ and `godotnim <godotnim.html>`_ 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 <godotapigen.html>`_ - 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 <godotnim.html>`_ Defines ``NimGodotObject`` and Varaint converters
for standard Nim types.
* `godotmacros <godotmacros.html>`_ Defines ``gdobj`` macro for defining
Godot objects.
* `variants <variants.html>`_ ``Variant`` type represents a "dynamic object"
that many Godot procedures make use of.
* `arrays <arrays.html>`_ Defines ``Array`` of Variants.
* `basis <basis.html>`_ Defines 3D ``Basis``.
* `colors <colors.html>`_ Defines ARGB ``Color``.
* `dictionaries <dictionaries.html>`_ Defines ``Variant`` -> ``Variant``
``Dictionary``.
* `nodepaths <nodepaths.html>`_ Defines ``NodePath`` - a path to a ``Node``.
* `planes <planes.html>`_ Defines 3D ``Plane``.
* `poolarrays <poolarrays.html>`_ Defines pooled arrays: ``PoolByteArray``,
``PoolIntArray``, ``PoolRealArray``, ``PoolVector2Array``,
``PoolVector3Array``, ``PoolColorArray``, ``PoolStringArray``.
* `quats <quats.html>`_ Defines ``Quat`` (quaternion) describing object
rotation in 3D space.
* `rect2 <rect2.html>`_ Defines ``Rect2`` - a 2D rectangle.
* `aabb <aabb.html>`_ Defines ``AABB`` - a 3D box.
* `rids <rids.html>`_ Defines ``RID`` - a resource identifier.
* `transform2d <transform2d.html>`_ Defines ``Transform2D``.
* `transforms <transforms.html>`_ Defines ``Transform``.
* `vector2 <vector2.html>`_ Defines ``Vector2``.
* `vector3 <vector3.html>`_ Defines ``Vector3``.
* `godotbase <godotbase.html>`_ 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
<https://github.com/godotengine/godot/commit/$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 <godotdictionaries.html>`_
* `godotnodepaths <godotnodepaths.html>`_
* `godotpoolarrays <godotpoolarrays.html>`_
* `godotstrings <godotstrings.html>`_
* `godotvariants <godotvariants.html>`_

1
docs/nim.cfg Normal file
View file

@ -0,0 +1 @@
--threads:on

View file

@ -1,5 +0,0 @@
/project/.import
/project/_dlls
/nakefile
/godotapi
nimcache

View file

@ -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.

View file

@ -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..<params.len].join(" ")
proc genGodotApi() =
let godotBin = getEnv("GODOT_BIN")
if godotBin.isNil or godotBin.len == 0:
echo "GODOT_BIN environment variable is not set"
quit(-1)
if not fileExists(godotBin):
echo "Invalid GODOT_BIN path: " & godotBin
quit(-1)
const targetDir = "godotapi"
createDir(targetDir)
const jsonFile = "godotapi"/"api.json"
if not fileExists(jsonFile) or
godotBin.getLastModificationTime() > 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")

View file

@ -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

View file

@ -1,5 +0,0 @@
[gd_resource type="DynamicFontData" format=2]
[resource]
font_path = "res://fonts/Roboto/ttf/Roboto-Regular.ttf"

View file

@ -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.

View file

@ -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" ]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -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

View file

@ -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

View file

@ -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 = ""

View file

@ -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"

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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")

View file

@ -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)

View file

@ -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()

View file

@ -1,8 +0,0 @@
--path:"$projectdir"
--path:"$projectdir/../godotapi"
--experimental
--app:lib
--stackTrace:on
-d:useRealtimeGc
--noMain
--warning[LockLevel]:off

View file

@ -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

View file

@ -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)

View file

@ -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"
requires "nim >= 0.17.3", "compiler >= 0.17.3"

View file

@ -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()

View file

@ -1,3 +0,0 @@
Tool for wrapping Godot API into Nim
apigen [godot binary path] [target directory]

79
godot/core/aabb.nim Normal file
View file

@ -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)

View file

@ -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..<arr.len:
yield arr[i]
iterator items*(self: Array): Variant =
for i in 0..<self.len:
yield self[i]
iterator pairs*(arr: Array): tuple[key: int, val: Variant] {.inline.} =
for i in 0..<arr.len:
yield (i, arr[i])
iterator pairs*(self: Array): tuple[key: int, val: Variant] =
for i in 0..<self.len:
yield (i, self[i])
proc `$`*(self: Array): string =
$self.godotArray

View file

@ -1,11 +1,11 @@
# Copyright (c) 2017 Xored Software, Inc.
# Copyright (c) 2018 Xored Software, Inc.
import math, hashes
import math
import godotbase, vector3, quats
import godotcoretypes
type
Basis* {.byref.} = object
elements*: array[3, Vector3]
{.push stackTrace: off.}
proc setCells*(basis: var Basis, xx, xy, xz, yx, yy, yz, zx, zy, zz: float32) =
basis.elements[0].x = xx
@ -202,6 +202,9 @@ proc `$`*(self: Basis): string {.inline.} =
result.add(", ")
result.add($self[i][j])
proc hash*(self: Basis): Hash {.inline.} =
!$(self.elements[0].hash() !& self.elements[1].hash() !& self.elements[2].hash())
template cofac(row1, col1, row2, col2: int): float32 =
self.elements[row1][col1] * self.elements[row2][col2] -
self.elements[row1][col2] * self.elements[row2][col1]
@ -452,3 +455,5 @@ proc rotate*(self: var Vector3; axis: Vector3; phi: float32) =
proc rotated*(self: Vector3; axis: Vector3; phi: float32): Vector3 =
result = self
result.rotate(axis, phi)
{.pop.} # stackTrace: off

View file

@ -1,13 +1,8 @@
# Copyright (c) 2017 Xored Software, Inc.
# Copyright (c) 2018 Xored Software, Inc.
import godotbase
import hashes
type
Color* {.byref.} = object
r*: float32
g*: float32
b*: float32
a*: float32
import godotcoretypes, gdnativeapi
proc initColor*(r, g, b: float32; a: float32 = 1.0'f32): Color {.inline.} =
Color(
@ -21,12 +16,14 @@ proc initColor*(): Color {.inline.} =
## Initializes black color with 1.0 alpha
initColor(0, 0, 0)
proc h*(self: Color): float32 {.
importc: "godot_color_get_h".}
proc s*(self: Color): float32 {.
importc: "godot_color_get_s".}
proc v*(self: Color): float32 {.
importc: "godot_color_get_v".}
proc h*(self: Color): float32 {.inline.} =
getGDNativeAPI().colorGetH(self)
proc s*(self: Color): float32 {.inline.} =
getGDNativeAPI().colorGetS(self)
proc v*(self: Color): float32 {.inline.} =
getGDNativeAPI().colorGetV(self)
proc `$`*(self: Color): string {.inline.} =
result = newStringOfCap(50)
@ -38,6 +35,9 @@ proc `$`*(self: Color): string {.inline.} =
result.add(", ")
result.add($self.a)
proc hash*(self: Color): Hash {.inline.} =
!$(self.r.hash() !& self.g.hash() !& self.b.hash() !& self.a.hash())
proc toHex(val: float32, target: var string, targetIdx: int) =
let val = clamp(int(val * 255), 0, 255)
let nums = [(val and 0xF0) shr 4, val and 0xF]
@ -60,16 +60,20 @@ proc toARGB32*(self: Color): uint32 {.inline.} =
result = (result shl 8) or uint8(self.g * 255)
result = (result shl 8) or uint8(self.b * 255)
proc gray*(self: Color): float32 {.
importc: "godot_color_gray".}
proc inverted*(self: Color): Color {.
importc: "godot_color_inverted".}
proc contrasted*(self: Color): Color {.
importc: "godot_color_contrasted".}
proc lerp*(self: Color; b: Color; t: float32): Color {.
importc: "godot_color_linear_interpolate".}
proc blend*(self: Color; over: Color): Color {.
importc: "godot_color_blend".}
proc gray*(self: Color): float32 {.inline.} =
getGDNativeAPI().colorGray(self)
proc inverted*(self: Color): Color {.inline.} =
getGDNativeAPI().colorInverted(self).toColor()
proc contrasted*(self: Color): Color {.inline.} =
getGDNativeAPI().colorContrasted(self).toColor()
proc lerp*(self: Color; b: Color; t: float32): Color {.inline.} =
getGDNativeAPI().colorLinearInterpolate(self, b, t).toColor()
proc blend*(self: Color; over: Color): Color {.inline.} =
getGDNativeAPI().colorBlend(self, over).toColor()
proc `==`*(a, b: Color): bool {.inline.} =
a.r == b.r and a.g == b.g and a.b == b.b and a.a == b.a

View file

@ -1,9 +1,8 @@
# Copyright 2017 Xored Software, Inc.
# Copyright 2018 Xored Software, Inc.
import hashes
import godotbase
import "../internal/godotinternaltypes.nim", "../internal/godotstrings.nim",
"../internal/godotdictionaries.nim", "../internal/godotvariants.nim"
import internal/godotinternaltypes, internal/godotdictionaries,
internal/godotvariants, internal/godotstrings
type
Dictionary* = ref object
@ -31,23 +30,30 @@ proc len*(self: Dictionary): int {.inline.} =
proc isEmpty*(self: Dictionary): bool {.inline.} =
self.godotDictionary.isEmpty()
proc clear*(self: var Dictionary) {.inline.} =
proc clear*(self: Dictionary) {.inline.} =
self.godotDictionary.clear()
proc hash*(self: Dictionary): Hash {.inline.} =
hash(self.godotDictionary.godotHash())
import variants, arrays
proc newVariant*(dict: Dictionary): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant[], dict.godotDictionary)
proc asDictionary*(self: Variant): Dictionary {.inline.} =
newDictionary(self.godotVariant[].asGodotDictionary())
proc contains*(self: Dictionary; key: Variant): bool {.inline.}=
self.godotDictionary.contains(key.godotVariant[])
proc contains*(self: Dictionary; keys: Array): bool {.inline.} =
self.godotDictionary.contains(keys.godotArray[])
proc del*(self: var Dictionary; key: Variant) {.inline.} =
proc del*(self: Dictionary; key: Variant) {.inline.} =
self.godotDictionary.del(key.godotVariant[])
proc hash*(self: Dictionary): Hash {.inline.} =
hash(self.godotDictionary.godotHash())
import arrays, variants
proc keys*(self: Dictionary): Array {.inline.} =
newArray(self.godotDictionary.keys())
@ -65,7 +71,7 @@ proc `[]`*(self: Dictionary; keyStr: string): Variant {.inline.} =
godotStr.deinit()
godotVariant.deinit()
proc `[]=`*(self: var Dictionary; key, value: Variant) {.inline.} =
proc `[]=`*(self: Dictionary; key, value: Variant) {.inline.} =
self.godotDictionary[key.godotVariant[]] = value.godotVariant[]
proc `==`*(self, other: Dictionary): bool {.inline.} =
@ -78,16 +84,27 @@ proc toJson*(self: Dictionary): string {.inline.} =
result = $s
s.deinit()
iterator keys*(dict: Dictionary): Variant {.inline.} =
iterator keys*(dict: Dictionary): Variant =
let keyArr = dict.keys()
for key in keyArr:
yield key
iterator values*(dict: Dictionary): Variant {.inline.} =
iterator values*(dict: Dictionary): Variant =
let valArr = dict.values()
for val in valArr:
yield val
iterator pairs*(dict: Dictionary): tuple[key, val: Variant] {.inline.} =
iterator pairs*(dict: Dictionary): tuple[key, val: Variant] =
for key in keys(dict):
yield (key, dict[key])
proc `$`*(self: Dictionary): string =
result = newStringOfCap(32)
result.add('{')
for k, v in self:
if result.len > 1:
result.add(", ")
result.add($k)
result.add(": ")
result.add($v)
result.add('}')

View file

@ -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()

View file

@ -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

1
godot/core/nim.cfg Normal file
View file

@ -0,0 +1 @@
--path:"$projectdir/../"

View file

@ -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()

View file

@ -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)

View file

@ -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..<arr.len:
yield arr[i]
for item in arr.fieldName.items:
yield item
iterator pairs*(arr: T): tuple[key: int, val: DataT] =
for i in 0..<arr.len:
yield (i, arr[i])
for pair in arr.fieldName.pairs:
yield (pair[0].int, pair[1])
iterator mitems*(arr: T): var DataT =
for item in arr.fieldName.mitems:
yield item
iterator mpairs*(arr: T): tuple[key: int, val: var DataT] =
for pair in arr.fieldName.mpairs:
yield (pair[0].int, pair[1])
definePoolArray(PoolByteArray, GodotPoolByteArray, uint8,
godotPoolByteArray, newPoolByteArray,
@ -75,7 +122,7 @@ definePoolArray(PoolByteArray, GodotPoolByteArray, uint8,
definePoolArray(PoolIntArray, GodotPoolIntArray, cint,
godotPoolIntArray, newPoolIntArray,
initGodotPoolIntArray)
definePoolArray(PoolRealArray, GodotPoolRealArray, float64,
definePoolArray(PoolRealArray, GodotPoolRealArray, float32,
godotPoolRealArray, newPoolRealArray,
initGodotPoolRealArray)
definePoolArray(PoolVector2Array, GodotPoolVector2Array, Vector2,
@ -87,27 +134,21 @@ definePoolArray(PoolVector3Array, GodotPoolVector3Array, Vector3,
definePoolArray(PoolColorArray, GodotPoolColorArray, Color,
godotPoolColorArray, newPoolColorArray,
initGodotPoolColorArray)
definePoolArray(PoolStringArray, GodotPoolStringArray, string,
godotPoolStringArray, newPoolStringArray,
initGodotPoolStringArray, true)
proc add*(self: var PoolStringArray; data: string) =
proc add*(self: PoolStringArray; data: string) =
var s = data.toGodotString()
self.godotPoolStringArray.add(s)
s.deinit()
proc addFirst*(self: var PoolStringArray, data: string) =
var s = data.toGodotString()
self.godotPoolStringArray.addFirst(s)
s.deinit()
proc insert*(self: var PoolStringArray; idx: int; data: string): Error =
proc insert*(self: PoolStringArray; idx: int; data: string): Error =
var s = data.toGodotString()
result = self.godotPoolStringArray.insert(idx.cint, s)
s.deinit()
proc `[]=`*(self: var PoolStringArray; idx: int; data: string) =
proc `[]=`*(self: PoolStringArray; idx: int; data: string) =
var s = data.toGodotString()
self.godotPoolStringArray[idx.cint] = s
s.deinit()

View file

@ -1,91 +1,84 @@
# Copyright (c) 2017 Xored Software, Inc.
# Copyright (c) 2018 Xored Software, Inc.
import godotbase, vector3
import "../internal/godotstrings.nim"
import hashes
type
Quat* {.byref.} = object
x*: float32
y*: float32
z*: float32
w*: float32
proc initQuat(dest: var Quat; x, y, z, w: float32) {.
importc: "godot_quat_new".}
proc initQuat(dest: var Quat; axis: Vector3; angle: float32) {.
importc: "godot_quat_new_with_axis_angle".}
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
proc initQuat*(x, y, z, w: float32): Quat {.inline.} =
initQuat(result, x, y, z, w)
result = Quat(
x: x,
y: y,
z: z,
w: w
)
proc initQuat*(axis: Vector3; angle: float32): Quat {.inline.} =
initQuat(result, axis, angle)
proc toGodotString(self: Quat): GodotString {.
noSideEffect,
importc: "godot_quat_as_string".}
getGDNativeAPI().quatNewWithAxisAngle(result, axis, angle)
proc `$`*(self: Quat): string {.inline.} =
$self.toGodotString()
$getGDNativeAPI().quatAsString(self)
proc hash*(self: Quat): Hash {.inline.} =
!$(self.x.hash() !& self.y.hash() !& self.z.hash() !& self.w.hash())
proc length*(self: Quat): float32 {.inline.} =
getGDNativeAPI().quatLength(self)
proc lengthSquared*(self: Quat): float32 {.inline.} =
getGDNativeAPI().quatLengthSquared(self)
proc normalized*(self: Quat): Quat {.inline.} =
getGDNativeAPI().quatNormalized(self).toQuat()
proc isNormalized*(self: Quat): bool {.inline.} =
getGDNativeAPI().quatIsNormalized(self)
proc inverse*(self: Quat): Quat {.inline.} =
getGDNativeAPI().quatInverse(self).toQuat()
proc dot*(a, b: Quat): float32 {.inline.} =
getGDNativeAPI().quatDot(a, b)
proc xform*(self: Quat; v: Vector3): Vector3 {.inline.} =
getGDNativeAPI().quatXform(self, v).toVector3()
proc slerp*(self: Quat; b: Quat; t: float32): Quat {.inline.} =
getGDNativeAPI().quatSlerp(self, b, t).toQuat()
proc slerpni*(self: Quat; b: Quat; t: float32): Quat {.inline.} =
getGDNativeAPI().quatSlerpni(self, b, t).toQuat()
proc cubicSlerp*(self, b, preA, postB: Quat;
t: float32): Quat {.inline.} =
getGDNativeAPI().quatCubicSlerp(self, b, preA, postB, t).toQuat()
proc `*`*(a: Quat, b: float32): Quat {.inline.} =
getGDNativeAPI().quatOperatorMultiply(a, b).toQuat()
proc length*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_length".}
proc lengthSquared*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_length_squared".}
proc normalized*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_normalized".}
proc isNormalized*(self: Quat): bool {.
noSideEffect,
importc: "godot_quat_is_normalized".}
proc inverse*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_inverse".}
proc dot*(a, b: Quat): float32 {.
noSideEffect,
importc: "godot_quat_dot".}
proc xform*(self: Quat; v: Vector3): Vector3 {.
noSideEffect,
importc: "godot_quat_xform".}
proc slerp*(self: Quat; b: Quat; t: float32): Quat {.
noSideEffect,
importc: "godot_quat_slerp".}
proc slerpni*(self: Quat; b: Quat; t: float32): Quat {.
noSideEffect,
importc: "godot_quat_slerpni".}
proc cubicSlerp*(self, b, pre_a, post_b: Quat;
t: float32): Quat {.
noSideEffect,
importc: "godot_quat_cubic_slerp".}
proc `*`*(a: Quat, b: float32): Quat {.
noSideEffect,
importc: "godot_quat_operator_multiply".}
proc `*=`*(a: var Quat, b: float32) {.inline.} =
a = a * b
proc `+`*(a, b: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_add".}
proc `+`*(a, b: Quat): Quat {.inline.} =
getGDNativeAPI().quatOperatorAdd(a, b).toQuat()
proc `+=`*(a: var Quat, b: Quat) {.inline.} =
a = a + b
proc `-`*(a, b: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_substract".}
proc `-`*(a, b: Quat): Quat {.inline.} =
getGDNativeAPI().quatOperatorSubtract(a, b).toQuat()
proc `-=`* (a: var Quat, b: Quat) {.inline.} =
a = a - b
proc `/`*(self: Quat; b: float32): Quat {.
noSideEffect,
importc: "godot_quat_operator_divide".}
proc `/`*(self: Quat; b: float32): Quat {.inline.} =
getGDNativeAPI().quatOperatorDivide(self, b).toQuat()
proc `/=`*(self: var Quat, b: float32) {.inline.} =
self = self / b
proc `==`*(a, b: Quat): bool {.
noSideEffect,
importc: "godot_quat_operator_equal".}
proc `-`*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_neg".}
proc `==`*(a, b: Quat): bool {.inline.} =
getGDNativeAPI().quatOperatorEqual(a, b)
proc `-`*(self: Quat): Quat {.inline.} =
getGDNativeAPI().quatOperatorNeg(self).toQuat()

View file

@ -1,54 +1,153 @@
# Copyright (c) 2017 Xored Software, Inc.
# Copyright (c) 2018 Xored Software, Inc.
import godotbase, vector2
import hashes
import "../internal/godotstrings.nim"
import vector2
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
type
Rect2* {.byref.} = object
position*: Vector2
size*: Vector2
{.push stackTrace: off.}
proc initRect2*(pos, size: Vector2): Rect2 {.inline.} =
proc initRect2*(): Rect2 {.inline, noinit.} =
Rect2()
proc initRect2*(pos, size: Vector2): Rect2 {.inline, noinit.} =
Rect2(position: pos, size: size)
proc initRect2*(x, y, sizeX, sizeY: float32): Rect2 {.inline.} =
proc initRect2*(x, y, sizeX, sizeY: float32): Rect2 {.inline, noinit.} =
Rect2(position: vec2(x, y), size: vec2(sizeX, sizeY))
proc toGodotString(self: Rect2): GodotString {.
noSideEffect,
importc: "godot_rect2_as_string".}
proc `$`*(self: Rect2): string {.inline, noinit.} =
$getGDNativeAPI().rect2AsString(self)
proc `$`*(self: Rect2): string {.inline.} =
$self.toGodotString()
proc hash*(self: Rect2): Hash {.inline, noinit.} =
!$(self.position.hash() !& self.size.hash())
proc area*(self: Rect2): float32 {.
noSideEffect,
importc: "godot_rect2_get_area".}
proc intersects*(a, b: Rect2): bool {.
noSideEffect,
importc: "godot_rect2_intersects".}
proc encloses*(a, b: Rect2): bool {.
noSideEffect,
importc: "godot_rect2_encloses".}
proc hasNoArea*(self: Rect2): bool {.
noSideEffect,
importc: "godot_rect2_has_no_area".}
proc clip*(a, b: Rect2): Rect2 {.
noSideEffect,
importc: "godot_rect2_clip".}
proc merge*(a, b: Rect2): Rect2 {.
noSideEffect,
importc: "godot_rect2_merge".}
proc contains*(self: Rect2; point: Vector2): bool {.
noSideEffect,
importc: "godot_rect2_has_point".}
proc grow*(self: Rect2; by: float32): Rect2 {.
noSideEffect,
importc: "godot_rect2_grow".}
proc expand*(self: Rect2; to: Vector2): Rect2 {.
noSideEffect,
importc: "godot_rect2_expand".}
proc `==`*(a, b: Rect2): bool {.
noSideEffect,
importc: "godot_rect2_operator_equal".}
proc area*(self: Rect2): float32 {.inline, noinit.} =
self.size.x * self.size.y
proc intersects*(a, b: Rect2): bool {.inline, noinit.} =
if a.position.x >= (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

View file

@ -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".}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

3617
godot/gdnativeapi.nim Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,18 @@
# Copyright 2017 Xored Software, Inc.
# Copyright 2018 Xored Software, Inc.
import core.godotbase, godotinternal
import core / [vector2, rect2, vector3, transform2d, planes, quats]
import core / [rect3, basis, transforms, colors, nodepaths, rids]
import core / [dictionaries, arrays, poolarrays, variants]
import core/godotbase, godotinternal
import core/godotcoretypes
import core/vector2, core/rect2, core/vector3, core/transform2d, core/planes,
core/quats
import core/aabb, core/basis, core/transforms, core/colors, core/nodepaths,
core/rids
import core/dictionaries, core/arrays, core/poolarrays, core/variants
import nim / [godotmacros, godotnim]
import nim/godotmacros, nim/godotnim
export godotbase, vector2, rect2, vector3, transform2d, planes, quats,
rect3, basis, transforms, colors, nodepaths, rids, dictionaries, arrays,
poolarrays, variants
export godotbase, godotcoretypes, vector2, rect2, vector3, transform2d, planes,
quats, aabb, basis, transforms, colors, nodepaths, rids, dictionaries,
arrays, poolarrays, variants
export godotmacros, godotnim
export GodotPropertyHint, GodotPropertyUsage

2
godot/godot.nim.cfg Normal file
View file

@ -0,0 +1,2 @@
--path:"$projectdir"
-d:useRealtimeGc

1115
godot/godotapigen.nim Normal file

File diff suppressed because it is too large Load diff

View file

@ -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
type
GodotNativeInitOptions* = object
inEditor*: bool
coreApiHash*: uint64
editorApiHash*: uint64
noApiHash*: uint64
gdNativeLibrary*: ptr GodotObject
GodotNativeTerminateOptions* = 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
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;
proc nativeScriptRegisterClass*(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.}
destroyFunc: GodotInstanceDestroyFunc)
{.inline.} =
getGDNativeAPI().nativeScriptRegisterClass(
libHandle, name, base, createFunc, destroyFunc)
proc godotScriptRegisterMethod*(libHandle: pointer;
proc nativeScriptRegisterToolClass*(libHandle: pointer; name, base: cstring;
createFunc: GodotInstanceCreateFunc;
destroyFunc: GodotInstanceDestroyFunc)
{.inline.} =
getGDNativeAPI().nativeScriptRegisterToolClass(
libHandle, name, base, createFunc, destroyFunc)
proc nativeScriptRegisterMethod*(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.}
meth: GodotInstanceMethod) {.inline.} =
getGDNativeAPI().nativeScriptRegisterMethod(
libHandle, name, functionName, attr, meth)
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;
proc nativeScriptRegisterProperty*(libHandle: pointer;
name, path: cstring;
attr: ptr GodotPropertyAttributes;
setFunc: GodotPropertySetFunc;
getFunc: GodotPropertyGetFunc) {.
importc: "godot_nativescript_register_property".}
getFunc: GodotPropertyGetFunc) {.inline.} =
getGDNativeAPI().nativeScriptRegisterProperty(
libHandle, name, path, attr, setFunc, getFunc)
type
GodotSignalArgument* {.bycopy.} = object
name*: GodotString
typ*: cint
hint*: GodotPropertyHint
hintString*: GodotString
usage*: GodotPropertyUsageFlags
defaultValue*: GodotVariant
proc nativeScriptRegisterSignal*(libHandle: pointer; name: cstring;
signal: GodotSignal) {.inline.} =
getGDNativeAPI().nativeScriptRegisterSignal(libHandle, name, signal)
GodotSignal* = object
name*: GodotString
numArgs*: cint
args*: ptr GodotSignalArgument
numDefaultArgs*: cint
defaultArgs*: ptr GodotVariant
proc getUserdata*(instance: ptr GodotObject): pointer {.inline.} =
getGDNativeAPI().nativeScriptGetUserdata(instance)
proc getClassConstructor*(className: cstring): GodotClassConstructor
{.inline.} =
getGDNativeAPI().getClassConstructor(className)
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)

View file

@ -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]()

View file

@ -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..<arr.len:
yield arr[i]
proc sort*(self: var GodotArray) {.inline.} =
getGDNativeAPI().arraySort(self)
iterator mitems*(arr: var GodotArray): var GodotVariant =
for i in 0..<arr.len:
yield arr.mget(i)[]
proc sortCustom*(self: var GodotArray; obj: ptr GodotObject;
funcName: GodotString) {.inline.} =
getGDNativeAPI().arraySortCustom(self, obj, funcName)
iterator pairs*(arr: GodotArray): tuple[key: cint, val: GodotVariant] =
for i in 0..<arr.len:
yield (i, arr[i])
proc binarySearch*(self: var GodotArray, val: ptr GodotVariant,
before: bool) {.inline.} =
getGDNativeAPI().arrayBSearch(self, val, before)
iterator mpairs*(arr: var GodotArray): tuple[key: cint, val: var GodotVariant] =
for i in 0..<arr.len:
yield (i, arr.mget(i)[])
proc binarySearchCustom*(self: var GodotArray, val: ptr GodotVariant,
obj: ptr GodotObject, funcName: GodotString,
before: bool) {.inline.} =
getGDNativeAPI().arrayBSearchCustom(self, val, obj, funcName, before)
iterator items*(self: GodotArray): GodotVariant =
for i in 0.cint..<self.len:
yield self[i]
iterator mitems*(self: var GodotArray): var GodotVariant =
for i in 0.cint..<self.len:
yield self.mget(i)[]
iterator pairs*(self: GodotArray): tuple[key: cint, val: GodotVariant] =
for i in 0.cint..<self.len:
yield (i, self[i])
iterator mpairs*(self: var GodotArray): tuple[key: cint,
val: var GodotVariant] =
for i in 0.cint..<self.len:
yield (i, self.mget(i)[])
proc `$`*(self: GodotArray): string =
result = newStringOfCap(32)
result.add('[')
for item in self:
if result.len > 1:
result.add(", ")
result.add($item)
result.add(']')

View file

@ -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)

View file

@ -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]
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)))

View file

@ -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)

View file

@ -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..<arr.len:
yield arr[i]
proc reverse*(self: var ArrayT) {.inline.} =
getGDNativeAPI().invertProc(self)
iterator pairs*(arr: GodotPoolByteArray): tuple[key: cint, val: byte] =
for i in 0..<arr.len:
yield (i, arr[i])
proc setLen*(self: var ArrayT; size: cint) {.inline.} =
getGDNativeAPI().resizeProc(self, size)
proc initGodotPoolIntArray*(dest: var GodotPoolIntArray) {.
importc: "godot_pool_int_array_new".}
proc initGodotPoolIntArray*(dest: var GodotPoolIntArray;
src: GodotPoolIntArray) {.
importc: "godot_pool_int_array_new_copy".}
proc initGodotPoolIntArray*(dest: var GodotPoolIntArray;
arr: GodotArray) {.
importc: "godot_pool_int_array_new_with_array".}
proc deinit*(self: var GodotPoolIntArray) {.
importc: "godot_pool_int_array_destroy".}
proc `[]=`*(self: var ArrayT; idx: cint; data: DataT) {.inline.} =
getGDNativeAPI().setProc(self, idx, data)
proc add*(self: var GodotPoolIntArray; data: cint) {.
importc: "godot_pool_int_array_append".}
proc addFirst*(self: var GodotPoolIntArray; data: cint) {.
importc: "godot_pool_int_array_push_back".}
proc add*(self: var GodotPoolIntArray; arr: GodotPoolIntArray) {.
importc: "godot_pool_int_array_append_array".}
proc insert*(self: var GodotPoolIntArray; idx: cint;
data: cint): Error {.
importc: "godot_pool_int_array_insert".}
proc delete*(self: var GodotPoolIntArray; idx: cint) {.
importc: "godot_pool_int_array_remove".}
proc reverse*(self: var GodotPoolIntArray) {.
importc: "godot_pool_int_array_invert".}
proc `[]`*(self: ArrayT; idx: cint): DataT {.inline.} =
let data = getGDNativeAPI().getProc(self, idx)
when DataT is Color:
data.toColor()
elif DataT is Vector2:
data.toVector2()
elif DataT is Vector3:
data.toVector3()
else:
data
proc setLen*(self: var GodotPoolIntArray; size: cint) {.
importc: "godot_pool_int_array_resize".}
proc `[]=`*(self: var GodotPoolIntArray; idx: cint; data: cint) {.
importc: "godot_pool_int_array_set".}
proc `[]`*(self: GodotPoolIntArray; idx: cint): cint {.
noSideEffect,
importc: "godot_pool_int_array_get".}
proc len*(self: GodotPoolIntArray): cint {.
noSideEffect,
importc: "godot_pool_int_array_size".}
proc len*(self: ArrayT): cint {.inline.} =
getGDNativeAPI().sizeProc(self)
iterator items*(arr: GodotPoolIntArray): cint =
for i in 0..<arr.len:
yield arr[i]
iterator items*(self: ArrayT): DataT =
let readAccess = getGDNativeAPI().readProc(self)
let readPtr = getGDNativeAPI().readAccessPtrProc(readAccess)
for i in 0.cint..<self.len:
yield readPtr.offset(i)[]
getGDNativeAPI().readAccessDestroyProc(readAccess)
iterator pairs*(arr: GodotPoolIntArray): tuple[key: cint, val: cint] =
for i in 0..<arr.len:
yield (i, arr[i])
iterator mitems*(self: var ArrayT): var DataT =
let writeAccess = getGDNativeAPI().writeProc(self)
let writePtr = getGDNativeAPI().writeAccessPtrProc(writeAccess)
for i in 0.cint..<self.len:
yield writePtr.offset(i)[]
getGDNativeAPI().writeAccessDestroyProc(writeAccess)
# Real
iterator pairs*(self: ArrayT): tuple[key: cint, val: DataT] =
let readAccess = getGDNativeAPI().readProc(self)
let readPtr = getGDNativeAPI().readAccessPtrProc(readAccess)
for i in 0.cint..<self.len:
yield (i, readPtr.offset(i)[])
getGDNativeAPI().readAccessDestroyProc(readAccess)
proc initGodotPoolRealArray*(dest: var GodotPoolRealArray) {.
importc: "godot_pool_real_array_new".}
proc initGodotPoolRealArray*(dest: var GodotPoolRealArray;
src: GodotPoolRealArray) {.
importc: "godot_pool_real_array_new_copy".}
proc initGodotPoolRealArray*(dest: var GodotPoolRealArray; arr: GodotArray) {.
importc: "godot_pool_real_array_new_with_array".}
iterator mpairs*(self: var ArrayT): tuple[key: cint, val: var DataT] =
let writeAccess = getGDNativeAPI().writeProc(self)
let writePtr = getGDNativeAPI().writeAccessPtrProc(writeAccess)
for i in 0.cint..<self.len:
yield (i, writePtr.offset(i)[])
getGDNativeAPI().writeAccessDestroyProc(writeAccess)
proc deinit*(self: var GodotPoolRealArray) {.
importc: "godot_pool_real_array_destroy".}
proc subarray*(self: ArrayT, idxFrom, idxTo: cint): ArrayT =
## Indexes are inclusive, negative values count from the end of the array.
let ownLen = self.len
var actualIdxFrom = if idxFrom < 0: idxFrom + ownLen
else: idxFrom
var actualIdxTo = if idxTo < 0: idxTo + ownLen
else: idxTo
proc add*(self: var GodotPoolRealArray; data: float32) {.
importc: "godot_pool_real_array_append".}
proc addFirst*(self: var GodotPoolRealArray; data: float32) {.
importc: "godot_pool_real_array_push_back".}
proc add*(self: var GodotPoolRealArray; arr: GodotPoolRealArray) {.
importc: "godot_pool_real_array_append_array".}
proc insert*(self: var GodotPoolRealArray;
idx: cint; data: float32): Error {.
importc: "godot_pool_real_array_insert".}
proc delete*(self: var GodotPoolRealArray; idx: cint) {.
importc: "godot_pool_real_array_remove".}
proc reverse*(self: var GodotPoolRealArray) {.
importc: "godot_pool_real_array_invert".}
proc setLen*(self: var GodotPoolRealArray; size: cint) {.
importc: "godot_pool_real_array_resize".}
proc `[]=`*(self: var GodotPoolRealArray; idx: cint; data: float32) {.
importc: "godot_pool_real_array_set".}
proc `[]`*(self: GodotPoolRealArray; idx: cint): float32 {.
noSideEffect,
importc: "godot_pool_real_array_get".}
proc len*(self: GodotPoolRealArray): cint {.
noSideEffect,
importc: "godot_pool_real_array_size".}
initIdent(result)
if actualIdxFrom < 0 or actualIdxFrom >= 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..<arr.len:
yield arr[i]
genPoolArrayAPI(GodotPoolByteArray, initGodotPoolByteArray, byte,
poolByteArrayNew,
poolByteArrayNewCopy,
poolByteArrayNewWithArray,
poolByteArrayAppend,
poolByteArrayAppendArray,
poolByteArrayInsert,
poolByteArrayInvert,
poolByteArrayPushBack,
poolByteArrayRemove,
poolByteArrayResize,
poolByteArraySet,
poolByteArrayGet,
poolByteArraySize,
poolByteArrayDestroy,
poolByteArrayRead,
poolByteArrayWrite,
poolByteArrayReadAccessPtr,
poolByteArrayWriteAccessPtr,
poolByteArrayReadAccessDestroy,
poolByteArrayWriteAccessDestroy)
iterator pairs*(arr: GodotPoolRealArray): tuple[key: cint, val: float32] =
for i in 0..<arr.len:
yield (i, arr[i])
genPoolArrayAPI(GodotPoolIntArray, initGodotPoolIntArray, cint,
poolIntArrayNew,
poolIntArrayNewCopy,
poolIntArrayNewWithArray,
poolIntArrayAppend,
poolIntArrayAppendArray,
poolIntArrayInsert,
poolIntArrayInvert,
poolIntArrayPushBack,
poolIntArrayRemove,
poolIntArrayResize,
poolIntArraySet,
poolIntArrayGet,
poolIntArraySize,
poolIntArrayDestroy,
poolIntArrayRead,
poolIntArrayWrite,
poolIntArrayReadAccessPtr,
poolIntArrayWriteAccessPtr,
poolIntArrayReadAccessDestroy,
poolIntArrayWriteAccessDestroy)
# String
genPoolArrayAPI(GodotPoolRealArray, initGodotPoolRealArray, float32,
poolRealArrayNew,
poolRealArrayNewCopy,
poolRealArrayNewWithArray,
poolRealArrayAppend,
poolRealArrayAppendArray,
poolRealArrayInsert,
poolRealArrayInvert,
poolRealArrayPushBack,
poolRealArrayRemove,
poolRealArrayResize,
poolRealArraySet,
poolRealArrayGet,
poolRealArraySize,
poolRealArrayDestroy,
poolRealArrayRead,
poolRealArrayWrite,
poolRealArrayReadAccessPtr,
poolRealArrayWriteAccessPtr,
poolRealArrayReadAccessDestroy,
poolRealArrayWriteAccessDestroy)
proc initGodotPoolStringArray*(dest: var GodotPoolStringArray) {.
importc: "godot_pool_string_array_new".}
proc initGodotPoolStringArray*(dest: var GodotPoolStringArray;
src: GodotPoolStringArray) {.
importc: "godot_pool_string_array_new_copy".}
proc initGodotPoolStringArray*(dest: var GodotPoolStringArray; arr: GodotArray) {.
importc: "godot_pool_string_array_new_with_array".}
genPoolArrayAPI(GodotPoolStringArray, initGodotPoolStringArray, GodotString,
poolStringArrayNew,
poolStringArrayNewCopy,
poolStringArrayNewWithArray,
poolStringArrayAppend,
poolStringArrayAppendArray,
poolStringArrayInsert,
poolStringArrayInvert,
poolStringArrayPushBack,
poolStringArrayRemove,
poolStringArrayResize,
poolStringArraySet,
poolStringArrayGet,
poolStringArraySize,
poolStringArrayDestroy,
poolStringArrayRead,
poolStringArrayWrite,
poolStringArrayReadAccessPtr,
poolStringArrayWriteAccessPtr,
poolStringArrayReadAccessDestroy,
poolStringArrayWriteAccessDestroy)
proc deinit*(self: var GodotPoolStringArray) {.
importc: "godot_pool_string_array_destroy".}
genPoolArrayAPI(GodotPoolVector2Array, initGodotPoolVector2Array, Vector2,
poolVector2ArrayNew,
poolVector2ArrayNewCopy,
poolVector2ArrayNewWithArray,
poolVector2ArrayAppend,
poolVector2ArrayAppendArray,
poolVector2ArrayInsert,
poolVector2ArrayInvert,
poolVector2ArrayPushBack,
poolVector2ArrayRemove,
poolVector2ArrayResize,
poolVector2ArraySet,
poolVector2ArrayGet,
poolVector2ArraySize,
poolVector2ArrayDestroy,
poolVector2ArrayRead,
poolVector2ArrayWrite,
poolVector2ArrayReadAccessPtr,
poolVector2ArrayWriteAccessPtr,
poolVector2ArrayReadAccessDestroy,
poolVector2ArrayWriteAccessDestroy)
proc initGodotPoolStringArray*(): GodotPoolStringArray {.inline.} =
initGodotPoolStringArray(result)
genPoolArrayAPI(GodotPoolVector3Array, initGodotPoolVector3Array, Vector3,
poolVector3ArrayNew,
poolVector3ArrayNewCopy,
poolVector3ArrayNewWithArray,
poolVector3ArrayAppend,
poolVector3ArrayAppendArray,
poolVector3ArrayInsert,
poolVector3ArrayInvert,
poolVector3ArrayPushBack,
poolVector3ArrayRemove,
poolVector3ArrayResize,
poolVector3ArraySet,
poolVector3ArrayGet,
poolVector3ArraySize,
poolVector3ArrayDestroy,
poolVector3ArrayRead,
poolVector3ArrayWrite,
poolVector3ArrayReadAccessPtr,
poolVector3ArrayWriteAccessPtr,
poolVector3ArrayReadAccessDestroy,
poolVector3ArrayWriteAccessDestroy)
proc initGodotPoolStringArray*(arr: GodotArray): GodotPoolStringArray {.inline.} =
initGodotPoolStringArray(result, arr)
proc add*(self: var GodotPoolStringArray; data: GodotString) {.
importc: "godot_pool_string_array_append".}
proc addFirst*(self: var GodotPoolStringArray; data: GodotString) {.
importc: "godot_pool_string_array_push_back".}
proc add*(self: var GodotPoolStringArray; arr: GodotPoolStringArray) {.
importc: "godot_pool_string_array_append_array".}
proc insert*(self: var GodotPoolStringArray;
idx: cint; data: GodotString): Error {.
importc: "godot_pool_string_array_insert".}
proc delete*(self: var GodotPoolStringArray; idx: cint) {.
importc: "godot_pool_string_array_remove".}
proc reverse*(self: var GodotPoolStringArray) {.
importc: "godot_pool_string_array_invert".}
proc setLen*(self: var GodotPoolStringArray; size: cint) {.
importc: "godot_pool_string_array_resize".}
proc `[]=`*(self: var GodotPoolStringArray; idx: cint;
data: GodotString) {.
importc: "godot_pool_string_array_set".}
proc `[]`*(self: GodotPoolStringArray; idx: cint): GodotString {.
noSideEffect,
importc: "godot_pool_string_array_get".}
proc len*(self: GodotPoolStringArray): cint {.
noSideEffect,
importc: "godot_pool_string_array_size".}
iterator items*(arr: GodotPoolStringArray): GodotString =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: GodotPoolStringArray): tuple[key: cint, val: GodotString] =
for i in 0..<arr.len:
yield (i, arr[i])
# Vector2
proc initGodotPoolVector2Array*(dest: var GodotPoolVector2Array) {.
importc: "godot_pool_vector2_array_new".}
proc initGodotPoolVector2Array*(dest: var GodotPoolVector2Array;
src: GodotPoolVector2Array) {.
importc: "godot_pool_vector2_array_new_copy".}
proc initGodotPoolVector2Array*(dest: var GodotPoolVector2Array;
arr: GodotArray) {.
importc: "godot_pool_vector2_array_new_with_array".}
proc deinit*(self: var GodotPoolVector2Array) {.
importc: "godot_pool_vector2_array_destroy".}
proc initGodotPoolVector2Array*(): GodotPoolVector2Array {.inline.} =
initGodotPoolVector2Array(result)
proc initGodotPoolVector2Array*(arr: GodotArray): GodotPoolVector2Array {.inline.} =
initGodotPoolVector2Array(result, arr)
proc add*(self: var GodotPoolVector2Array; data: Vector2) {.
importc: "godot_pool_vector2_array_append".}
proc addFirst*(self: var GodotPoolVector2Array; data: Vector2) {.
importc: "godot_pool_vector2_array_push_back".}
proc add*(self: var GodotPoolVector2Array;
arr: GodotPoolVector2Array) {.
importc: "godot_pool_vector2_array_append_array".}
proc insert*(self: var GodotPoolVector2Array;
idx: cint; data: Vector2): Error {.
importc: "godot_pool_vector2_array_insert".}
proc delete*(self: var GodotPoolVector2Array; idx: cint) {.
importc: "godot_pool_vector2_array_remove".}
proc reverse*(self: var GodotPoolVector2Array) {.
importc: "godot_pool_vector2_array_invert".}
proc setLen*(self: var GodotPoolVector2Array; size: cint) {.
importc: "godot_pool_vector2_array_resize".}
proc `[]=`*(self: var GodotPoolVector2Array; idx: cint;
data: Vector2) {.
importc: "godot_pool_vector2_array_set".}
proc `[]`*(self: GodotPoolVector2Array; idx: cint): Vector2 {.
noSideEffect,
importc: "godot_pool_vector2_array_get".}
proc len*(self: GodotPoolVector2Array): cint {.
noSideEffect,
importc: "godot_pool_vector2_array_size".}
iterator items*(arr: GodotPoolVector2Array): Vector2 =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: GodotPoolVector2Array): tuple[key: cint, val: Vector2] =
for i in 0..<arr.len:
yield (i, arr[i])
# Vector3
proc initGodotPoolVector3Array*(dest: var GodotPoolVector3Array) {.
importc: "godot_pool_vector3_array_new".}
proc initGodotPoolVector3Array*(dest: var GodotPoolVector3Array;
src: GodotPoolVector3Array) {.
importc: "godot_pool_vector3_array_new_copy".}
proc initGodotPoolVector3Array*(dest: var GodotPoolVector3Array;
arr: GodotArray) {.
importc: "godot_pool_vector3_array_new_with_array".}
proc deinit*(self: var GodotPoolVector3Array) {.
importc: "godot_pool_vector3_array_destroy".}
proc initGodotPoolVector3Array*(): GodotPoolVector3Array {.inline.} =
initGodotPoolVector3Array(result)
proc initGodotPoolVector3Array*(arr: GodotArray):
GodotPoolVector3Array {.inline.} =
initGodotPoolVector3Array(result, arr)
proc add*(self: var GodotPoolVector3Array;
data: Vector3) {.
importc: "godot_pool_vector3_array_append".}
proc addFirst*(self: var GodotPoolVector3Array;
data: Vector3) {.
importc: "godot_pool_vector3_array_push_back".}
proc add*(self: var GodotPoolVector3Array;
arr: GodotPoolVector3Array) {.
importc: "godot_pool_vector3_array_append_array".}
proc insert*(self: var GodotPoolVector3Array;
idx: cint; data: Vector3): Error {.
importc: "godot_pool_vector3_array_insert".}
proc delete*(self: var GodotPoolVector3Array; idx: cint) {.
importc: "godot_pool_vector3_array_remove".}
proc reverse*(self: var GodotPoolVector3Array) {.
importc: "godot_pool_vector3_array_invert".}
proc setLen*(self: var GodotPoolVector3Array; size: cint) {.
importc: "godot_pool_vector3_array_resize".}
proc `[]=`*(self: var GodotPoolVector3Array;
idx: cint; data: Vector3) {.
importc: "godot_pool_vector3_array_set".}
proc `[]`*(self: GodotPoolVector3Array;
idx: cint): Vector3 {.
noSideEffect,
importc: "godot_pool_vector3_array_get".}
proc len*(self: GodotPoolVector3Array): cint {.
noSideEffect,
importc: "godot_pool_vector3_array_size".}
iterator items*(arr: GodotPoolVector3Array): Vector3 =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: GodotPoolVector3Array): tuple[key: cint, val: Vector3] =
for i in 0..<arr.len:
yield (i, arr[i])
# Color
proc initGodotPoolColorArray*(dest: var GodotPoolColorArray) {.
importc: "godot_pool_color_array_new".}
proc initGodotPoolColorArray*(dest: var GodotPoolColorArray;
src: GodotPoolColorArray) {.
importc: "godot_pool_color_array_new_copy".}
proc initGodotPoolColorArray*(dest: var GodotPoolColorArray; arr: GodotArray) {.
importc: "godot_pool_color_array_new_with_array".}
proc deinit*(self: var GodotPoolColorArray) {.
importc: "godot_pool_color_array_destroy".}
proc initGodotPoolColorArray*(): GodotPoolColorArray {.inline.} =
initGodotPoolColorArray(result)
proc initGodotPoolColorArray*(arr: GodotArray): GodotPoolColorArray {.inline.} =
initGodotPoolColorArray(result, arr)
proc add*(self: var GodotPoolColorArray; data: Color) {.
importc: "godot_pool_color_array_append".}
proc addFirst*(self: var GodotPoolColorArray; data: Color) {.
importc: "godot_pool_color_array_push_back".}
proc add*(self: var GodotPoolColorArray; arr: GodotPoolColorArray) {.
importc: "godot_pool_color_array_append_array".}
proc insert*(self: var GodotPoolColorArray;
idx: cint; data: Color): Error {.
importc: "godot_pool_color_array_insert".}
proc delete*(self: var GodotPoolColorArray; idx: cint) {.
importc: "godot_pool_color_array_remove".}
proc reverse*(self: var GodotPoolColorArray) {.
importc: "godot_pool_color_array_invert".}
proc setLen*(self: var GodotPoolColorArray; size: cint) {.
importc: "godot_pool_color_array_resize".}
proc `[]=`*(self: var GodotPoolColorArray; idx: cint;
data: Color) {.
importc: "godot_pool_color_array_set".}
proc `[]`*(self: GodotPoolColorArray; idx: cint): Color {.
noSideEffect,
importc: "godot_pool_color_array_get".}
proc len*(self: GodotPoolColorArray): cint {.
noSideEffect,
importc: "godot_pool_color_array_size".}
iterator items*(arr: GodotPoolColorArray): Color =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: GodotPoolColorArray): tuple[key: cint, val: Color] =
for i in 0..<arr.len:
yield (i, arr[i])
genPoolArrayAPI(GodotPoolColorArray, initGodotPoolColorArray, Color,
poolColorArrayNew,
poolColorArrayNewCopy,
poolColorArrayNewWithArray,
poolColorArrayAppend,
poolColorArrayAppendArray,
poolColorArrayInsert,
poolColorArrayInvert,
poolColorArrayPushBack,
poolColorArrayRemove,
poolColorArrayResize,
poolColorArraySet,
poolColorArrayGet,
poolColorArraySize,
poolColorArrayDestroy,
poolColorArrayRead,
poolColorArrayWrite,
poolColorArrayReadAccessPtr,
poolColorArrayWriteAccessPtr,
poolColorArrayReadAccessDestroy,
poolColorArrayWriteAccessDestroy)

View file

@ -1,50 +1,50 @@
# Copyright (c) 2017 Xored Software, Inc.
# Copyright (c) 2018 Xored Software, Inc.
type
GodotString* {.byref.} = object
p: pointer
import godotinternaltypes, gdnativeapi
proc initGodotString(dest: var GodotString) {.inline, raises: [].} =
getGDNativeAPI().stringNew(dest)
proc initGodotString(dest: var GodotString) {.
importc: "godot_string_new".}
proc initGodotString(dest: var GodotString; contents: cstring;
size: cint) {.
importc: "godot_string_new_data".}
size: cint) {.inline.} =
## Initializes ``dest`` from UTF-8 ``contents``
proc getData(self: GodotString; dest: cstring;
size: var cint) {.
noSideEffect
importc: "godot_string_get_data".}
## Converts ``self`` into UTF-8 encoding, putting the result into ``dest``.
dest = getGDNativeAPI().stringCharsToUtf8WithLen(contents, size)
proc `==`*(self, b: GodotString): bool {.inline.} =
getGDNativeAPI().stringOperatorEqual(self, b)
proc `<`*(self, b: GodotString): bool {.inline.} =
getGDNativeAPI().stringOperatorLess(self, b)
proc `&`*(self, b: GodotString): GodotString {.inline.} =
getGDNativeAPI().stringOperatorPlus(self, b)
proc deinit*(self: var GodotString) {.inline.} =
getGDNativeAPI().stringDestroy(self)
proc len*(self: GodotString): cint {.inline.} =
## Returns the length of string in bytes if it is represented as UTF-8.
getData(self, nil, result)
getGDNativeAPI().stringLength(self)
proc cstring*(self: GodotString): cstring {.
importc: "godot_string_c_str".}
proc `==`*(self, b: GodotString): bool {.
importc: "godot_string_operator_equal".}
proc `<`*(self, b: GodotString): bool {.
importc: "godot_string_operator_less".}
proc `&`*(self, b: GodotString): GodotString {.
importc: "godot_string_operator_plus".}
proc deinit*(self: var GodotString) {.importc: "godot_string_destroy".}
proc dataPtr*(self: GodotString): ptr cwchar_t {.inline.} =
getGDNativeAPI().stringWideStr(self)
proc `$`*(self: GodotString): string =
## Converts the ``GodotString`` into Nim string
var length = self.len
result = newStringOfCap(length)
getData(self, addr result[0], length)
result.setLen(length)
assert(result[length] == '\0')
var charStr = getGDNativeAPI().stringUtf8(self)
let length = getGDNativeAPI().charStringLength(charStr)
result = newString(length)
copyMem(addr result[0], getGDNativeAPI().charStringGetData(charStr), length)
getGDNativeAPI().charStringDestroy(charStr)
proc toGodotString*(s: string): GodotString {.inline.} =
## Converts the Nim string into ``GodotString``
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
if s.isNil:
initGodotString(result)
else:
initGodotString(result, unsafeAddr s[0], cint(s.len + 1))
initGodotString(result, cstring(s), cint(s.len + 1))
else:
initGodotString(result, cstring(s), cint(s.len + 1))
proc toGodotString*(s: cstring): GodotString {.inline.} =
## Converts the cstring into ``GodotString``

View file

@ -1,190 +1,217 @@
# Copyright 2017 Xored Software, Inc.
# Copyright 2018 Xored Software, Inc.
type
VariantType* {.size: sizeof(cint), pure.} = enum
Nil, ## atomic types
Bool,
Int,
Real,
String,
# math types
Vector2, ## 5
Rect2,
Vector3,
Transform2D,
Plane,
Quat, ## 10
Rect3,
Basis,
Transform, ## misc types
Color,
NodePath, ## 15
RID,
Object,
Dictionary,
Array, ## 20
# arrays
PoolByteArray,
PoolIntArray,
PoolRealArray,
PoolStringArray,
PoolVector2Array, ## 25
PoolVector3Array,
PoolColorArray
import core/godotcoretypes, godotinternaltypes, gdnativeapi
VariantCallErrorType* {.size: sizeof(cint), pure.} = enum
OK,
InvalidMethod,
InvalidArgument,
TooManyArguments,
TooFewArguments,
InstanceIsNull
proc getType*(p: GodotVariant): VariantType {.inline.} =
getGDNativeAPI().variantGetType(p)
VariantCallError* = object
error*: VariantCallErrorType
argument*: cint
expected*: VariantType
proc initGodotVariant*(dest: var GodotVariant) {.inline.} =
getGDNativeAPI().variantNewNil(dest)
import godotinternaltypes, godotpoolarrays, godotstrings, godotnodepaths,
godotdictionaries
proc initGodotVariant*(dest: var GodotVariant, src: GodotVariant) {.inline.} =
getGDNativeAPI().variantNewCopy(dest, src)
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/rids.nim",
"../core/rect2.nim"
proc initGodotVariant*(dest: var GodotVariant; b: bool) {.inline.} =
getGDNativeAPI().variantNewBool(dest, b)
proc getType*(p: GodotVariant): VariantType {.
importc: "godot_variant_get_type".}
proc initGodotVariant*(dest: var GodotVariant; i: uint64) {.inline.} =
getGDNativeAPI().variantNewUInt(dest, i)
proc initGodotVariant*(dest: var GodotVariant) {.
importc: "godot_variant_new_nil".}
proc initGodotVariant*(dest: var GodotVariant, src: GodotVariant) {.
importc: "godot_variant_new_copy".}
proc initGodotVariant*(dest: var GodotVariant; b: bool) {.
importc: "godot_variant_new_bool".}
proc initGodotVariant*(dest: var GodotVariant; i: uint64) {.
importc: "godot_variant_new_uint".}
proc initGodotVariant*(dest: var GodotVariant; i: int64) {.
importc: "godot_variant_new_int".}
proc initGodotVariant*(dest: var GodotVariant; r: cdouble) {.
importc: "godot_variant_new_real".}
proc initGodotVariant*(dest: var GodotVariant; s: GodotString) {.
importc: "godot_variant_new_string".}
proc initGodotVariant*(dest: var GodotVariant; v2: Vector2) {.
importc: "godot_variant_new_vector2".}
proc initGodotVariant*(dest: var GodotVariant; rect2: Rect2) {.
importc: "godot_variant_new_rect2".}
proc initGodotVariant*(dest: var GodotVariant; v3: Vector3) {.
importc: "godot_variant_new_vector3".}
proc initGodotVariant*(dest: var GodotVariant; t2d: Transform2D) {.
importc: "godot_variant_new_transform2d".}
proc initGodotVariant*(dest: var GodotVariant; plane: Plane) {.
importc: "godot_variant_new_plane".}
proc initGodotVariant*(dest: var GodotVariant; quat: Quat) {.
importc: "godot_variant_new_quat".}
proc initGodotVariant*(dest: var GodotVariant; rect3: Rect3) {.
importc: "godot_variant_new_rect3".}
proc initGodotVariant*(dest: var GodotVariant; basis: Basis) {.
importc: "godot_variant_new_basis".}
proc initGodotVariant*(dest: var GodotVariant; trans: Transform) {.
importc: "godot_variant_new_transform".}
proc initGodotVariant*(dest: var GodotVariant; color: Color) {.
importc: "godot_variant_new_color".}
proc initGodotVariant*(dest: var GodotVariant; nodePath: GodotNodePath) {.
importc: "godot_variant_new_node_path".}
proc initGodotVariant*(dest: var GodotVariant; rid: RID) {.
importc: "godot_variant_new_rid".}
proc initGodotVariant*(dest: var GodotVariant; obj: ptr GodotObject) {.
importc: "godot_variant_new_object".}
proc initGodotVariant*(dest: var GodotVariant; arr: GodotArray) {.
importc: "godot_variant_new_array".}
proc initGodotVariant*(dest: var GodotVariant; pba: GodotPoolByteArray) {.
importc: "godot_variant_new_pool_byte_array".}
proc initGodotVariant*(dest: var GodotVariant; pia: GodotPoolIntArray) {.
importc: "godot_variant_new_pool_int_array".}
proc initGodotVariant*(dest: var GodotVariant; pra: GodotPoolRealArray) {.
importc: "godot_variant_new_pool_real_array".}
proc initGodotVariant*(dest: var GodotVariant; psa: GodotPoolStringArray) {.
importc: "godot_variant_new_pool_string_array".}
proc initGodotVariant*(dest: var GodotVariant; pv2a: GodotPoolVector2Array) {.
importc: "godot_variant_new_pool_vector2_array".}
proc initGodotVariant*(dest: var GodotVariant; pv3a: GodotPoolVector3Array) {.
importc: "godot_variant_new_pool_vector3_array".}
proc initGodotVariant*(dest: var GodotVariant; pca: GodotPoolColorArray) {.
importc: "godot_variant_new_pool_color_array".}
proc initGodotVariant*(dest: var GodotVariant; dict: GodotDictionary) {.
importc: "godot_variant_new_dictionary".}
proc initGodotVariant*(dest: var GodotVariant; i: int64) {.inline.} =
getGDNativeAPI().variantNewInt(dest, i)
proc deinit*(v: var GodotVariant) {.importc: "godot_variant_destroy".}
proc initGodotVariant*(dest: var GodotVariant; r: cdouble) {.inline.} =
getGDNativeAPI().variantNewReal(dest, r)
proc asBool*(self: GodotVariant): bool {.
importc: "godot_variant_as_bool".}
proc asUInt*(self: GodotVariant): uint64 {.
importc: "godot_variant_as_uint".}
proc asInt*(self: GodotVariant): int64 {.
importc: "godot_variant_as_int".}
proc asReal*(self: GodotVariant): cdouble {.
importc: "godot_variant_as_real".}
proc asGodotString*(self: GodotVariant): GodotString {.
importc: "godot_variant_as_string".}
proc asVector2*(self: GodotVariant): Vector2 {.
importc: "godot_variant_as_vector2".}
proc asRect2*(self: GodotVariant): Rect2 {.
importc: "godot_variant_as_rect2".}
proc asVector3*(self: GodotVariant): Vector3 {.
importc: "godot_variant_as_vector3".}
proc asTransform2D*(self: GodotVariant): Transform2D {.
importc: "godot_variant_as_transform2d".}
proc asPlane*(self: GodotVariant): Plane {.
importc: "godot_variant_as_plane".}
proc asQuat*(self: GodotVariant): Quat {.
importc: "godot_variant_as_quat".}
proc asRect3*(self: GodotVariant): Rect3 {.
importc: "godot_variant_as_rect3".}
proc asBasis*(self: GodotVariant): Basis {.
importc: "godot_variant_as_basis".}
proc asTransform*(self: GodotVariant): Transform {.
importc: "godot_variant_as_transform".}
proc asColor*(self: GodotVariant): Color {.
importc: "godot_variant_as_color".}
proc asNodePath*(self: GodotVariant): GodotNodePath {.
importc: "godot_variant_as_node_path".}
proc asRID*(self: GodotVariant): RID {.
importc: "godot_variant_as_rid".}
proc asGodotObject*(self: GodotVariant): ptr GodotObject {.
importc: "godot_variant_as_object".}
proc asGodotArray*(self: GodotVariant): GodotArray {.
importc: "godot_variant_as_array".}
proc asGodotPoolByteArray*(self: GodotVariant): GodotPoolByteArray {.
importc: "godot_variant_as_pool_byte_array".}
proc asGodotPoolIntArray*(self: GodotVariant): GodotPoolIntArray {.
importc: "godot_variant_as_pool_int_array".}
proc asGodotPoolRealArray*(self: GodotVariant): GodotPoolRealArray {.
importc: "godot_variant_as_pool_real_array".}
proc asGodotPoolStringArray*(self: GodotVariant): GodotPoolStringArray {.
importc: "godot_variant_as_pool_string_array".}
proc asGodotPoolVector2Array*(self: GodotVariant): GodotPoolVector2Array {.
importc: "godot_variant_as_pool_vector2_array".}
proc asGodotPoolVector3Array*(self: GodotVariant): GodotPoolVector3Array {.
importc: "godot_variant_as_pool_vector3_array".}
proc asGodotPoolColorArray*(self: GodotVariant): GodotPoolColorArray {.
importc: "godot_variant_as_pool_color_array".}
proc asGodotDictionary*(self: GodotVariant): GodotDictionary {.
importc: "godot_variant_as_dictionary".}
proc initGodotVariant*(dest: var GodotVariant; s: GodotString) {.inline.} =
getGDNativeAPI().variantNewString(dest, s)
proc call*(self: GodotVariant; meth: GodotString;
args: var array[128, GodotVariant]; argCount: cint;
error: var VariantCallError): GodotVariant {.
importc: "godot_variant_call".}
proc initGodotVariant*(dest: var GodotVariant; v2: Vector2) {.inline.} =
getGDNativeAPI().variantNewVector2(dest, v2)
proc hasMethod*(self: GodotVariant; meth: GodotString): bool {.
importc: "godot_variant_has_method".}
proc `==`*(self, other: GodotVariant): bool {.
importc: "godot_variant_operator_equal".}
proc `<`*(self, other: GodotVariant): bool {.
importc: "godot_variant_operator_less".}
proc hashCompare*(self, other: GodotVariant): bool {.
importc: "godot_variant_hash_compare".}
proc booleanize*(self: GodotVariant; isValid: var bool): bool {.
importc: "godot_variant_booleanize".}
proc initGodotVariant*(dest: var GodotVariant; rect2: Rect2) {.inline.} =
getGDNativeAPI().variantNewRect2(dest, rect2)
proc initGodotVariant*(dest: var GodotVariant; v3: Vector3) {.inline.} =
getGDNativeAPI().variantNewVector3(dest, v3)
proc initGodotVariant*(dest: var GodotVariant; t2d: Transform2D) {.inline.} =
getGDNativeAPI().variantNewTransform2D(dest, t2d)
proc initGodotVariant*(dest: var GodotVariant; plane: Plane) {.inline.} =
getGDNativeAPI().variantNewPlane(dest, plane)
proc initGodotVariant*(dest: var GodotVariant; quat: Quat) {.inline.} =
getGDNativeAPI().variantNewQuat(dest, quat)
proc initGodotVariant*(dest: var GodotVariant; aabb: AABB) {.inline.} =
getGDNativeAPI().variantNewAABB(dest, aabb)
proc initGodotVariant*(dest: var GodotVariant; basis: Basis) {.inline.} =
getGDNativeAPI().variantNewBasis(dest, basis)
proc initGodotVariant*(dest: var GodotVariant; trans: Transform) {.inline.} =
getGDNativeAPI().variantNewTransform(dest, trans)
proc initGodotVariant*(dest: var GodotVariant; color: Color) {.inline.} =
getGDNativeAPI().variantNewColor(dest, color)
proc initGodotVariant*(dest: var GodotVariant;
nodePath: GodotNodePath) {.inline.} =
getGDNativeAPI().variantNewNodePath(dest, nodePath)
proc initGodotVariant*(dest: var GodotVariant; rid: RID) {.inline.} =
getGDNativeAPI().variantNewRID(dest, rid)
proc initGodotVariant*(dest: var GodotVariant;
obj: ptr GodotObject) {.inline.} =
getGDNativeAPI().variantNewObject(dest, obj)
proc initGodotVariant*(dest: var GodotVariant; arr: GodotArray) {.inline.} =
getGDNativeAPI().variantNewArray(dest, arr)
proc initGodotVariant*(dest: var GodotVariant;
pba: GodotPoolByteArray) {.inline.} =
getGDNativeAPI().variantNewPoolByteArray(dest, pba)
proc initGodotVariant*(dest: var GodotVariant;
pia: GodotPoolIntArray) {.inline.} =
getGDNativeAPI().variantNewPoolIntArray(dest, pia)
proc initGodotVariant*(dest: var GodotVariant;
pra: GodotPoolRealArray) {.inline.} =
getGDNativeAPI().variantNewPoolRealArray(dest, pra)
proc initGodotVariant*(dest: var GodotVariant;
psa: GodotPoolStringArray) {.inline.} =
getGDNativeAPI().variantNewPoolStringArray(dest, psa)
proc initGodotVariant*(dest: var GodotVariant;
pv2a: GodotPoolVector2Array) {.inline.} =
getGDNativeAPI().variantNewPoolVector2Array(dest, pv2a)
proc initGodotVariant*(dest: var GodotVariant;
pv3a: GodotPoolVector3Array) {.inline.} =
getGDNativeAPI().variantNewPoolVector3Array(dest, pv3a)
proc initGodotVariant*(dest: var GodotVariant;
pca: GodotPoolColorArray) {.inline.} =
getGDNativeAPI().variantNewPoolColorArray(dest, pca)
proc initGodotVariant*(dest: var GodotVariant;
dict: GodotDictionary) {.inline.} =
getGDNativeAPI().variantNewDictionary(dest, dict)
proc deinit*(v: var GodotVariant) {.inline.} =
getGDNativeAPI().variantDestroy(v)
proc asBool*(self: GodotVariant): bool {.inline.} =
getGDNativeAPI().variantAsBool(self)
proc asUInt*(self: GodotVariant): uint64 {.inline.} =
getGDNativeAPI().variantAsUInt(self)
proc asInt*(self: GodotVariant): int64 {.inline.} =
getGDNativeAPI().variantAsInt(self)
proc asReal*(self: GodotVariant): cdouble {.inline.} =
getGDNativeAPI().variantAsReal(self)
proc asGodotString*(self: GodotVariant): GodotString {.inline.} =
getGDNativeAPI().variantAsString(self)
proc asVector2*(self: GodotVariant): Vector2 {.inline.} =
getGDNativeAPI().variantAsVector2(self).toVector2()
proc asRect2*(self: GodotVariant): Rect2 {.inline.} =
getGDNativeAPI().variantAsRect2(self).toRect2()
proc asVector3*(self: GodotVariant): Vector3 {.inline.} =
getGDNativeAPI().variantAsVector3(self).toVector3()
proc asTransform2D*(self: GodotVariant): Transform2D {.inline.} =
getGDNativeAPI().variantAsTransform2D(self).toTransform2D()
proc asPlane*(self: GodotVariant): Plane {.inline.} =
getGDNativeAPI().variantAsPlane(self).toPlane()
proc asQuat*(self: GodotVariant): Quat {.inline.} =
getGDNativeAPI().variantAsQuat(self).toQuat()
proc asAABB*(self: GodotVariant): AABB {.inline.} =
getGDNativeAPI().variantAsAABB(self).toAABB()
proc asBasis*(self: GodotVariant): Basis {.inline.} =
getGDNativeAPI().variantAsBasis(self).toBasis()
proc asTransform*(self: GodotVariant): Transform {.inline.} =
getGDNativeAPI().variantAsTransform(self).toTransform()
proc asColor*(self: GodotVariant): Color {.inline.} =
getGDNativeAPI().variantAsColor(self).toColor()
proc asNodePath*(self: GodotVariant): GodotNodePath {.inline.} =
getGDNativeAPI().variantAsNodePath(self)
proc asRID*(self: GodotVariant): RID {.inline.} =
getGDNativeAPI().variantAsRID(self)
proc asGodotObject*(self: GodotVariant): ptr GodotObject {.inline.} =
getGDNativeAPI().variantAsObject(self)
proc asGodotArray*(self: GodotVariant): GodotArray {.inline.} =
getGDNativeAPI().variantAsArray(self)
proc asGodotPoolByteArray*(self: GodotVariant): GodotPoolByteArray {.inline.} =
getGDNativeAPI().variantAsPoolByteArray(self)
proc asGodotPoolIntArray*(self: GodotVariant): GodotPoolIntArray {.inline.} =
getGDNativeAPI().variantAsPoolIntArray(self)
proc asGodotPoolRealArray*(self: GodotVariant): GodotPoolRealArray {.inline.} =
getGDNativeAPI().variantAsPoolRealArray(self)
proc asGodotPoolStringArray*(self: GodotVariant): GodotPoolStringArray
{.inline.} =
getGDNativeAPI().variantAsPoolStringArray(self)
proc asGodotPoolVector2Array*(self: GodotVariant): GodotPoolVector2Array
{.inline.} =
getGDNativeAPI().variantAsPoolVector2Array(self)
proc asGodotPoolVector3Array*(self: GodotVariant): GodotPoolVector3Array
{.inline.} =
getGDNativeAPI().variantAsPoolVector3Array(self)
proc asGodotPoolColorArray*(self: GodotVariant): GodotPoolColorArray
{.inline.} =
getGDNativeAPI().variantAsPoolColorArray(self)
proc asGodotDictionary*(self: GodotVariant): GodotDictionary {.inline.} =
getGDNativeAPI().variantAsDictionary(self)
proc call*(self: var GodotVariant; meth: GodotString;
args: ptr array[256, ptr GodotVariant]; argCount: cint;
error: var VariantCallError): GodotVariant {.inline.} =
getGDNativeAPI().variantCall(self, meth, args, argCount, error)
proc hasMethod*(self: GodotVariant; meth: GodotString): bool {.inline.} =
getGDNativeAPI().variantHasMethod(self, meth)
proc `==`*(self, other: GodotVariant): bool {.inline.} =
getGDNativeAPI().variantOperatorEqual(self, other)
proc `<`*(self, other: GodotVariant): bool {.inline.} =
getGDNativeAPI().variantOperatorLess(self, other)
proc hashCompare*(self, other: GodotVariant): bool {.inline.} =
getGDNativeAPI().variantHashCompare(self, other)
proc booleanize*(self: GodotVariant): bool {.inline.} =
getGDNativeAPI().variantBooleanize(self)
import godotstrings
proc `$`*(self: GodotVariant): string =
var s = self.asGodotString()
result = $s
s.deinit()

1
godot/internal/nim.cfg Normal file
View file

@ -0,0 +1 @@
--path:"$projectdir/../"

View file

@ -1,8 +1,8 @@
# Copyright 2017 Xored Software, Inc.
# Copyright 2018 Xored Software, Inc.
import macros, tables, typetraits
import "../godotinternal.nim", "../internal/godotvariants.nim"
import godotnim, "../core/variants.nim"
import macros, tables, typetraits, strutils, sets, sequtils, options, algorithm
import godotinternal, internal/godotvariants
import godotnim, core/variants
type
VarDecl = ref object
@ -10,9 +10,10 @@ type
typ: NimNode
defaultValue: NimNode
isNoGodot: bool
hint: string
hintTip: string
usage: string
hint: Option[string]
hintStr: Option[string]
usage: NimNode
isExported: bool
MethodDecl = ref object
name: string
@ -27,26 +28,44 @@ type
parentName: string
fields: seq[VarDecl]
methods: seq[MethodDecl]
isTool: bool
ParseError = object of Exception
include "internal/backwardcompat.inc.nim"
proc godotToNim[T](val: Variant): (T, ConversionResult) =
mixin fromVariant
result[1] = fromVariant(result[0], val)
proc nimToGodot[T](val: T): Variant =
mixin toVariant
when compiles(toVariant(val)):
result = toVariant(val)
else:
const err = "Cannot convert Nim value of type " & T.name &
" into Variant"
{.error: err.}
template parseError(node: NimNode, msg: string) =
raise newException(ParseError, lineinfo(node) & ": " & msg)
proc extractNames(definition: NimNode):
tuple[name, parentName: string] =
if definition.kind == nnkIdent:
result.name = $(definition.ident)
result.name = definition.strVal
else:
if not (definition.kind == nnkInfix and definition[0].ident == !"of"):
if not (definition.kind == nnkInfix and
definition[0].strVal == "of"):
parseError(definition, "invalid type definition")
result.name = $(definition[1].ident)
result.name = definition[1].strVal
case definition[2].kind:
of nnkIdent:
result.parentName = $definition[2].ident
result.parentName = definition[2].strVal
else:
parseError(definition[2], "parent type expected")
when not declared(newRStrLit):
proc newRStrLit(s: string): NimNode {.compileTime.} =
result = newNimNode(nnkRStrLit)
result.strVal = s
@ -55,30 +74,16 @@ proc newCStringLit(s: string): NimNode {.compileTime.} =
newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s))
iterator pragmas(node: NimNode):
tuple[key: NimIdent, value: string, index: int] =
tuple[key: string, value: NimNode, index: int] =
assert node.kind in {nnkPragma, nnkEmpty}
for index in countdown(node.len - 1, 0):
if node[index].kind == nnkExprColonExpr:
let val = $(node[index][1])
yield (node[index][0].ident, val, index)
yield (node[index][0].strVal, node[index][1], index)
elif node[index].kind == nnkIdent:
yield (node[index].ident, nil, index)
yield (node[index].strVal, nil, index)
proc removePragma(statement: NimNode, pname: string): bool =
## Removes the pragma from the node and returns whether pragma was removed
if not (RoutineNodes.contains(statement.kind) or
statement.kind == nnkPragmaExpr):
return false
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
else: statement[1]
let pnameIdent = !pname
for ident, val, i in pragmas(pragmas):
if ident == pnameIdent:
pragmas.del(i)
return true
proc removeStrPragma(statement: NimNode,
pname: string): string {.compileTime.} =
proc removePragmaNode(statement: NimNode,
pname: string): NimNode {.compileTime.} =
## Removes the pragma from the node and returns value of the pragma
## Works for routine nodes or nnkPragmaExpr
if not (RoutineNodes.contains(statement.kind) or
@ -88,11 +93,30 @@ proc removeStrPragma(statement: NimNode,
result = nil
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
else: statement[1]
let pnameIdent = !pname
for ident, val, i in pragmas(pragmas):
if ident == pnameIdent:
if ident.eqIdent(pname):
pragmas.del(i)
return (if val.isNil: "" else: val)
return val
proc removePragma(statement: NimNode, pname: string): bool =
## Removes the pragma from the node and returns whether pragma was removed
if not (RoutineNodes.contains(statement.kind) or
statement.kind == nnkPragmaExpr):
return false
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
else: statement[1]
for ident, val, i in pragmas(pragmas):
if ident.eqIdent(pname):
pragmas.del(i)
return true
proc removeStrPragma(statement: NimNode,
pname: string): Option[string] {.compileTime.} =
## Removes the pragma from the node and returns value of the pragma
## Works for routine nodes or nnkPragmaExpr
let node = removePragmaNode(statement, pname)
result = if node.isNil: none(string)
else: some($node)
proc isExported(node: NimNode): bool {.compileTime.} =
if node.kind == nnkPragmaExpr:
@ -104,38 +128,36 @@ proc identDefsToVarDecls(identDefs: NimNode): seq[VarDecl] =
assert(identDefs.kind == nnkIdentDefs)
result = newSeqOfCap[VarDecl](identDefs.len - 2)
var typ = identDefs[identDefs.len - 2]
if typ.kind == nnkEmpty:
let defaultValue = identDefs[identDefs.len - 1]
if defaultValue.kind != nnkEmpty:
typ = newCall("type", defaultValue)
for i in 0..<(identDefs.len - 2):
let nameNode = identDefs[i].copyNimTree()
let hint = removeStrPragma(nameNode, "hint")
let hintTip = removeStrPragma(nameNode, "tip")
let usage = removeStrPragma(nameNode, "usage")
let hintStr = removeStrPragma(nameNode, "hintStr")
let usage = removePragmaNode(nameNode, "usage")
let isGdExport = removePragma(nameNode, "gdExport")
if not nameNode.isExported() and isGdExport:
parseError(nameNode, "gdExport is not applicable for private fields")
let isNoGodot = not nameNode.isExported() or not isGdExport
result.add(VarDecl(
name: if nameNode.kind == nnkPragmaExpr: nameNode[0].basename()
else: nameNode.basename(),
typ: identDefs[identDefs.len - 2],
typ: typ,
defaultValue: identDefs[identDefs.len - 1],
hint: hint,
hintTip: hintTip,
isNoGodot: isNoGodot,
usage: usage
hintStr: hintStr,
isNoGodot: not isGdExport,
usage: usage,
isExported: nameNode.isExported()
))
proc parseMethod(meth: NimNode): MethodDecl =
assert(meth.kind in {nnkProcDef, nnkMethodDef})
let methName = meth[0]
let isGdExport = removePragma(meth, "gdExport")
if not methName.isExported() and isGdExport:
parseError(meth, "gdExport is not applicable for private procs/methods")
let isNoGodot = meth.kind != nnkMethodDef and (
not methName.isExported() or
not isGdExport
) or removePragma(meth, "noExport")
let isNoGodot = (meth.kind != nnkMethodDef and not isGdExport) or
removePragma(meth, "noGdExport")
result = MethodDecl(
name: $meth[0].basename,
args: newSeq[VarDecl](),
@ -150,16 +172,33 @@ proc parseMethod(meth: NimNode): MethodDecl =
proc parseVarSection(decl: NimNode): seq[VarDecl] =
assert(decl.kind == nnkVarSection)
result = identDefsToVarDecls(decl[0])
for i in 0..<decl.len:
if i == 0:
result = identDefsToVarDecls(decl[i])
else:
result.add(identDefsToVarDecls(decl[i]))
proc parseType(definition, callSite: NimNode): ObjectDecl =
let body = callSite[^1]
proc parseType(ast: NimNode): ObjectDecl =
let definition = ast[0]
let body = ast[^1]
result = ObjectDecl(
fields: newSeq[VarDecl](),
methods: newSeq[MethodDecl]()
)
(result.name, result.parentName) = extractNames(definition)
if result.parentName.isNil: result.parentName = "Object"
var isTool = false
for i in 1..(ast.len - 2):
let option = ast[i]
if option.kind != nnkIdent:
parseError(option, "type specifier expected")
if option.strVal == "tool":
isTool = true
else:
parseError(option, "valid type specifier expected")
result.isTool = isTool
if result.parentName.len == 0: result.parentName = "Object"
for statement in body:
case statement.kind:
of nnkVarSection:
@ -176,7 +215,7 @@ proc parseType(definition, callSite: NimNode): ObjectDecl =
macro invokeVarArgs(procIdent, objIdent;
minArgs, maxArgs: static[int], numArgsIdent,
argSeqIdent; argTypes: seq[NimNode],
hasReturnValue: static[bool]): typed =
hasReturnValue, isStaticCall: static[bool]): untyped =
## Produces statement in form:
##
## .. code-block:: nim
@ -218,7 +257,7 @@ macro invokeVarArgs(procIdent, objIdent;
for i in minArgs..maxArgs:
let branch = newNimNode(nnkOfBranch).add(newIntLitNode(i))
let branchBody = newStmtList()
let invocation = newNimNode(nnkCall)
var invocation = newNimNode(nnkCall)
invocation.add(procIdent)
invocation.add(objIdent) # self
for idx in 0..<i:
@ -228,9 +267,17 @@ macro invokeVarArgs(procIdent, objIdent;
branchBody.add(getAst(conv($procIdent, argT,
argSeqIdent, idx, argIdent, errIdent)))
invocation.add(argIdent)
if isStaticCall:
invocation = newNimNode(nnkCall).add(ident("procCall"), invocation)
if hasReturnValue:
let resultVariant = genSym(nskLet, "ret")
branchBody.add(
newNimNode(nnkLetSection).add(
newIdentDefs(resultVariant, ident("Variant"), newCall("toVariant", invocation))))
let theCall = newNimNode(nnkBracketExpr).add(newNimNode(nnkDotExpr).add(
newCall("toGodot", invocation), ident("godotVariant")))
resultVariant, ident("godotVariant")))
branchBody.add(getAst(initGodotVariantCall(ident("result"), theCall)))
else:
branchBody.add(invocation)
@ -245,18 +292,18 @@ macro invokeVarArgs(procIdent, objIdent;
" arguments, but got " & $numArgs)
result.add(newNimNode(nnkElse).add(getAst(
printInvokeErr($procIdent.ident, minArgs, maxArgs, numArgsIdent))))
printInvokeErr(procIdent.strVal, minArgs, maxArgs, numArgsIdent))))
proc typeError(nimType: cstring, value: string, godotType: VariantType,
proc typeError(nimType: string, value: string, godotType: VariantType,
className: cstring, propertyName: cstring): string =
result = "Tried to assign incompatible value " & value & " (" & $godotType &
") to field \"" & $propertyName & "\" (" & $nimType & ") of " &
") to field \"" & $propertyName & ": " & $nimType & "\" of " &
$className
proc rangeError(nimType: cstring, value: string, className: cstring,
proc rangeError(nimType: string, value: string, className: cstring,
propertyName: cstring): string =
result = "Tried to assign the out-of-range value " & value &
" to field \"" & $propertyName & "\" (" & $nimType & ") of " &
" to field \"" & $propertyName & ": " & $nimType & "\" of " &
$className
@ -272,36 +319,56 @@ proc nimDestroyRefFunc(obj: ptr GodotObject, methData: pointer,
# so nothing to do here.
discard
proc refcountIncremented*(obj: NimGodotObject) =
GC_ref(obj)
proc refcountIncremented(obj: ptr GodotObject, methodData: pointer,
userData: pointer, numArgs: cint,
args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
GodotVariant {.noconv.} =
let nimObj = cast[NimGodotObject](userData)
if not nimObj.isFinalized:
GC_ref(nimObj)
proc refcountDecremented*(obj: NimGodotObject): bool =
GC_unref(obj)
proc refcountDecremented(obj: ptr GodotObject, methodData: pointer,
userData: pointer, numArgs: cint,
args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
GodotVariant {.noconv.} =
let nimObj = cast[NimGodotObject](userData)
if not nimObj.isFinalized:
GC_unref(nimObj)
initGodotVariant(result, nimObj.isFinalized)
template registerGodotClass(classNameIdent, classNameLit, isRef,
baseNameLit, createFuncIdent) =
template registerGodotClass(classNameIdent, classNameLit; isRefClass: bool;
baseNameLit, createFuncIdent; isTool: bool) =
proc createFuncIdent(obj: ptr GodotObject,
methData: pointer): pointer {.noconv.} =
let nimObj = new(classNameIdent)
nimObj.setOwn()
var nimObj: classNameIdent
new(nimObj, nimGodotObjectFinalizer[classNameIdent])
nimObj.setGodotObject(obj)
nimObj.isRef = when isRefClass: true else: false
nimObj.setNativeObject(asNimGodotObject[NimGodotObject](
obj, forceNativeObject = true))
GC_ref(nimObj)
result = cast[pointer](nimObj)
when compiles(nimObj.init()):
nimObj.init()
let createFuncObj = GodotInstanceCreateFunc(
createFunc: createFuncIdent
)
let destroyFuncObj = GodotInstanceDestroyFunc(
destroyFunc: when isRef: nimDestroyRefFunc else: nimDestroyFunc
destroyFunc: when isRefClass: nimDestroyRefFunc else: nimDestroyFunc
)
registerClass(classNameIdent, classNameLit, false)
godotScriptRegisterClass(getNativeLibHandle(), classNameLit, baseNameLit,
createFuncObj, destroyFuncObj)
when isTool:
nativeScriptRegisterToolClass(getNativeLibHandle(), classNameLit,
baseNameLit, createFuncObj, destroyFuncObj)
else:
nativeScriptRegisterClass(getNativeLibHandle(), classNameLit,
baseNameLit, createFuncObj, destroyFuncObj)
template registerGodotField(classNameLit, classNameIdent, propNameLit,
propNameIdent, propTypeLit, propTypeIdent,
setFuncIdent, getFuncIdent, hintTipLit,
hintIdent, usageIdent, hasDefaultValue,
setFuncIdent, getFuncIdent, hintStrLit,
hintIdent, usageExpr, hasDefaultValue,
defaultValueNode) =
proc setFuncIdent(obj: ptr GodotObject, methData: pointer,
nimPtr: pointer, val: GodotVariant) {.noconv.} =
@ -332,18 +399,35 @@ template registerGodotField(classNameLit, classNameIdent, propNameLit,
let getFunc = GodotPropertyGetFunc(
getFunc: getFuncIdent
)
mixin godotTypeInfo
const typeInfo = when compiles(godotTypeInfo(propTypeIdent)):
godotTypeInfo(propTypeIdent)
else: GodotTypeInfo()
const hintStr = when hintStrLit != "NIM":
hintStrLit
else:
typeInfo.hintStr
const hint = when astToStr(hintIdent) != "NIM":
GodotPropertyHint.hintIdent
else:
typeInfo.hint
const variantType = typeInfo.variantType
var hintStrGodot = hintStr.toGodotString()
{.push warning[ProveInit]: off.} # false warning, Nim bug
var attr = GodotPropertyAttributes(
typ: ord(godotVariantType(propTypeIdent)),
hintString: hintTipLit.toGodotString(),
hint: GodotPropertyHint.hintIdent,
usage: GodotPropertyUsageFlags.usageIdent
typ: ord(variantType),
hint: hint,
hintString: hintStrGodot,
usage: usageExpr
)
{.push warning[ProveInit]: on.}
when hasDefaultValue:
attr.defaultValue = (defaultValueNode).toGodot()
godotScriptRegisterProperty(getNativeLibHandle(), classNameLit, propNameLit,
attr, setFunc, getFunc)
static:
import strutils, sets
attr.defaultValue = (defaultValueNode).toVariant().godotVariant[]
nativeScriptRegisterProperty(getNativeLibHandle(), classNameLit, propNameLit,
unsafeAddr attr, setFunc, getFunc)
hintStrGodot.deinit()
proc toGodotStyle(s: string): string {.compileTime.} =
result = newStringOfCap(s.len + 10)
for c in s:
@ -356,7 +440,7 @@ proc toGodotStyle(s: string): string {.compileTime.} =
proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
result = newNimNode(nnkStmtList)
# 1. Nim type definition
# Nim type definition
let typeDef = newNimNode(nnkTypeDef)
result.add(newNimNode(nnkTypeSection).add(typeDef))
typeDef.add(postfix(ident(obj.name), "*"))
@ -364,25 +448,50 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let objTy = newNimNode(nnkObjectTy)
typeDef.add(newNimNode(nnkRefTy).add(objTy))
objTy.add(newEmptyNode())
if obj.parentName.isNil:
if obj.parentName.len == 0:
objTy.add(newEmptyNode())
else:
objTy.add(newNimNode(nnkOfInherit).add(ident(obj.parentName)))
let recList = newNimNode(nnkRecList)
objTy.add(recList)
let initBody = newStmtList()
for decl in obj.fields:
if not decl.defaultValue.isNil and decl.defaultValue.kind != nnkEmpty:
parseError(decl.defaultValue,
"Default values are not supported for fields for now.")
recList.add(newIdentDefs(decl.name, decl.typ))
initBody.add(newNimNode(nnkAsgn).add(newDotExpr(ident("self"), decl.name),
decl.defaultValue))
let name = if not decl.isExported: decl.name
else: postfix(decl.name, "*")
recList.add(newIdentDefs(name, decl.typ))
# 2. {.this: self.} for convenience
# Add default values and/or super call to init method
initBody.insert(0, newNimNode(nnkCommand).add(ident("procCall"),
newCall("init", newCall(obj.parentName, ident("self")))))
var initMethod: NimNode
for meth in obj.methods:
if meth.name == "init" and meth.nimNode[3].len == 1:
initMethod = meth.nimNode
break
if initMethod.isNil:
obj.methods.add(MethodDecl(
name: "init",
args: newSeq[VarDecl](),
returnType: newEmptyNode(),
isVirtual: true,
isNoGodot: false,
nimNode: newProc(postfix(ident("init"), "*"), body = initBody,
procType = nnkMethodDef)
))
else:
initMethod.body.insert(0, initBody)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
# {.this: self.} for convenience
result.add(newNimNode(nnkPragma).add(newNimNode(nnkExprColonExpr).add(
ident("this"), ident("self")
)))
# 3. Nim proc defintions
# Nim proc defintions
var decls = newSeqOfCap[NimNode](obj.methods.len)
for meth in obj.methods:
let selfArg = newIdentDefs(ident("self"), ident(obj.name))
@ -399,55 +508,81 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
for meth in obj.methods:
result.add(meth.nimNode)
# 4. Register Godot object
let parentName = if obj.parentName.isNil: newStrLitNode("Object")
# Register Godot object
let parentName = if obj.parentName.len == 0: newStrLitNode("Object")
else: newStrLitNode(obj.parentName)
let classNameLit = newCStringLit(obj.name)
let classNameLit = newStrLitNode(obj.name)
let classNameIdent = ident(obj.name)
let isRef: bool = if obj.parentName.isNil: false
let isRef: bool = if obj.parentName.len == 0: false
else: obj.parentName in refClasses
# Wrapping bools with a newLit is required as a temporary workaround for
# https://github.com/nim-lang/Nim/issues/7375
result.add(getAst(
registerGodotClass(classNameIdent, classNameLit, isRef, parentName,
genSym(nskProc, "createFunc"))))
registerGodotClass(classNameIdent, classNameLit, newLit(isRef), parentName,
genSym(nskProc, "createFunc"), newLit(obj.isTool))))
# 5. Register fields (properties)
# Register fields (properties)
for field in obj.fields:
if field.isNoGodot: continue
let hintTip = if field.hintTip.isNil: ""
else: field.hintTip
let hint = if field.hint.isNil: "None"
else: field.hint
let usage = if field.usage.isNil: "Default"
let hintStr = if field.hintStr.isNone: "NIM"
else: field.hintStr.get
let hint = if field.hint.isNone: "NIM"
else: field.hint.get
let usage =
if field.usage.isNil:
newLit(ord(GodotPropertyUsage.Default) or
ord(GodotPropertyUsage.ScriptVariable))
else: field.usage
let hasDefaultValue = not field.defaultValue.isNil and
field.defaultValue.kind != nnkEmpty
let hintIdent = ident(hint)
let usageIdent = ident(usage)
let nimType = repr field.typ
result.add(getAst(
registerGodotField(classNameLit, classNameIdent,
newCStringLit(toGodotStyle($field.name.basename())),
ident(field.name), newCStringLit($field.typ),
ident(field.name), nimType,
field.typ, genSym(nskProc, "setFunc"),
genSym(nskProc, "getFunc"),
newStrLitNode(hintTip), hintIdent, usageIdent,
newStrLitNode(hintStr), hintIdent, usage,
ident($hasDefaultValue), field.defaultValue)))
# 6. Register methods
# Register methods
template registerGodotMethod(classNameLit, classNameIdent, methodNameIdent,
methodNameLit, minArgs, maxArgs,
argTypes, methFuncIdent, hasReturnValue) =
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
{.emit: """/*TYPESECTION*/
N_NOINLINE(void, setStackBottom)(void* thestackbottom);
""".}
proc methFuncIdent(obj: ptr GodotObject, methodData: pointer,
userData: pointer, numArgs: cint,
args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
GodotVariant {.noconv.} =
var stackBottom {.volatile.}: pointer
stackBottom = addr(stackBottom)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
{.emit: """
setStackBottom((void*)(&`stackBottom`));
""".}
else:
nimGC_setStackBottom(stackBottom)
let self = cast[classNameIdent](userData)
const isStaticCall = methodNameLit == cstring"_ready" or
methodNameLit == cstring"_process" or
methodNameLit == cstring"_fixed_process" or
methodNameLit == cstring"_enter_tree" or
methodNameLit == cstring"_exit_tree" or
methodNameLit == cstring"_enter_world" or
methodNameLit == cstring"_exit_world" or
methodNameLit == cstring"_draw"
when defined(release):
invokeVarArgs(methodNameIdent, self, minArgs, maxArgs, numArgs,
args, argTypes, hasReturnValue)
args, argTypes, hasReturnValue, isStaticCall)
else:
try:
invokeVarArgs(methodNameIdent, self, minArgs, maxArgs, numArgs,
args, argTypes, hasReturnValue)
args, argTypes, hasReturnValue, isStaticCall)
except:
let ex = getCurrentException()
printError("Unhandled Nim exception (" & $ex.name & "): " &
@ -456,8 +591,8 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let meth = GodotInstanceMethod(
meth: methFuncIdent
)
godotScriptRegisterMethod(getNativeLibHandle(), classNameLit, methodNameLit,
GodotMethodAttributes(), meth)
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit,
methodNameLit, GodotMethodAttributes(), meth)
for meth in obj.methods:
if meth.isNoGodot: continue
@ -475,7 +610,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let hasReturnValueBool = not (meth.returnType.isNil or
meth.returnType.kind == nnkEmpty or
(meth.returnType.kind == nnkIdent and
meth.returnType.ident == !"void"))
meth.returnType.strVal == "void"))
let hasReturnValue = if hasReturnValueBool: ident("true")
else: ident("false")
result.add(getAst(
@ -486,18 +621,64 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
if isRef:
# add ref/unref for types inherited from Reference
let noArgs = newSeq[NimNode]()
result.add(getAst(
registerGodotMethod(classNameLit, classNameIdent, ident("refcountIncremented"),
cstring"_refcount_incremented", 0, 0,
noArgs, genSym(nskProc, "refcount_incremented"),
ident("false"))))
result.add(getAst(
registerGodotMethod(classNameLit, classNameIdent, ident("refcountDecremented"),
cstring"_refcount_decremented", 0, 0,
noArgs, genSym(nskProc, "refcount_decremented"),
ident("true"))))
template registerRefIncDec(classNameLit) =
let refInc = GodotInstanceMethod(
meth: refcountIncremented
)
let refDec = GodotInstanceMethod(
meth: refcountDecremented
)
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit,
cstring"_refcount_incremented",
GodotMethodAttributes(), refInc)
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit,
cstring"_refcount_decremented",
GodotMethodAttributes(), refDec)
result.add(getAst(registerRefIncDec(classNameLit)))
macro gdobj*(definition: untyped, body: untyped): typed =
let typeDef = parseType(definition, callsite())
macro gdobj*(ast: varargs[untyped]): untyped =
## Generates Godot type. Self-documenting example:
##
## .. code-block:: nim
## import godot, node
##
## gdobj MyObj of Node:
## var myField: int
## ## Not exported to Godot (i.e. editor and scripts will not see this field).
##
## var myString* {.gdExport, hint: Length, hintStr: "20".}: string
## ## Exported to Godot as ``my_string``.
## ## Editor will limit this string to length 20.
## ## ``hint` is a value of ``GodotPropertyHint`` enum.
## ## ``hintStr`` depends on the value of ``hint``, its format is
## ## described in ``GodotPropertyHint`` documentation.
##
## method ready*() =
## ## Exported methods are exported to Godot by default,
## ## and their Godot names are prefixed with ``_``
## ## (in this case ``_ready``)
## print("I am ready! myString is: " & self.myString)
##
## proc myProc*() {.gdExport.} =
## ## Exported to Godot as ``my_proc``
## print("myProc is called! Incrementing myField.")
## inc self.myField
##
## If parent type is omitted, the type is inherited from ``Object``.
##
## ``tool`` specifier can be added to mark the type as an
## `editor plugin <https://godot.readthedocs.io/en/stable/development/plugins/making_plugins.html>`_:
##
## .. code-block:: nim
## import godot, editor_plugin
##
## gdobj(MyTool of EditorPlugin, tool):
## method enterTree*() =
## print("MyTool initialized!")
##
## Objects can be instantiated by invoking
## `gdnew <godotnim.html#gdnew>`_ or by using
## `load <godotapi/resource_loader.html#load,string,string,bool>`_ or any other way
## that you can find in `Godot API <index.html#modules-godot-api>`_.
let typeDef = parseType(ast)
result = genType(typeDef)

File diff suppressed because it is too large Load diff

2
godot/nim/nim.cfg Normal file
View file

@ -0,0 +1,2 @@
--path:"$projectdir/../"
-d:useRealtimeGc

5
godot/nimdoc.cfg Normal file
View file

@ -0,0 +1,5 @@
doc.item.seesrc = """&nbsp;&nbsp;<a
href="${url}/tree/${commit}/${path}#L${line}"
class="link-seesrc" target="_blank">Source</a>
<a href="${url}/edit/master/${path}#L${line}" class="link-seesrc" target="_blank" >Edit</a>
"""

View file

@ -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)