Compare commits

..

No commits in common. "master" and "v0.1.1" have entirely different histories.

63 changed files with 3752 additions and 10007 deletions

12
.gitignore vendored
View file

@ -1,14 +1,4 @@
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

View file

@ -1,53 +0,0 @@
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/godotapigen.nim"],
"godot/apigen/apigen.nim"],
"nim.buildOnSave": false,
"nim.lintOnSave": true,
"nim.licenseString": "# Copyright 2018 Xored Software, Inc.\n\n",
"nim.licenseString": "# Copyright 2017 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) 2018 Xored Software Inc.
Copyright (c) 2017 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,6 @@
# Nim bindings for Godot Engine
Nim bindings for Godot 3 based on [GDNative](https://godotengine.org/article/dlscript-here).
Documentation: https://pragmagic.github.io/godot-nim/
Nim bindings for Godot 3.0 based on [GDNative](https://godotengine.org/article/dlscript-here).
## Links
@ -11,6 +9,6 @@ Documentation: https://pragmagic.github.io/godot-nim/
## License
This project is licensed under the MIT license. Read [LICENSE](LICENSE) file for details.
This project is licensed under the MIT license. Read [LICENSE](https://github.com/pragmagic/godot-nim/blob/master/LICENSE) file for details.
Copyright (c) 2018 Xored Software, Inc.
Copyright (c) 2017 Xored Software, Inc.

View file

@ -1,161 +0,0 @@
# 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)

View file

@ -1,97 +0,0 @@
# 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)

View file

@ -1,12 +0,0 @@
===============
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

View file

@ -1,173 +0,0 @@
=============================
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>`_

View file

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

View file

@ -1,7 +1,7 @@
version = "0.8.2"
version = "0.1.1"
author = "Xored Software, Inc."
description = "Godot Engine bindings"
license = "MIT"
srcDir = "godot"
requires "nim >= 0.17.3", "compiler >= 0.17.3"
requires "nim >= 0.17.0", "compiler >= 0.17.0"

860
godot/apigen/apigen.nim Normal file
View file

@ -0,0 +1,860 @@
# 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 newExprColonExpr(key, value: PNode): PNode =
newNode(nkExprColonExpr).addChain(key, value)
proc pragma(key: PNode, value: PNode): PNode =
newNode(nkPragma).addChain(key, value)
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", "NodePath", "RID", "Dictionary", "Array", "PoolByteArray",
"PoolIntArray", "PoolRealArray", "PoolStringArray", "PoolVector2Array",
"PoolVector3Array", "PoolColorArray", "Variant"])
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"])
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("variant")
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: ident("Variant") 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 convArg = if not varargsName.isNil: newCall("toGodot", argName)
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:
if arg.typ == "string":
argConversions.add(newNode(nkLetSection).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(argAsgn)
argLoop.add(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
)))
if not varargsName.isNil:
body.add(
pragma(ident("push"), newExprColonExpr(
newBracketExpr(ident("warning"), ident("Destructor")),
ident("off"))))
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
let retValIdent = if not isVarargs: ident("ptrCallVal") else: ident(retName)
if not returnType.isNil and varargsName.isNil:
var addrToAssign = newCall("addr", ident("ptrCallVal"))
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 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 not returnType.isNil and not varargsName.isNil:
# body.add(newCall("fromGodot", ident("result"), ident(retName)))
# body.add(newCall("deinit", ident(retName)))
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"), 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 not isVarargs and (isVariantRet or isStringRet):
# varargs use call with "let" so destructor is invoked
body.add(newCall("deinit", retValIdent))
elif isConversionRet:
body.add(newNode(nkAsgn).addChain(ident("result"),
newCall(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)))
if not varargsName.isNil:
body.add(
pragma(ident("push"), newExprColonExpr(
newBracketExpr(ident("warning"), ident("Destructor")),
ident("on"))))
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
generateMethod(tree, methodBindRegistry,
ident(toNimStyle(godotName)), 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(newDotExpr(ident("core"), ident("godotcore")))
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()

3
godot/apigen/usage.txt Normal file
View file

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

View file

@ -1,79 +0,0 @@
# 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,146 +1,145 @@
# Copyright 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import hashes
import internal/godotinternaltypes, internal/godotarrays
import godotbase, poolarray, variant, strings
type
Array* = ref object
godotArray: GodotArray
proc initArray(dest: var Array) {.
importc: "godot_array_new", header: "godot_array.h".}
proc initArray(dest: var Array; pca: PoolColorArray) {.
importc: "godot_array_new_pool_coloarray",
header: "godot_array.h".}
proc initArray(dest: var Array; pv3a: PoolVector3Array) {.
importc: "godot_array_new_pool_vector3_array",
header: "godot_array.h".}
proc initArray(dest: var Array; pv2a: PoolVector2Array) {.
importc: "godot_array_new_pool_vector2_array",
header: "godot_array.h".}
proc initArray(dest: var Array; psa: PoolStringArray) {.
importc: "godot_array_new_pool_string_array",
header: "godot_array.h".}
proc initArray(dest: var Array; pra: PoolRealArray) {.
importc: "godot_array_new_pool_real_array",
header: "godot_array.h".}
proc initArray(dest: var Array; pia: PoolIntArray) {.
importc: "godot_array_new_pool_int_array",
header: "godot_array.h".}
proc initArray(dest: var Array; pba: PoolByteArray) {.
importc: "godot_array_new_pool_byte_array",
header: "godot_array.h".}
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 initArray*(): Array {.inline.} =
initArray(result)
proc arrayFinalizer(arr: Array) =
arr.godotArray.deinit()
proc initArray*(pca: PoolColorArray): Array {.inline.} =
initArray(result, pca)
proc newArray*(arr: GodotArray): Array {.inline.} =
new(result, arrayFinalizer)
result.godotArray = arr
proc initArray*(pv3a: PoolVector3Array): Array {.inline.} =
initArray(result, pv3a)
import variants
proc initArray*(pv2a: PoolVector2Array): Array {.inline.} =
initArray(result, pv2a)
proc newArray*(s: varargs[Variant]): Array =
new(result, arrayFinalizer)
initGodotArray(result.godotArray)
for v in s:
result.godotArray.add(v.godotVariant[])
proc initArray*(psa: PoolStringArray): Array {.inline.} =
initArray(result, psa)
proc newArray*(s: openarray[Variant]): Array =
result = newArray()
for v in s:
result.godotArray.add(v.godotVariant[])
proc initArray*(pra: PoolRealArray): Array {.inline.} =
initArray(result, pra)
import poolarrays
proc initArray*(pia: PoolIntArray): Array {.inline.} =
initArray(result, pia)
proc newArray*(pca: PoolColorArray): Array {.inline.} =
new(result, arrayFinalizer)
initGodotArray(result.godotArray, pca.godotPoolColorArray[])
proc initArray*(pba: PoolByteArray): Array {.inline.} =
initArray(result, pba)
proc newArray*(pv3a: PoolVector3Array): Array {.inline.} =
new(result, arrayFinalizer)
initGodotArray(result.godotArray, pv3a.godotPoolVector3Array[])
proc `[]=`*(self: var Array; idx: cint;
value: Variant) {.
noSideEffect,
importc: "godot_array_set", header: "godot_array.h".}
proc `[]`*(self: Array; idx: cint): Variant {.
noSideEffect,
importc: "godot_array_get", header: "godot_array.h".}
proc mget*(self: var Array; idx: cint): ptr Variant {.
importc: "godot_array_operator_index", header: "godot_array.h".}
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])
proc add*(self: Array; value: Variant) {.inline.} =
self.godotArray.add(value.godotVariant[])
proc clear*(self: Array) {.inline.} =
self.godotArray.clear()
proc count*(self: Array; value: Variant): int {.inline.} =
self.godotArray.count(value.godotVariant[]).int
proc isEmpty*(self: Array): bool {.inline.} =
self.godotArray.isEmpty()
proc erase*(self: Array; value: Variant) {.inline.} =
self.godotArray.erase(value.godotVariant[])
proc first*(self: Array): Variant {.inline.} =
newVariant(self.godotArray.first())
proc last*(self: Array): Variant {.inline.} =
newVariant(self.godotArray.last())
proc find*(self: Array; what: Variant; f: int): int {.inline.} =
self.godotArray.find(what.godotVariant[], f.cint).int
proc findLast*(self: Array; what: Variant): int {.inline.} =
self.godotArray.findLast(what.godotVariant[]).int
proc contains*(self: Array; value: Variant): bool {.inline.} =
self.godotArray.contains(value.godotVariant[])
proc add*(self: var Array; value: Variant) {.
noSideEffect,
importc: "godot_array_append", header: "godot_array.h".}
proc clear*(self: var Array) {.importc: "godot_array_clear",
header: "godot_array.h".}
proc count*(self: Array; value: Variant): cint {.
noSideEffect,
importc: "godot_array_count", header: "godot_array.h".}
proc isEmpty*(self: Array): bool {.
noSideEffect,
importc: "godot_array_empty", header: "godot_array.h".}
proc erase*(self: var Array; value: Variant) {.
importc: "godot_array_erase", header: "godot_array.h".}
proc first*(self: Array): Variant {.
noSideEffect,
importc: "godot_array_front", header: "godot_array.h".}
proc last*(self: Array): Variant {.
noSideEffect,
importc: "godot_array_back", header: "godot_array.h".}
proc find*(self: Array; what: Variant;
f: cint): cint {.
noSideEffect,
importc: "godot_array_find", header: "godot_array.h".}
proc findLast*(self: Array; what: Variant): cint {.
noSideEffect,
importc: "godot_array_find_last", header: "godot_array.h".}
proc contains*(self: Array; value: Variant): bool {.
noSideEffect,
importc: "godot_array_has", header: "godot_array.h".}
proc godotHash*(self: Array): cint {.
noSideEffect,
importc: "godot_array_hash", header: "godot_array.h".}
proc hash*(self: Array): Hash {.inline.} =
hash(self.godotArray.godotHash())
hash(godotHash(self))
proc insert*(self: Array; pos: int; value: Variant) {.inline.} =
self.godotArray.insert(pos.cint, value.godotVariant[])
proc insert*(self: var Array; pos: cint;
value: Variant) {.
importc: "godot_array_insert", header: "godot_array.h".}
proc reverse*(self: var Array) {.importc: "godot_array_invert",
header: "godot_array.h".}
proc popLast*(self: var Array): Variant {.
importc: "godot_array_pop_back", header: "godot_array.h".}
proc popFirst*(self: var Array): Variant {.
importc: "godot_array_pop_front", header: "godot_array.h".}
proc addLast*(self: var Array; value: Variant) {.
importc: "godot_array_push_back", header: "godot_array.h".}
proc addFirst*(self: var Array; value: Variant) {.
importc: "godot_array_push_front", header: "godot_array.h".}
proc reverse*(self: Array) {.inline.} =
self.godotArray.reverse()
proc delete*(self: var Array; idx: cint) {.
importc: "godot_array_remove", header: "godot_array.h".}
proc setLen*(self: var Array; size: cint) {.
importc: "godot_array_resize", header: "godot_array.h".}
proc rfind*(self: Array; what: Variant;
f: cint): cint {.
noSideEffect,
importc: "godot_array_rfind", header: "godot_array.h".}
proc len*(self: Array): cint {.
noSideEffect,
importc: "godot_array_size", header: "godot_array.h".}
proc sort*(self: var Array) {.importc: "godot_array_sort",
header: "godot_array.h".}
proc sortCustom*(self: var Array; obj: var GodotObject;
funcName: GodotString) {.
importc: "godot_array_sort_custom", header: "godot_array.h".}
proc popLast*(self: Array): Variant {.inline.} =
newVariant(self.godotArray.popLast())
iterator items*(arr: Array): Variant =
for i in 0..<arr.len:
yield arr[i]
proc popFirst*(self: Array): Variant {.inline.} =
newVariant(self.godotArray.popFirst())
iterator mitems*(arr: var Array): var Variant =
for i in 0..<arr.len:
yield arr.mget(i)[]
proc addLast*(self: Array; value: Variant) {.inline.} =
self.godotArray.addLast(value.godotVariant[])
iterator pairs*(arr: Array): tuple[key: cint, val: Variant] =
for i in 0..<arr.len:
yield (i, arr[i])
proc addFirst*(self: Array; value: Variant) {.inline.} =
self.godotArray.addFirst(value.godotVariant[])
proc delete*(self: Array; idx: int) {.inline.} =
self.godotArray.delete(idx.cint)
proc setLen*(self: Array; size: int) {.inline.} =
self.godotArray.setLen(size.cint)
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
proc sort*(self: Array) {.inline.} =
self.godotArray.sort()
iterator items*(self: Array): Variant =
for i in 0..<self.len:
yield self[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
iterator mpairs*(arr: var Array): tuple[key: cint, val: var Variant] =
for i in 0..<arr.len:
yield (i, arr.mget(i)[])

View file

@ -1,459 +1,140 @@
# Copyright (c) 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import math, hashes
import godotbase, vector3, quat, strings
import godotbase, vector3, quats
import godotcoretypes
type
Basis* {.importc: "godot_basis", header: "godot_basis.h", byref.} = object
{.push stackTrace: off.}
proc setCells*(basis: var Basis, xx, xy, xz, yx, yy, yz, zx, zy, zz: float32) =
basis.elements[0].x = xx
basis.elements[0].y = xy
basis.elements[0].z = xz
basis.elements[1].x = yx
basis.elements[1].y = yy
basis.elements[1].z = yz
basis.elements[2].x = zx
basis.elements[2].y = zy
basis.elements[2].z = zz
proc `[]`*(self: Basis; row: range[0..2]): Vector3 {.inline.} =
self.elements[row]
proc `[]`*(self: var Basis; row: range[0..2]): var Vector3 {.inline.} =
self.elements[row]
proc `[]=`*(self: var Basis; row: range[0..2];
value: Vector3) {.inline.} =
self.elements[row] = value
proc `==`*(self, other: Basis): bool =
for i in 0..2:
for j in 0..2:
if self[i][j] != other[i][j]:
return false
result = true
proc isEqualApprox*(self, other: Basis): bool =
for i in 0..2:
for j in 0..2:
if not self[i][j].isEqualApprox(other[i][j]):
return false
result = true
proc tdotx*(self: Basis; v: Vector3): float32 {.inline.} =
self.elements[0].x * v.x + self.elements[1].x * v.y + self.elements[2].x * v.z
proc tdoty*(self: Basis; v: Vector3): float32 {.inline.} =
self.elements[0].y * v.x + self.elements[1].y * v.y + self.elements[2].y * v.z
proc tdotz*(self: Basis; v: Vector3): float32 {.inline.} =
self.elements[0].z * v.x + self.elements[1].z * v.y + self.elements[2].z * v.z
proc `+`*(self, other: Basis): Basis {.inline.} =
result[0] = self[0] + other[0]
result[1] = self[1] + other[1]
result[2] = self[2] + other[2]
proc `+=`*(self: var Basis, other: Basis) {.inline.} =
self[0] += other[0]
self[1] += other[1]
self[2] += other[2]
proc `-`*(self, other: Basis): Basis {.inline.} =
result[0] = self[0] - other[0]
result[1] = self[1] - other[1]
result[2] = self[2] - other[2]
proc `-=`*(self: var Basis, other: Basis) {.inline.} =
self[0] -= other[0]
self[1] -= other[1]
self[2] -= other[2]
proc `*`*(self, other: Basis): Basis {.inline.} =
result.setCells(
other.tdotx(self[0]), other.tdoty(self[0]), other.tdotz(self[0]),
other.tdotx(self[1]), other.tdoty(self[1]), other.tdotz(self[1]),
other.tdotx(self[2]), other.tdoty(self[2]), other.tdotz(self[2])
)
proc `*=`*(self: var Basis, other: Basis) {.inline.} =
self.setCells(
other.tdotx(self[0]), other.tdoty(self[0]), other.tdotz(self[0]),
other.tdotx(self[1]), other.tdoty(self[1]), other.tdotz(self[1]),
other.tdotx(self[2]), other.tdoty(self[2]), other.tdotz(self[2])
)
proc `*=`*(self: var Basis; b: float32) {.inline.} =
self[0] *= b
self[1] *= b
self[2] *= b
proc `*`*(self: Basis; b: float32): Basis {.inline.} =
result = self
result *= b
proc initBasis(dest: var Basis) {.importc: "godot_basis_new",
header: "godot_basis.h".}
proc initBasis(dest: var Basis;
xAxis: Vector3;
yAxis: Vector3;
zAxis: Vector3) {.
importc: "godot_basis_new_with_rows", header: "godot_basis.h".}
proc initBasis(dest: var Basis;
euler: Quat) {.
importc: "godot_basis_new_with_euler_quat", header: "godot_basis.h".}
proc initBasis(dest: var Basis; axis: Vector3; phi: float32) {.
importc: "godot_basis_new_with_axis_and_angle", header: "godot_basis.h".}
proc initBasis(dest: var Basis; euler: Vector3) {.
importc: "godot_basis_new_with_euler", header: "godot_basis.h".}
proc initBasis*(): Basis {.inline.} =
result.setCells(
1, 0, 0,
0, 1, 0,
0, 0, 1
)
initBasis(result)
proc initBasis*(row0, row1, row2: Vector3): Basis {.inline.} =
Basis(elements: [row0, row1, row2])
proc initBasis*(xx, xy, xz, yx, yy, yz, zx, zy, zz: float32): Basis =
result.setCells(xx, xy, xz, yx, yy, yz, zx, zy, zz)
proc initBasis*(xAxis, yAxis, zAxis: Vector3): Basis {.inline.} =
initBasis(result, xAxis, yAxis, zAxis)
proc initBasis*(euler: Quat): Basis {.inline.} =
let d = euler.lengthSquared()
let s = 2.0 / d
let xs = euler.x * s
let ys = euler.y * s
let zs = euler.z * s
let wx = euler.w * xs
let wy = euler.w * ys
let wz = euler.w * zs
let xx = euler.x * xs
let xy = euler.x * ys
let xz = euler.x * zs
let yy = euler.y * ys
let yz = euler.y * zs
let zz = euler.z * zs
result.setCells(
1.0 - (yy + zz), xy - wz, xz + wy,
xy + wz, 1.0 - (xx + zz), yz - wx,
xz - wy, yz + wx, 1.0 - (xx + yy))
proc setAxisAngle(self: var Basis, axis: Vector3, phi: float32) =
assert(axis.isNormalized())
let axisSq = vec3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z)
let cosine = cos(phi);
let sine = sin(phi);
self.elements[0].x = axisSq.x + cosine * (1.0 - axisSq.x)
self.elements[0].y = axis.x * axis.y * (1.0 - cosine) - axis.z * sine
self.elements[0].z = axis.z * axis.x * (1.0 - cosine) + axis.y * sine
self.elements[1].x = axis.x * axis.y * (1.0 - cosine) + axis.z * sine
self.elements[1].y = axisSq.y + cosine * (1.0 - axisSq.y)
self.elements[1].z = axis.y * axis.z * (1.0 - cosine) - axis.x * sine
self.elements[2].x = axis.z * axis.x * (1.0 - cosine) - axis.y * sine
self.elements[2].y = axis.y * axis.z * (1.0 - cosine) + axis.x * sine
self.elements[2].z = axisSq.z + cosine * (1.0 - axisSq.z)
initBasis(result, euler)
proc initBasis*(axis: Vector3, phi: float32): Basis {.inline.} =
result.setAxisAngle(axis, phi)
proc setEuler*(self: var Basis, euler: Vector3) =
var c = cos(euler.x)
var s = sin(euler.x)
let xmat = initBasis(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c)
c = cos(euler.y)
s = sin(euler.y)
let ymat = initBasis(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c)
c = cos(euler.z)
s = sin(euler.z)
let zmat = initBasis(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0)
self = xmat * (ymat * zmat)
proc getEuler*(self: Basis): Vector3 =
result.y = arcsin(self.elements[0].z)
if result.y < PI * 0.5:
if result.y > -PI * 0.5:
result.x = arctan2(-self.elements[1].z, self.elements[2].z)
result.z = arctan2(-self.elements[0].y, self.elements[0].x)
else:
let r = arctan2(self.elements[1].x, self.elements[1].y)
result.x = -r
else:
let r = arctan2(self.elements[0].y, self.elements[1].y)
result.x = r
initBasis(result, axis, phi)
proc initBasis*(euler: Vector3): Basis {.inline.} =
result.setEuler(euler)
initBasis(result, euler)
proc outer*(self, other: Vector3): Basis {.inline.} =
let row0 = vec3(self.x * other.x, self.x * other.y, self.x * other.z)
let row1 = vec3(self.y * other.x, self.y * other.y, self.y * other.z)
let row2 = vec3(self.z * other.x, self.z * other.y, self.z * other.z)
initBasis(row0, row1, row2)
proc toDiagonalMatrix*(self: Vector3): Basis {.inline.} =
initBasis(
self.x, 0, 0,
0, self.y, 0,
0, 0, self.z
)
proc toGodotString*(self: Basis): GodotString {.
noSideEffect,
importc: "godot_basis_as_string", header: "godot_basis.h".}
proc `$`*(self: Basis): string {.inline.} =
result = newStringOfCap(128)
for i in 0..2:
for j in 0..2:
if i != 0 or j != 0:
result.add(", ")
result.add($self[i][j])
$self.toGodotString()
proc hash*(self: Basis): Hash {.inline.} =
!$(self.elements[0].hash() !& self.elements[1].hash() !& self.elements[2].hash())
proc inverse*(self: Basis): Basis {.
noSideEffect,
importc: "godot_basis_inverse", header: "godot_basis.h".}
proc transposed*(self: Basis): Basis {.
noSideEffect,
importc: "godot_basis_transposed", header: "godot_basis.h".}
proc orthonormalized*(self: Basis): Basis {.
noSideEffect,
importc: "godot_basis_orthonormalized", header: "godot_basis.h".}
proc determinant*(self: Basis): float32 {.
noSideEffect,
importc: "godot_basis_determinant", header: "godot_basis.h".}
proc rotated*(self: Basis; axis: Vector3;
phi: float32): Basis {.
noSideEffect,
importc: "godot_basis_rotated", header: "godot_basis.h".}
proc scaled*(self: Basis; scale: Vector3): Basis {.
noSideEffect,
importc: "godot_basis_scaled", header: "godot_basis.h".}
template cofac(row1, col1, row2, col2: int): float32 =
self.elements[row1][col1] * self.elements[row2][col2] -
self.elements[row1][col2] * self.elements[row2][col1]
proc setScale*(self: var Basis; scale: Vector3) {.
noSideEffect,
importc: "godot_basis_set_scale", header: "godot_basis.h".}
proc setRotationEuler*(self: var Basis;
euler: Vector3) {.
noSideEffect,
importc: "godot_basis_set_rotation_euler", header: "godot_basis.h".}
proc setRotationAxisAngle*(self: var Basis; axis: Vector3; angle: float32) {.
noSideEffect,
importc: "godot_basis_set_rotation_axis_angle", header: "godot_basis.h".}
proc determinant(self: Basis): float32 {.inline.} =
self[0][0] * cofac(1, 1, 2, 2) -
self[1][0] * cofac(0, 1, 2, 2) +
self[2][0] * cofac(0, 1, 1, 2)
proc scale*(self: Basis): Vector3 {.
noSideEffect,
importc: "godot_basis_get_scale", header: "godot_basis.h".}
proc euler*(self: Basis): Vector3 {.
noSideEffect,
importc: "godot_basis_get_euler", header: "godot_basis.h".}
proc invert*(self: var Basis) =
let co = [cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)]
let det = self.elements[0][0] * co[0] +
self.elements[0][1] * co[1] +
self.elements[0][2] * co[2]
assert(det != 0)
let s = 1.0'f32 / det
self.setCells(
co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s
)
proc tdotx*(self: Basis; x: Vector3): float32 {.
noSideEffect,
importc: "godot_basis_tdotx", header: "godot_basis.h".}
proc tdoty*(self: Basis; y: Vector3): float32 {.
noSideEffect,
importc: "godot_basis_tdoty", header: "godot_basis.h".}
proc tdotz*(self: Basis; z: Vector3): float32 {.
noSideEffect,
importc: "godot_basis_tdotz", header: "godot_basis.h".}
proc inverse*(self: Basis): Basis {.inline.} =
result = self
result.invert()
proc xform*(self: Basis; v: Vector3): Vector3 {.
noSideEffect,
importc: "godot_basis_xform", header: "godot_basis.h".}
proc xformInv*(self: Basis; v: Vector3): Vector3 {.
noSideEffect,
importc: "godot_basis_xform_inv", header: "godot_basis.h".}
proc axis*(self: Basis; idx: range[0..2]): Vector3 {.inline.} =
vec3(self[0][idx], self[1][idx], self[2][idx])
proc orthogonalIndex*(self: Basis): cint {.
noSideEffect,
importc: "godot_basis_get_orthogonal_index", header: "godot_basis.h".}
proc setAxis*(self: var Basis; idx: range[0..2]; value: Vector3) {.inline.} =
self.elements[0][idx] = value.x
self.elements[1][idx] = value.y
self.elements[2][idx] = value.z
proc godot_basis_get_elements(self: Basis;
elements: var array[3, Vector3]) {.
noSideEffect,
importc: "godot_basis_get_elements", header: "godot_basis.h".}
proc row*(self: Basis; row: range[0..2]): Vector3 {.inline.} =
self.elements[row]
proc elements*(self: Basis): array[3, Vector3] {.inline.} =
godot_basis_get_elements(self, result)
proc setRow*(self: var Basis; row: range[0..2]; value: Vector3) {.inline.} =
self.elements[row] = value
proc getMainDiagonal*(self: Basis): Vector3 {.inline.} =
vec3(self.elements[0][0], self.elements[1][1], self.elements[2][2])
proc zero*(self: var Basis) {.inline.} =
self.elements[0].zero()
self.elements[1].zero()
self.elements[2].zero()
proc orthonormalize(self: var Basis) =
var x = self.axis(0)
var y = self.axis(1)
var z = self.axis(2)
x.normalize()
y = y - x * x.dot(y)
y.normalize()
z = z - x * x.dot(z) - y * y.dot(z)
z.normalize()
self.setAxis(0, x)
self.setAxis(1, y)
self.setAxis(2, z)
proc orthonormalized*(self: Basis): Basis {.inline.} =
result = self
result.orthonormalize()
proc transpose*(self: var Basis) {.inline.} =
swap(self.elements[0].x, self.elements[1].x)
swap(self.elements[0].z, self.elements[2].x)
swap(self.elements[1].z, self.elements[2].y)
proc transposed*(self: Basis): Basis {.inline.} =
result = self
result.transpose()
proc isOrthogonal*(self: Basis): bool {.inline.} =
let id = initBasis()
let m = self * self.transposed()
result = id.isEqualApprox(m)
proc isRotation*(self: Basis): bool {.inline.} =
self.determinant().isEqualApprox(1.0) and self.isOrthogonal()
proc isSymmetric*(self: Basis): bool {.inline.} =
if not self.elements[0][1].isEqualApprox(self.elements[1][0]):
return false
if not self.elements[0][2].isEqualApprox(self.elements[2][0]):
return false
if not self.elements[1][2].isEqualApprox(self.elements[2][1]):
return false
result = true
proc scale*(self: var Basis, scale: Vector3) =
self[0].x *= scale.x
self[0].y *= scale.x
self[0].z *= scale.x
self[1].x *= scale.y
self[1].y *= scale.y
self[1].z *= scale.y
self[2].x *= scale.z
self[2].y *= scale.z
self[2].z *= scale.z
proc scaled*(self: Basis, scale: Vector3): Basis =
result = self
result.scale(scale)
proc rotated*(self: Basis; axis: Vector3; phi: float32): Basis {.inline.} =
initBasis(axis, phi) * self
proc rotate*(self: var Basis; axis: Vector3; phi: float32) {.inline.} =
self = self.rotated(axis, phi)
proc rotated*(self: Basis; euler: Vector3): Basis {.inline.} =
initBasis(euler) * self
proc rotate*(self: var Basis; euler: Vector3) {.inline.} =
self = self.rotated(euler)
proc getScale*(self: Basis): Vector3 =
let detSign = if self.determinant() > 0: 1'f32 else: -1'f32
result = detSign * vec3(
vec3(self.elements[0].x, self.elements[1].x, self.elements[2].x).length(),
vec3(self.elements[0].y, self.elements[1].y, self.elements[2].y).length(),
vec3(self.elements[0].z, self.elements[1].z, self.elements[2].z).length(),
)
proc getRotation*(self: Basis): Vector3 {.inline.} =
var m = self.orthonormalized()
let det = m.determinant()
if det < 0:
m.scale(vec3(-1, -1, -1))
result = m.getEuler()
proc setScale*(self: var Basis; scale: Vector3) =
let e = self.getEuler()
self = initBasis() # reset to identity
self.scale(scale)
self.rotate(e)
proc setRotationEuler*(self: var Basis; euler: Vector3) =
let s = self.getScale()
self = initBasis()
self.scale(s)
self.rotate(euler)
proc setRotationAxisAngle*(self: var Basis; axis: Vector3; angle: float32) =
let s = self.getScale()
self = initBasis()
self.scale(s)
self.rotate(axis, angle)
proc asQuat*(self: Basis): Quat =
let trace = self.elements[0].x + self.elements[1].y + self.elements[2].z
var temp: array[4, float32]
if trace > 0'f32:
var s = sqrt(trace + 1.0)
temp[3] = s * 0.5
s = 0.5 / s
temp[0] = (self.elements[2].y - self.elements[1].z) * s
temp[1] = (self.elements[0].z - self.elements[2].x) * s
temp[2] = (self.elements[1].x - self.elements[0].y) * s
else:
let i = if self.elements[0].x < self.elements[1].y:
if self.elements[1].y < self.elements[2].z: 2 else: 1
else:
if self.elements[0].x < self.elements[2].z: 2 else: 0
let j = (i + 1) mod 3
let k = (i + 2) mod 3
var s = sqrt(self.elements[i][i] - self.elements[j][j] -
self.elements[k][k] + 1.0)
temp[i] = s * 0.5
s = 0.5 / s
temp[3] = (self.elements[k][j] - self.elements[j][k]) * s
temp[j] = (self.elements[j][i] + self.elements[i][j]) * s
temp[k] = (self.elements[k][i] + self.elements[i][k]) * s
result = initQuat(temp[0], temp[1], temp[2], temp[3])
proc xform*(self: Basis; v: Vector3): Vector3 {.inline.} =
vec3(
self.elements[0].dot(v),
self.elements[1].dot(v),
self.elements[2].dot(v)
)
proc xformInv*(self: Basis; v: Vector3): Vector3 {.inline.} =
vec3(
self.elements[0].x * v.x + self.elements[1].x * v.y + self.elements[2].x * v.z,
self.elements[0].y * v.x + self.elements[1].y * v.y + self.elements[2].y * v.z,
self.elements[0].z * v.x + self.elements[1].z * v.y + self.elements[2].z * v.z,
)
const orthoBases = [
initBasis(1, 0, 0, 0, 1, 0, 0, 0, 1),
initBasis(0, -1, 0, 1, 0, 0, 0, 0, 1),
initBasis(-1, 0, 0, 0, -1, 0, 0, 0, 1),
initBasis(0, 1, 0, -1, 0, 0, 0, 0, 1),
initBasis(1, 0, 0, 0, 0, -1, 0, 1, 0),
initBasis(0, 0, 1, 1, 0, 0, 0, 1, 0),
initBasis(-1, 0, 0, 0, 0, 1, 0, 1, 0),
initBasis(0, 0, -1, -1, 0, 0, 0, 1, 0),
initBasis(1, 0, 0, 0, -1, 0, 0, 0, -1),
initBasis(0, 1, 0, 1, 0, 0, 0, 0, -1),
initBasis(-1, 0, 0, 0, 1, 0, 0, 0, -1),
initBasis(0, -1, 0, -1, 0, 0, 0, 0, -1),
initBasis(1, 0, 0, 0, 0, 1, 0, -1, 0),
initBasis(0, 0, -1, 1, 0, 0, 0, -1, 0),
initBasis(-1, 0, 0, 0, 0, -1, 0, -1, 0),
initBasis(0, 0, 1, -1, 0, 0, 0, -1, 0),
initBasis(0, 0, 1, 0, 1, 0, -1, 0, 0),
initBasis(0, -1, 0, 0, 0, 1, -1, 0, 0),
initBasis(0, 0, -1, 0, -1, 0, -1, 0, 0),
initBasis(0, 1, 0, 0, 0, -1, -1, 0, 0),
initBasis(0, 0, 1, 0, -1, 0, 1, 0, 0),
initBasis(0, 1, 0, 0, 0, 1, 1, 0, 0),
initBasis(0, 0, -1, 0, 1, 0, 1, 0, 0),
initBasis(0, -1, 0, 0, 0, -1, 1, 0, 0)
]
proc orthogonalIndex*(self: Basis): int =
var orth = self
for i in 0..2:
for j in 0..2:
var v = orth[i][j]
if v > 0.5:
v = 1.0'f32
elif v < -0.5:
v = -1.0'f32
else:
v = 0'f32
orth[i][j] = v
for idx, base in orthoBases:
if base == orth:
return idx
proc setOrthogonalIndex*(self: var Basis, idx: range[0..23]) =
self = orthoBases[idx]
proc rotate*(self: var Vector3; axis: Vector3; phi: float32) =
self = initBasis(axis, phi).xform(self)
proc rotated*(self: Vector3; axis: Vector3; phi: float32): Vector3 =
result = self
result.rotate(axis, phi)
{.pop.} # stackTrace: off
proc `[]`*(self: Basis; axis: range[0..2]): Vector3 {.
noSideEffect,
importc: "godot_basis_get_axis", header: "godot_basis.h".}
proc `[]=`*(self: var Basis; axis: range[0..2];
value: Vector3) {.
noSideEffect,
importc: "godot_basis_set_axis", header: "godot_basis.h".}
proc row*(self: Basis; row: cint): Vector3 {.
noSideEffect,
importc: "godot_basis_get_row", header: "godot_basis.h".}
proc setRow*(self: var Basis; row: cint;
value: Vector3) {.
noSideEffect,
importc: "godot_basis_set_row", header: "godot_basis.h".}
proc `==`*(self: Basis; b: Basis): bool {.
noSideEffect,
importc: "godot_basis_operator_equal", header: "godot_basis.h".}
proc `+`*(self: Basis; b: Basis): Basis {.
noSideEffect,
importc: "godot_basis_operator_add", header: "godot_basis.h".}
proc `-`*(self: Basis; b: Basis): Basis {.
noSideEffect,
importc: "godot_basis_operator_substract", header: "godot_basis.h".}
proc `*`*(self: Basis; b: Basis): Basis {.
noSideEffect,
importc: "godot_basis_operator_multiply_vector", header: "godot_basis.h".}
proc `*`*(self: Basis; b: float32): Basis {.
noSideEffect,
importc: "godot_basis_operator_multiply_scalar", header: "godot_basis.h".}

76
godot/core/color.nim Normal file
View file

@ -0,0 +1,76 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, strings
type
Color* {.importc: "godot_color", header: "godot_color.h", byref.} = object
proc initColor(dest: var Color; r, g, b, a: float32) {.
importc: "godot_color_new_rgba", header: "godot_color.h".}
proc initColor(dest: var Color; r, g, b: float32) {.
importc: "godot_color_new_rgb",
header: "godot_color.h".}
proc initColor*(r, g, b, a: float32): Color {.inline.} =
initColor(result, r, g, b, a)
proc initColor*(r, g, b: float32): Color {.inline.} =
initColor(result, r, g, b)
proc r*(self: Color): float32 {.
importc: "godot_color_get_r", header: "godot_color.h".}
proc `r=`*(self: var Color; r: float32) {.
importc: "godot_color_set_r", header: "godot_color.h".}
proc g*(self: Color): float32 {.
importc: "godot_color_get_g", header: "godot_color.h".}
proc `g=`*(self: var Color; g: float32) {.
importc: "godot_color_set_g", header: "godot_color.h".}
proc b*(self: Color): float32 {.
importc: "godot_color_get_b", header: "godot_color.h".}
proc `b=`*(self: var Color; b: float32) {.
importc: "godot_color_set_b", header: "godot_color.h".}
proc a*(self: Color): float32 {.
importc: "godot_color_get_a", header: "godot_color.h".}
proc `a=`*(self: var Color; a: float32) {.
importc: "godot_color_set_a", header: "godot_color.h".}
proc h*(self: Color): float32 {.
importc: "godot_color_get_h", header: "godot_color.h".}
proc s*(self: Color): float32 {.
importc: "godot_color_get_s", header: "godot_color.h".}
proc v*(self: Color): float32 {.
importc: "godot_color_get_v", header: "godot_color.h".}
proc toGodotString*(self: Color): GodotString {.
importc: "godot_color_as_string", header: "godot_color.h".}
proc `$`*(self: Color): string {.inline.} =
$self.toGodotString()
proc toHtml*(self: Color; with_alpha: bool): GodotString {.
importc: "godot_color_to_html", header: "godot_color.h".}
proc to32CInt(self: Color): cint {.
importc: "godot_color_to_32", header: "godot_color.h".}
proc toARGB32CInt(self: Color): cint {.
importc: "godot_color_to_ARGB32", header: "godot_color.h".}
proc to32*(self: Color): uint32 {.inline.}=
cast[uint32](to32CInt(self))
proc toARGB32*(self: Color): uint32 {.inline.} =
cast[uint32](toARGB32CInt(self))
proc gray*(self: Color): float32 {.
importc: "godot_color_gray", header: "godot_color.h".}
proc inverted*(self: Color): Color {.
importc: "godot_color_inverted", header: "godot_color.h".}
proc contrasted*(self: Color): Color {.
importc: "godot_color_contrasted", header: "godot_color.h".}
proc lerp*(self: Color; b: Color; t: float32): Color {.
importc: "godot_color_linear_interpolate", header: "godot_color.h".}
proc blend*(self: Color; over: Color): Color {.
importc: "godot_color_blend", header: "godot_color.h".}
proc `==`*(self, b: Color): bool {.
importc: "godot_color_operator_equal", header: "godot_color.h".}
proc `<`*(self, b: Color): bool {.
importc: "godot_color_operator_less", header: "godot_color.h".}

View file

@ -1,88 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import hashes
import godotcoretypes, gdnativeapi
proc initColor*(r, g, b: float32; a: float32 = 1.0'f32): Color {.inline.} =
Color(
r: r,
g: g,
b: b,
a: a
)
proc initColor*(): Color {.inline.} =
## Initializes black color with 1.0 alpha
initColor(0, 0, 0)
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)
result.add($self.r)
result.add(", ")
result.add($self.g)
result.add(", ")
result.add($self.b)
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]
for i, num in nums:
target[targetIdx + i] = if num < 10: chr(ord('0') + num)
else: chr(ord('A') + (num - 10))
proc toHtml*(self: Color, withAlpha: bool): string =
let size = if withAlpha: 8 else: 6
result = newString(size)
toHex(self.r, result, 0)
toHex(self.g, result, 2)
toHex(self.b, result, 4)
if withAlpha:
toHex(self.b, result, 6)
proc toARGB32*(self: Color): uint32 {.inline.} =
result = uint8(self.a * 255)
result = (result shl 8) or uint8(self.r * 255)
result = (result shl 8) or uint8(self.g * 255)
result = (result shl 8) or uint8(self.b * 255)
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
proc `<`*(a, b: Color): bool =
if a.r == b.r:
if a.g == b.g:
if a.b == b.b:
return a.a < b.a
return a.b < b.b
return a.g < b.g
return a.r < b.r

View file

@ -1,110 +0,0 @@
# Copyright 2018 Xored Software, Inc.
import hashes
import internal/godotinternaltypes, internal/godotdictionaries,
internal/godotvariants, internal/godotstrings
type
Dictionary* = ref object
godotDictionary: GodotDictionary
proc dictionaryFinalizer(dict: Dictionary) =
dict.godotDictionary.deinit()
proc newDictionary*(): Dictionary {.inline.} =
new(result, dictionaryFinalizer)
initGodotDictionary(result.godotDictionary)
proc newDictionary*(dict: GodotDictionary): Dictionary {.inline.} =
new(result, dictionaryFinalizer)
result.godotDictionary = dict
proc godotDictionary*(dict: Dictionary): ptr GodotDictionary =
## WARNING: do not keep the returned value for longer than the lifetime of
## ``dict``
addr dict.godotDictionary
proc len*(self: Dictionary): int {.inline.} =
self.godotDictionary.len.int
proc isEmpty*(self: Dictionary): bool {.inline.} =
self.godotDictionary.isEmpty()
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: Dictionary; key: Variant) {.inline.} =
self.godotDictionary.del(key.godotVariant[])
proc keys*(self: Dictionary): Array {.inline.} =
newArray(self.godotDictionary.keys())
proc values*(self: Dictionary): Array {.inline.} =
newArray(self.godotDictionary.values())
proc `[]`*(self: Dictionary; key: Variant): Variant {.inline.} =
newVariant(self.godotDictionary[key.godotVariant[]])
proc `[]`*(self: Dictionary; keyStr: string): Variant {.inline.} =
var godotVariant: GodotVariant
var godotStr = keyStr.toGodotString()
initGodotVariant(godotVariant, godotStr)
result = newVariant(self.godotDictionary[godotVariant])
godotStr.deinit()
godotVariant.deinit()
proc `[]=`*(self: Dictionary; key, value: Variant) {.inline.} =
self.godotDictionary[key.godotVariant[]] = value.godotVariant[]
proc `==`*(self, other: Dictionary): bool {.inline.} =
if self.isNil and other.isNil: return true
if self.isNil != other.isNil: return false
result = self.godotDictionary == other.godotDictionary
proc toJson*(self: Dictionary): string {.inline.} =
var s = self.godotDictionary.toJson()
result = $s
s.deinit()
iterator keys*(dict: Dictionary): Variant =
let keyArr = dict.keys()
for key in keyArr:
yield key
iterator values*(dict: Dictionary): Variant =
let valArr = dict.values()
for val in valArr:
yield val
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('}')

96
godot/core/dictionary.nim Normal file
View file

@ -0,0 +1,96 @@
# Copyright (c) 2017 Xored Software, Inc.
import hashes
import godotbase, arrays, variant, strings
type
Dictionary* {.importc: "godot_dictionary",
header: "godot_dictionary.h", byref.} = object
proc initVariant(dest: var Variant; dict: Dictionary) {.
importc: "godot_variant_new_dictionary",
header: "godot_variant.h".}
proc variant*(dict: Dictionary): Variant {.inline.} =
initVariant(result, dict)
proc asDictionary*(self: Variant): Dictionary {.
importc: "godot_variant_as_dictionary", header: "godot_variant.h".}
proc initDictionary(dest: var Dictionary;
src: Dictionary) {.
importc: "godot_dictionary_new_copy",
header: "godot_dictionary.h".}
proc deinit(self: var Dictionary) {.
importc: "godot_dictionary_destroy", header: "godot_dictionary.h".}
proc `=`(self: var Dictionary, other: Dictionary) {.inline.} =
initDictionary(self, other)
proc `=destroy`(self: Dictionary) {.inline.} =
unsafeAddr(self)[].deinit()
proc initDictionary(dest: var Dictionary) {.
importc: "godot_dictionary_new", header: "godot_dictionary.h".}
proc initDictionary*(): Dictionary {.inline.} =
initDictionary(result)
proc len*(self: Dictionary): cint {.
importc: "godot_dictionary_size", header: "godot_dictionary.h".}
proc isEmpty*(self: Dictionary): bool {.
importc: "godot_dictionary_empty", header: "godot_dictionary.h".}
proc clear*(self: var Dictionary) {.
importc: "godot_dictionary_clear", header: "godot_dictionary.h".}
proc contains*(self: Dictionary; key: Variant): bool {.
importc: "godot_dictionary_has",
header: "godot_dictionary.h".}
proc contains*(self: Dictionary; keys: Array): bool {.
importc: "godot_dictionary_has_all",
header: "godot_dictionary.h".}
proc del*(self: var Dictionary; key: Variant) {.
importc: "godot_dictionary_erase", header: "godot_dictionary.h".}
proc godotHash*(self: Dictionary): cint {.
importc: "godot_dictionary_hash", header: "godot_dictionary.h".}
proc hash*(self: Dictionary): Hash {.inline.} =
hash(godotHash(self))
proc keys*(self: Dictionary): Array {.
importc: "godot_dictionary_keys", header: "godot_dictionary.h".}
proc values*(self: Dictionary): Array {.
importc: "godot_dictionary_values", header: "godot_dictionary.h".}
proc `[]`*(self: Dictionary; key: Variant): Variant {.
importc: "godot_dictionary_get", header: "godot_dictionary.h".}
proc `[]`*(self: Dictionary; keyStr: string): Variant =
let key = variant(keyStr)
result = self[key]
proc `[]=`*(self: var Dictionary; key, value: Variant) {.
importc: "godot_dictionary_set",
header: "godot_dictionary.h".}
proc mget*(self: var Dictionary; key: Variant): ptr Variant {.
importc: "godot_dictionary_operator_index",
header: "godot_dictionary.h".}
proc `==`*(self, other: Dictionary): bool {.
importc: "godot_dictionary_operator_equal",
header: "godot_dictionary.h".}
proc toJson*(self: Dictionary): GodotString {.
importc: "godot_dictionary_to_json", header: "godot_dictionary.h".}
iterator keys*(dict: Dictionary): Variant =
let keyArr = dict.keys()
for key in keyArr:
yield key
iterator values*(dict: Dictionary): Variant =
let valArr = dict.values()
for val in valArr:
yield val
iterator pairs*(dict: Dictionary): tuple[key, val: Variant] =
for key in keys(dict):
yield (key, dict[key])

View file

@ -1,64 +1,107 @@
# Copyright (c) 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import math, godotinternal
type
Error* {.importc: "godot_error", header: "../godot.h",
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
# math helpers
const MAX_ARG_COUNT* = 128
{.push stackTrace: off.}
const EPSILON = 0.00001'f32
proc isEqualApprox*(a, b: float32): bool {.inline, noinit.} =
abs(a - b) < EPSILON
type
GodotObject* {.importc: "godot_object", header: "../godot.h".} = object
Array* {.importc: "godot_array", header: "godot_array.h", byref.} = object
Variant* {.importc: "godot_variant",
header: "godot_variant.h", byref.} = object
proc isEqualApprox*(a, b: float64): bool {.inline, noinit.} =
abs(a - b) < EPSILON
proc initArray(dest: var Array, src: Array) {.
importc: "godot_array_new_copy",
header: "godot_array.h".}
proc sign*(a: float32): float32 {.inline, noinit.} =
if a < 0: -1.0'f32 else: 1.0'f32
proc deinit(self: var Array) {.importc: "godot_array_destroy",
header: "godot_array.h".}
proc sign*(a: float64): float64 {.inline, noinit.} =
if a < 0: -1.0'f64 else: 1.0'f64
proc `=`(self: var Array, other: Array) {.inline.} =
initArray(self, other)
proc stepify*(value, step: float64): float64 {.inline, noinit.} =
if step != 0'f64:
floor(value / step + 0.5'f64) * step
else:
value
proc `=destroy`(self: Array) {.inline.} =
unsafeAddr(self).deinit()
proc stepify*(value, step: float32): float32 {.inline, noinit.} =
if step != 0'f32:
floor(value / step + 0.5'f32) * step
else:
value
proc initVariant(dest: var Variant; src: Variant) {.
importc: "godot_variant_new_copy", header: "godot_variant.h".}
when (NimMajor, NimMinor, NimPatch) < (0, 20, 4):
# Newer Nim has these procs in system module
proc deinit*(self: var Variant) {.
importc: "godot_variant_destroy", header: "godot_variant.h".}
proc min*(x, y: float32): float32 {.inline, noinit.} =
if x <= y: x else: y
proc `=`(self: var Variant, other: Variant) {.inline.} =
initVariant(self, other)
proc abs*(x: float32): float32 {.inline, noinit.} =
if x < 0.0: -x else: x
proc `=destroy`(self: Variant) {.inline.} =
unsafeAddr(self).deinit()
proc max*(x, y: float32): float32 {.inline, noinit.} =
if y <= x: x else: y
# System Functions
{.pop.} # stackTrace: off
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)
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)
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()
proc godotAlloc*(bytes: cint): pointer {.
importc: "godot_alloc", header: "../godot.h".}
## 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", header: "../godot.h".}
## 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", header: "../godot.h".}
## 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.

288
godot/core/godotcore.nim Normal file
View file

@ -0,0 +1,288 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase
import strings, vector2, rect2, vector3, transform2d, plane, quat
import rect3, basis, transform, color, nodepath, rid
import dictionary, arrays, poolarray, variant
export godotbase, strings, vector2, rect2, vector3, transform2d, plane, quat,
rect3, basis, transform, color, nodepath, rid, dictionary, arrays,
poolarray, variant
# MethodBind API
type
GodotMethodBind* {.importc: "godot_method_bind",
header: "../godot.h".} = object
proc getMethod*(className: cstring; methodName: cstring): ptr GodotMethodBind {.
importc: "godot_method_bind_get_method", header: "../godot.h".}
proc ptrCall*(methodBind: ptr GodotMethodBind;
instance: ptr GodotObject;
args: ptr array[MAX_ARG_COUNT, pointer];
ret: pointer) {.
importc: "godot_method_bind_ptrcall", header: "../godot.h".}
proc call*(methodBind: ptr GodotMethodBind;
instance: ptr GodotObject;
args: ptr array[MAX_ARG_COUNT, Variant]; argCount: cint;
callError: var VariantCallError): Variant {.
importc: "godot_method_bind_call", header: "../godot.h".}
# Script API
type
GodotNativeInitOptions* {.importc: "godot_native_init_options",
header: "../godot.h".} = object
inEditor* {.importc: "in_editor".}: bool
coreApiHash* {.importc: "core_api_hash".}: uint64
editorApiHash* {.importc: "editor_api_hash".}: uint64
noApiHash* {.importc: "no_api_hash".}: uint64
GodotNativeTerminateOptions* {.importc: "godot_native_terminate_options",
header: "../godot.h".} = object
inEditor* {.importc: "in_editor".}: bool
GodotMethodRPCMode* {.importc: "godot_method_rpc_mode", header: "../godot.h",
size: sizeof(cint), pure.} = enum
Disabled,
Remote,
Sync,
Master,
Slave
GodotMethodAttributes* {.importc: "godot_method_attributes",
header: "../godot.h".} = object
rpcMode* {.importc: "rpc_type".}: GodotMethodRPCMode
GodotPropertyHint* {.importc: "godot_property_hint", header: "../godot.h",
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* {.importc: "godot_property_usage_flags",
header: "../godot.h", 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* {.importc: "godot_property_attributes",
header: "../godot.h", bycopy.} = object
rsetType* {.importc: "rset_type".}: GodotMethodRPCMode
typ* {.importc: "type".}: cint
hint* {.importc: "hint".}: GodotPropertyHint
hintString* {.importc: "hint_string".}: GodotString
usage* {.importc: "usage".}: GodotPropertyUsageFlags
defaultValue* {.importc: "default_value".}: Variant
GodotInstanceCreateFunc* {.importc: "godot_instance_create_func",
header: "../godot.h", bycopy.} = object
createFunc* {.importc: "create_func".}:
proc (obj: ptr GodotObject; methodData: pointer): pointer {.noconv.}
## returns user data
methodData* {.importc: "method_data".}: pointer
freeFunc* {.importc: "free_func".}: proc (a2: pointer) {.noconv.}
GodotInstanceDestroyFunc* {.importc: "godot_instance_destroy_func",
header: "../godot.h", bycopy.} = object
destroyFunc* {.importc: "destroy_func".}:
proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer) {.noconv.}
methodData* {.importc: "method_data".}: pointer
freeFunc* {.importc: "free_func".}: proc (a2: pointer) {.noconv.}
proc godotScriptRegisterClass*(name, base: cstring;
create_func: GodotInstanceCreateFunc;
destroy_func: GodotInstanceDestroyFunc) {.
importc: "godot_script_register_class", header: "../godot.h".}
proc godotScriptRegisterToolClass*(name, base: cstring;
createFunc: GodotInstanceCreateFunc;
destroyFunc: GodotInstanceDestroyFunc) {.
importc: "godot_script_register_tool_class", header: "../godot.h".}
type
GodotInstanceMethod* {.importc: "godot_instance_method",
header: "../godot.h", bycopy.} = object
meth* {.importc: "method".}:
proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer; numArgs: cint;
args: var ptr array[MAX_ARG_COUNT, Variant]): Variant {.noconv.}
methodData* {.importc: "method_data".}: pointer
freeFunc* {.importc: "free_func".}: proc (a2: pointer) {.noconv.}
proc godotScriptRegisterMethod*(name: cstring; function_name: cstring;
attr: GodotMethodAttributes;
meth: GodotInstanceMethod) {.
importc: "godot_script_register_method", header: "../godot.h".}
type
GodotPropertySetFunc* {.importc: "godot_property_set_func",
header: "../godot.h", bycopy.} = object
setFunc* {.importc: "set_func".}: proc (obj: ptr GodotObject;
methodData: pointer;
userData: pointer;
value: Variant) {.noconv.}
methodData* {.importc: "method_data".}: pointer
freeFunc* {.importc: "free_func".}: proc (a2: pointer) {.noconv.}
GodotPropertyGetFunc* {.importc: "godot_property_get_func",
header: "../godot.h", bycopy.} = object
getFunc* {.importc: "get_func".}:
proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer): Variant {.noconv.}
methodData* {.importc: "method_data".}: pointer
freeFunc* {.importc: "free_func".}: proc (a2: pointer) {.noconv.}
proc godotScriptRegisterProperty*(name: cstring; path: cstring;
attr: var GodotPropertyAttributes;
setFunc: GodotPropertySetFunc;
getFunc: GodotPropertyGetFunc) {.
importc: "godot_script_register_property", header: "../godot.h".}
type
GodotSignalArgument* {.importc: "godot_signal_argument",
header: "../godot.h", bycopy.} = object
name* {.importc: "name".}: GodotString
typ* {.importc: "type".}: cint
hint* {.importc: "hint".}: GodotPropertyHint
hintString* {.importc: "hint_string".}: GodotString
usage* {.importc: "usage".}: GodotPropertyUsageFlags
defaultValue* {.importc: "default_value".}: Variant
GodotSignal* {.importc: "godot_signal", header: "../godot.h".} = object
name* {.importc: "name".}: GodotString
numArgs* {.importc: "num_args".}: cint
args* {.importc: "args".}: ptr GodotSignalArgument
numDefaultArgs* {.importc: "num_default_args".}: cint
defaultArgs* {.importc: "default_args".}: ptr Variant
proc godotScriptRegisterSignal*(name: cstring; signal: GodotSignal) {.
importc: "godot_script_register_signal", header: "../godot.h".}
proc getUserdata*(instance: ptr GodotObject): pointer {.
importc: "godot_native_get_userdata", header: "../godot.h".}
type
GodotClassConstructor* = proc (): ptr GodotObject {.gcsafe, noconv.}
proc getClassConstructor*(className: cstring): GodotClassConstructor {.
importc: "godot_get_class_constructor", header: "../godot.h".}
proc getGlobalConstants*(): Dictionary {.
importc: "godot_get_global_constants", header: "../godot.h".}
proc godotNew*(p_classname: cstring): ptr GodotObject {.
importc: "godot_new", header: "../godot.h".}
proc godotStackBottom*(): pointer {.
importc: "godot_get_stack_bottom", header: "../godot.h".}
proc deinit*(o: ptr GodotObject) {.
importc: "godot_object_destroy", header: "../godot.h".}
# print using Godot's error handler list
proc godotPrintError(description: cstring; function: cstring; file: cstring;
line: cint) {.
importc: "godot_print_error", header: "../godot.h".}
proc godotPrintWarning(description: cstring; function: cstring;
file: cstring; line: cint) {.
importc: "godot_print_warning", header: "../godot.h".}
proc godotPrint(message: GodotString) {.
importc: "godot_print", header: "../godot.h".}
proc print*(message: string) {.inline.} =
let s = message.toGodotString()
godotPrint(s)
template printWarning*(warn: typed) =
let (filename, line) = instantiationInfo()
godotPrintWarning(cstring($warn), nil, cstring(filename), line.cint)
template printError*(err: typed) =
let (filename, line) = instantiationInfo()
godotPrintError(cstring($err), nil, cstring(filename), line.cint)

View file

@ -1,102 +0,0 @@
# 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

View file

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

55
godot/core/nodepath.nim Normal file
View file

@ -0,0 +1,55 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, strings
type
NodePath* {.importc: "godot_node_path",
header: "godot_node_path.h", byref.} = object
proc initNodePath(dest: var NodePath; s: GodotString) {.
importc: "godot_node_path_new", header: "godot_node_path.h".}
proc initNodePath(dest: var NodePath;
src: NodePath) {.
importc: "godot_node_path_new_copy", header: "godot_node_path.h".}
proc deinit(self: var NodePath) {.
importc: "godot_node_path_destroy", header: "godot_node_path.h".}
proc initNodePath*(s: string): NodePath {.inline.} =
initNodePath(result, s.toGodotString())
proc `=destroy`(self: NodePath) {.inline.} =
unsafeAddr(self).deinit()
proc `=`(self: var NodePath, other: NodePath) {.inline.} =
initNodePath(self, other)
proc toGodotString*(self: NodePath): GodotString {.
importc: "godot_node_path_as_string", header: "godot_node_path.h".}
proc `$`*(self: NodePath): string {.inline.} =
let s = self.toGodotString()
result = $s
proc isAbsolute*(self: NodePath): bool {.
importc: "godot_node_path_is_absolute", header: "godot_node_path.h".}
proc nameCount*(self: NodePath): cint {.
importc: "godot_node_path_get_name_count",
header: "godot_node_path.h".}
proc getName*(self: NodePath; idx: cint): GodotString {.
importc: "godot_node_path_get_name", header: "godot_node_path.h".}
proc subnameCount*(self: NodePath): cint {.
importc: "godot_node_path_get_subname_count",
header: "godot_node_path.h".}
proc getSubname*(self: NodePath; idx: cint): GodotString {.
importc: "godot_node_path_get_subname",
header: "godot_node_path.h".}
proc property*(self: NodePath): GodotString {.
importc: "godot_node_path_get_property", header: "godot_node_path.h".}
proc isEmpty*(self: NodePath): bool {.
importc: "godot_node_path_is_empty", header: "godot_node_path.h".}
proc `==`*(a, b: NodePath): bool {.
importc: "godot_node_path_operator_equal",
header: "godot_node_path.h".}
converter fromString*(s: string): NodePath =
initNodePath(result, s.toGodotString())

View file

@ -1,73 +0,0 @@
# Copyright 2018 Xored Software, Inc.
import hashes
import internal/godotinternaltypes, internal/godotnodepaths,
internal/godotstrings
type
NodePath* = ref object
path: GodotNodePath
proc nodePathFinalizer(path: NodePath) =
path.path.deinit()
proc newNodePath*(path: GodotNodePath): NodePath =
## Moves the GodotNodePath into Nim wrapper. The ``path`` will be destroyed
## automatically when the result is no longer referenced.
new(result, nodePathFinalizer)
result.path = path
proc newNodePath*(s: string): NodePath =
new(result, nodePathFinalizer)
var str = s.toGodotString()
initGodotNodePath(result.path, str)
str.deinit()
proc godotNodePath*(path: NodePath): ptr GodotNodePath {.inline.} =
## WARNING: do not keep the returned value for longer than the lifetime of
## ``path``
result = addr path.path
proc `$`*(self: NodePath): string {.inline.} =
var s = self.path.toGodotString()
result = $s
s.deinit()
proc hash*(self: NodePath): Hash {.inline.} =
($self).hash()
proc isAbsolute*(self: NodePath): bool {.inline.} =
self.path.isAbsolute()
proc nameCount*(self: NodePath): int {.inline.} =
int(self.path.nameCount())
proc getName*(self: NodePath; idx: int): string {.inline.} =
var s = self.path.getName(idx.cint)
result = $s
s.deinit()
proc subnameCount*(self: NodePath): int {.inline.} =
int(self.path.subnameCount())
proc getSubname*(self: NodePath; idx: int): string {.inline.} =
var s = self.path.getSubname(idx.cint)
result = $s
s.deinit()
proc getConcatenatedSubnames*(self: NodePath): string {.inline.} =
var s = self.path.getConcatenatedSubnames()
result = $s
s.deinit()
proc isEmpty*(self: NodePath): bool {.inline.} =
self.path.isEmpty()
proc `==`*(a, b: NodePath): bool =
if a.isNil and b.isNil: return true
if a.isNil != b.isNil: return false
result = a.path == b.path
converter fromString*(s: string): NodePath =
newNodePath(s)

84
godot/core/plane.nim Normal file
View file

@ -0,0 +1,84 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, vector3, strings
type
Plane* {.importc: "godot_plane", header: "godot_plane.h", byref.} = object
proc initPlane(dest: var Plane; a, b, c, d: float32) {.
importc: "godot_plane_new_with_reals", header: "godot_plane.h".}
proc initPlane(dest: var Plane; v1, v2, v3: Vector3) {.
importc: "godot_plane_new_with_vectors",
header: "godot_plane.h".}
proc initPlane(dest: var Plane; normal: Vector3; d: float32) {.
importc: "godot_plane_new_with_normal",
header: "godot_plane.h".}
proc initPlane*(a, b, c, d: float32): Plane =
initPlane(result, a, b, c, d)
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", header: "godot_plane.h".}
proc `$`*(self: Plane): string {.inline.} =
$self.toGodotString()
proc normalized*(self: Plane): Plane {.
noSideEffect,
importc: "godot_plane_normalized", header: "godot_plane.h".}
proc center*(self: Plane): Vector3 {.
noSideEffect,
importc: "godot_plane_center", header: "godot_plane.h".}
proc getAnyPoint*(self: Plane): Vector3 {.
noSideEffect,
importc: "godot_plane_get_any_point", header: "godot_plane.h".}
proc isPointOver*(self: Plane; point: Vector3): bool {.
noSideEffect,
importc: "godot_plane_is_point_over",
header: "godot_plane.h".}
proc distanceTo*(self: Plane; point: Vector3): float32 {.
noSideEffect,
importc: "godot_plane_distance_to", header: "godot_plane.h".}
proc contains*(self: Plane; point: Vector3;
epsilon: float32): bool {.
noSideEffect,
importc: "godot_plane_has_point", header: "godot_plane.h".}
proc project*(self: Plane; point: Vector3): Vector3 {.
noSideEffect,
importc: "godot_plane_project", header: "godot_plane.h".}
proc intersect3*(self: Plane; dest: var Vector3;
b, c: Plane): bool {.
noSideEffect,
importc: "godot_plane_intersect_3",
header: "godot_plane.h".}
proc intersectsRay*(self: Plane; dest: var Vector3;
v, dir: Vector3): bool {.
noSideEffect,
importc: "godot_plane_intersects_ray",
header: "godot_plane.h".}
proc intersectsSegment*(self: Plane; dest: var Vector3;
segmentBegin, segmentEnd: Vector3): bool {.
noSideEffect, importc: "godot_plane_intersects_segment",
header: "godot_plane.h".}
proc `-`*(self: Plane): Plane {.
noSideEffect,
importc: "godot_plane_operator_neg", header: "godot_plane.h".}
proc `==`*(a, b: Plane): bool {.
noSideEffect,
importc: "godot_plane_operator_equal", header: "godot_plane.h".}
proc normal*(self: Plane): Vector3 {.
noSideEffect,
importc: "godot_plane_get_normal", header: "godot_plane.h".}
proc `normal=`*(self: var Plane; normal: Vector3) {.
importc: "godot_plane_set_normal", header: "godot_plane.h".}
proc d*(self: Plane): float32 {.
noSideEffect,
importc: "godot_plane_get_d", header: "godot_plane.h".}
proc `d=`*(self: var Plane; d: float32) {.
importc: "godot_plane_set_d", header: "godot_plane.h".}

View file

@ -1,66 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import hashes
import vector3
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
proc initPlane*(a, b, c, d: float32): Plane {.inline.} =
getGDNativeAPI().planeNewWithReals(result, a, b, c, d)
proc initPlane*(v1, v2, v3: Vector3): Plane {.inline.} =
getGDNativeAPI().planeNewWithVectors(result, v1, v2, v3)
proc initPlane*(normal: Vector3; d: float32): Plane {.inline.} =
result = Plane(
normal: normal,
d: d
)
proc `$`*(self: Plane): string {.inline.} =
$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 contains*(self: Plane; point: Vector3;
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 {.inline.} =
getGDNativeAPI().planeIntersect3(self, dest, b, c)
proc intersectsRay*(self: Plane; dest: var Vector3;
v, dir: Vector3): bool {.inline.} =
getGDNativeAPI().planeIntersectsRay(self, dest, v, dir)
proc intersectsSegment*(self: Plane; dest: var Vector3;
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)

476
godot/core/poolarray.nim Normal file
View file

@ -0,0 +1,476 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, color, vector2, vector3, strings
type
PoolByteArray* {.importc: "godot_pool_byte_array",
header: "godot_pool_arrays.h", byref.} = object
PoolIntArray* {.importc: "godot_pool_int_array",
header: "godot_pool_arrays.h", byref.} = object
PoolRealArray* {.importc: "godot_pool_real_array",
header: "godot_pool_arrays.h", byref.} = object
PoolStringArray* {.importc: "godot_pool_string_array",
header: "godot_pool_arrays.h", byref.} = object
PoolVector2Array* {.importc: "godot_pool_vector2_array",
header: "godot_pool_arrays.h", byref.} = object
PoolVector3Array* {.importc: "godot_pool_vector3_array",
header: "godot_pool_arrays.h", byref.} = object
PoolColorArray* {.importc: "godot_pool_color_array",
header: "godot_pool_arrays.h", byref.} = object
# byte
proc initPoolByteArray(dest: var PoolByteArray) {.
importc: "godot_pool_byte_array_new", header: "godot_pool_arrays.h".}
proc initPoolByteArray(dest: var PoolByteArray;
src: PoolByteArray) {.
importc: "godot_pool_byte_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolByteArray(dest: var PoolByteArray; arr: Array) {.
importc: "godot_pool_byte_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolByteArray) {.
importc: "godot_pool_byte_array_destroy", header: "godot_pool_arrays.h".}
proc initPoolByteArray*(): PoolByteArray {.inline.} =
initPoolByteArray(result)
proc initPoolByteArray*(arr: Array): PoolByteArray {.inline.} =
initPoolByteArray(result, arr)
proc `=`(self: var PoolByteArray, other: PoolByteArray) {.inline.} =
initPoolByteArray(self, other)
proc `=destroy`(self: PoolByteArray) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolByteArray;
data: uint8) {.
importc: "godot_pool_byte_array_append", header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolByteArray, data: uint8) {.
importc: "godot_pool_byte_array_push_back", header: "godot_pool_arrays.h".}
proc add*(self: var PoolByteArray;
arr: PoolByteArray) {.
importc: "godot_pool_byte_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolByteArray; idx: cint;
data: uint8): Error {.
importc: "godot_pool_byte_array_insert", header: "godot_pool_arrays.h".}
proc delete*(self: var PoolByteArray; idx: cint) {.
importc: "godot_pool_byte_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolByteArray) {.
importc: "godot_pool_byte_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolByteArray; size: cint) {.
importc: "godot_pool_byte_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolByteArray; idx: cint; data: uint8) {.
importc: "godot_pool_byte_array_set", header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolByteArray; idx: cint): uint8 {.
noSideEffect,
importc: "godot_pool_byte_array_get",
header: "godot_pool_arrays.h".}
proc len*(self: PoolByteArray): cint {.
noSideEffect,
importc: "godot_pool_byte_array_size", header: "godot_pool_arrays.h".}
iterator items*(arr: PoolByteArray): byte =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolByteArray): tuple[key: cint, val: byte] =
for i in 0..<arr.len:
yield (i, arr[i])
proc initPoolIntArray(dest: var PoolIntArray) {.
importc: "godot_pool_int_array_new", header: "godot_pool_arrays.h".}
proc initPoolIntArray(dest: var PoolIntArray;
src: PoolIntArray) {.
importc: "godot_pool_int_array_new_copy", header: "godot_pool_arrays.h".}
proc initPoolIntArray(dest: var PoolIntArray;
arr: Array) {.
importc: "godot_pool_int_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolIntArray) {.
importc: "godot_pool_int_array_destroy", header: "godot_pool_arrays.h".}
proc initPoolIntArray*(): PoolIntArray {.inline.} =
initPoolIntArray(result)
proc initPoolIntArray*(arr: Array): PoolIntArray {.inline.} =
initPoolIntArray(result, arr)
proc `=`(self: var PoolIntArray, other: PoolIntArray) {.inline.} =
initPoolIntArray(self, other)
proc `=destroy`(self: PoolIntArray) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolIntArray; data: cint) {.
importc: "godot_pool_int_array_append", header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolIntArray; data: cint) {.
importc: "godot_pool_int_array_push_back", header: "godot_pool_arrays.h".}
proc add*(self: var PoolIntArray; arr: PoolIntArray) {.
importc: "godot_pool_int_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolIntArray; idx: cint;
data: cint): Error {.
importc: "godot_pool_int_array_insert", header: "godot_pool_arrays.h".}
proc delete*(self: var PoolIntArray; idx: cint) {.
importc: "godot_pool_int_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolIntArray) {.
importc: "godot_pool_int_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolIntArray; size: cint) {.
importc: "godot_pool_int_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolIntArray; idx: cint; data: cint) {.
importc: "godot_pool_int_array_set", header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolIntArray; idx: cint): cint {.
noSideEffect,
importc: "godot_pool_int_array_get",
header: "godot_pool_arrays.h".}
proc len*(self: PoolIntArray): cint {.
noSideEffect,
importc: "godot_pool_int_array_size",
header: "godot_pool_arrays.h".}
iterator items*(arr: PoolIntArray): cint =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolIntArray): tuple[key: cint, val: cint] =
for i in 0..<arr.len:
yield (i, arr[i])
# Real
proc initPoolRealArray(dest: var PoolRealArray) {.
importc: "godot_pool_real_array_new", header: "godot_pool_arrays.h".}
proc initPoolRealArray(dest: var PoolRealArray;
src: PoolRealArray) {.
importc: "godot_pool_real_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolRealArray(dest: var PoolRealArray; arr: Array) {.
importc: "godot_pool_real_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolRealArray) {.
importc: "godot_pool_real_array_destroy", header: "godot_pool_arrays.h".}
proc initPoolRealArray*(): PoolRealArray {.inline.} =
initPoolRealArray(result)
proc initPoolRealArray*(arr: Array): PoolRealArray {.inline.} =
initPoolRealArray(result, arr)
proc `=`(self: var PoolRealArray, other: PoolRealArray) {.inline.} =
initPoolRealArray(self, other)
proc `=destroy`(self: PoolRealArray) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolRealArray; data: float32) {.
importc: "godot_pool_real_array_append",
header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolRealArray; data: float32) {.
importc: "godot_pool_real_array_push_back", header: "godot_pool_arrays.h".}
proc add*(self: var PoolRealArray; arr: PoolRealArray) {.
importc: "godot_pool_real_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolRealArray;
idx: cint; data: float32): Error {.
importc: "godot_pool_real_array_insert", header: "godot_pool_arrays.h".}
proc delete*(self: var PoolRealArray; idx: cint) {.
importc: "godot_pool_real_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolRealArray) {.
importc: "godot_pool_real_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolRealArray; size: cint) {.
importc: "godot_pool_real_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolRealArray; idx: cint; data: float32) {.
importc: "godot_pool_real_array_set", header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolRealArray; idx: cint): float32 {.
noSideEffect,
importc: "godot_pool_real_array_get",
header: "godot_pool_arrays.h".}
proc len*(self: PoolRealArray): cint {.
noSideEffect,
importc: "godot_pool_real_array_size", header: "godot_pool_arrays.h".}
iterator items*(arr: PoolRealArray): float32 =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolRealArray): tuple[key: cint, val: float32] =
for i in 0..<arr.len:
yield (i, arr[i])
# String
proc initPoolStringArray(dest: var PoolStringArray) {.
importc: "godot_pool_string_array_new", header: "godot_pool_arrays.h".}
proc initPoolStringArray(dest: var PoolStringArray;
src: PoolStringArray) {.
importc: "godot_pool_string_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolStringArray(dest: var PoolStringArray; arr: Array) {.
importc: "godot_pool_string_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolStringArray) {.
importc: "godot_pool_string_array_destroy",
header: "godot_pool_arrays.h".}
proc initPoolStringArray*(): PoolStringArray {.inline.} =
initPoolStringArray(result)
proc initPoolStringArray*(arr: Array): PoolStringArray {.inline.} =
initPoolStringArray(result, arr)
proc `=`(self: var PoolStringArray, other: PoolStringArray) {.inline.} =
initPoolStringArray(self, other)
proc `=destroy`(self: PoolStringArray) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolStringArray; data: GodotString) {.
importc: "godot_pool_string_array_append",
header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolStringArray; data: GodotString) {.
importc: "godot_pool_string_array_push_back",
header: "godot_pool_arrays.h".}
proc add*(self: var PoolStringArray; arr: PoolStringArray) {.
importc: "godot_pool_string_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolStringArray;
idx: cint; data: GodotString): Error {.
importc: "godot_pool_string_array_insert",
header: "godot_pool_arrays.h".}
proc delete*(self: var PoolStringArray; idx: cint) {.
importc: "godot_pool_string_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolStringArray) {.
importc: "godot_pool_string_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolStringArray; size: cint) {.
importc: "godot_pool_string_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolStringArray; idx: cint;
data: GodotString) {.
importc: "godot_pool_string_array_set",
header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolStringArray; idx: cint): GodotString {.
noSideEffect,
importc: "godot_pool_string_array_get",
header: "godot_pool_arrays.h".}
proc len*(self: PoolStringArray): cint {.
noSideEffect,
importc: "godot_pool_string_array_size",
header: "godot_pool_arrays.h".}
iterator items*(arr: PoolStringArray): GodotString =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolStringArray): tuple[key: cint, val: GodotString] =
for i in 0..<arr.len:
yield (i, arr[i])
# Vector2
proc initPoolVector2Array(dest: var PoolVector2Array) {.
importc: "godot_pool_vector2_array_new", header: "godot_pool_arrays.h".}
proc initPoolVector2Array(dest: var PoolVector2Array;
src: PoolVector2Array) {.
importc: "godot_pool_vector2_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolVector2Array(dest: var PoolVector2Array; arr: Array) {.
importc: "godot_pool_vector2_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolVector2Array) {.
importc: "godot_pool_vector2_array_destroy", header: "godot_pool_arrays.h".}
proc initPoolVector2Array*(): PoolVector2Array {.inline.} =
initPoolVector2Array(result)
proc initPoolVector2Array*(arr: Array): PoolVector2Array {.inline.} =
initPoolVector2Array(result, arr)
proc `=`(self: var PoolVector2Array, other: PoolVector2Array) {.inline.} =
initPoolVector2Array(self, other)
proc `=destroy`(self: PoolVector2Array) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolVector2Array; data: Vector2) {.
importc: "godot_pool_vector2_array_append",
header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolVector2Array; data: Vector2) {.
importc: "godot_pool_vector2_array_push_back",
header: "godot_pool_arrays.h".}
proc add*(self: var PoolVector2Array;
arr: PoolVector2Array) {.
importc: "godot_pool_vector2_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolVector2Array;
idx: cint; data: Vector2): Error {.
importc: "godot_pool_vector2_array_insert",
header: "godot_pool_arrays.h".}
proc delete*(self: var PoolVector2Array; idx: cint) {.
importc: "godot_pool_vector2_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolVector2Array) {.
importc: "godot_pool_vector2_array_invert",
header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolVector2Array; size: cint) {.
importc: "godot_pool_vector2_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolVector2Array; idx: cint;
data: ptr Vector2) {.
importc: "godot_pool_vector2_array_set", header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolVector2Array; idx: cint): Vector2 {.
noSideEffect,
importc: "godot_pool_vector2_array_get", header: "godot_pool_arrays.h".}
proc len*(self: PoolVector2Array): cint {.
noSideEffect,
importc: "godot_pool_vector2_array_size", header: "godot_pool_arrays.h".}
iterator items*(arr: PoolVector2Array): Vector2 =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolVector2Array): tuple[key: cint, val: Vector2] =
for i in 0..<arr.len:
yield (i, arr[i])
# Vector3
proc initPoolVector3Array*(dest: var PoolVector3Array) {.
importc: "godot_pool_vector3_array_new", header: "godot_pool_arrays.h".}
proc initPoolVector3Array*(dest: var PoolVector3Array;
src: PoolVector3Array) {.
importc: "godot_pool_vector3_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolVector3Array*(dest: var PoolVector3Array; arr: Array) {.
importc: "godot_pool_vector3_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolVector3Array) {.
importc: "godot_pool_vector3_array_destroy",
header: "godot_pool_arrays.h".}
proc initPoolVector3Array*(): PoolVector3Array {.inline.} =
initPoolVector3Array(result)
proc initPoolVector3Array*(arr: Array): PoolVector3Array {.inline.} =
initPoolVector3Array(result, arr)
proc `=`(self: var PoolVector3Array, other: PoolVector3Array) {.inline.} =
initPoolVector3Array(self, other)
proc `=destroy`(self: PoolVector3Array) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolVector3Array;
data: Vector3) {.
importc: "godot_pool_vector3_array_append",
header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolVector3Array;
data: Vector3) {.
importc: "godot_pool_vector3_array_push_back",
header: "godot_pool_arrays.h".}
proc add*(self: var PoolVector3Array;
arr: PoolVector3Array) {.
importc: "godot_pool_vector3_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolVector3Array;
idx: cint; data: Vector3): Error {.
importc: "godot_pool_vector3_array_insert",
header: "godot_pool_arrays.h".}
proc delete*(self: var PoolVector3Array; idx: cint) {.
importc: "godot_pool_vector3_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolVector3Array) {.
importc: "godot_pool_vector3_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolVector3Array; size: cint) {.
importc: "godot_pool_vector3_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolVector3Array;
idx: cint; data: Vector3) {.
importc: "godot_pool_vector3_array_set",
header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolVector3Array;
idx: cint): Vector3 {.
noSideEffect,
importc: "godot_pool_vector3_array_get",
header: "godot_pool_arrays.h".}
proc len*(self: PoolVector3Array): cint {.
noSideEffect,
importc: "godot_pool_vector3_array_size",
header: "godot_pool_arrays.h".}
iterator items*(arr: PoolVector3Array): Vector3 =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolVector3Array): tuple[key: cint, val: Vector3] =
for i in 0..<arr.len:
yield (i, arr[i])
# Color
proc initPoolColorArray(dest: var PoolColorArray) {.
importc: "godot_pool_color_array_new", header: "godot_pool_arrays.h".}
proc initPoolColorArray(dest: var PoolColorArray;
src: PoolColorArray) {.
importc: "godot_pool_color_array_new_copy",
header: "godot_pool_arrays.h".}
proc initPoolColorArray(dest: var PoolColorArray; arr: Array) {.
importc: "godot_pool_color_array_new_with_array",
header: "godot_pool_arrays.h".}
proc deinit(self: var PoolColorArray) {.
importc: "godot_pool_color_array_destroy", header: "godot_pool_arrays.h".}
proc initPoolColorArray*(): PoolColorArray {.inline.} =
initPoolColorArray(result)
proc initPoolColorArray*(arr: Array): PoolColorArray {.inline.} =
initPoolColorArray(result, arr)
proc `=`(self: var PoolColorArray, other: PoolColorArray) {.inline.} =
initPoolColorArray(self, other)
proc `=destroy`(self: PoolColorArray) {.inline.} =
unsafeAddr(self).deinit()
proc add*(self: var PoolColorArray; data: Color) {.
importc: "godot_pool_color_array_append",
header: "godot_pool_arrays.h".}
proc addFirst*(self: var PoolColorArray; data: Color) {.
importc: "godot_pool_color_array_push_back",
header: "godot_pool_arrays.h".}
proc add*(self: var PoolColorArray; arr: PoolColorArray) {.
importc: "godot_pool_color_array_append_array",
header: "godot_pool_arrays.h".}
proc insert*(self: var PoolColorArray;
idx: cint; data: Color): Error {.
importc: "godot_pool_color_array_insert",
header: "godot_pool_arrays.h".}
proc delete*(self: var PoolColorArray; idx: cint) {.
importc: "godot_pool_color_array_remove", header: "godot_pool_arrays.h".}
proc reverse*(self: var PoolColorArray) {.
importc: "godot_pool_color_array_invert", header: "godot_pool_arrays.h".}
proc setLen*(self: var PoolColorArray; size: cint) {.
importc: "godot_pool_color_array_resize", header: "godot_pool_arrays.h".}
proc `[]=`*(self: var PoolColorArray; idx: cint;
data: Color) {.
importc: "godot_pool_color_array_set", header: "godot_pool_arrays.h".}
proc `[]`*(self: PoolColorArray; idx: cint): Color {.
noSideEffect,
importc: "godot_pool_color_array_get", header: "godot_pool_arrays.h".}
proc len*(self: PoolColorArray): cint {.
noSideEffect,
importc: "godot_pool_color_array_size", header: "godot_pool_arrays.h".}
iterator items*(arr: PoolColorArray): Color =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolColorArray): tuple[key: cint, val: Color] =
for i in 0..<arr.len:
yield (i, arr[i])

View file

@ -1,167 +0,0 @@
# Copyright 2018 Xored Software, Inc.
import hashes
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
proc poolArrayFinalizer(arr: T) =
arr.fieldName.deinit()
proc newProcName*(): T {.inline.} =
new(result, poolArrayFinalizer)
initProcName(result.fieldName)
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: T; data: DataT) {.inline.} =
self.fieldName.add(data)
proc insert*(self: T; idx: int; data: DataT): Error {.inline.} =
self.fieldName.insert(idx.cint, data)
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 item in arr.fieldName.items:
yield item
iterator pairs*(arr: T): tuple[key: int, val: DataT] =
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,
initGodotPoolByteArray)
definePoolArray(PoolIntArray, GodotPoolIntArray, cint,
godotPoolIntArray, newPoolIntArray,
initGodotPoolIntArray)
definePoolArray(PoolRealArray, GodotPoolRealArray, float32,
godotPoolRealArray, newPoolRealArray,
initGodotPoolRealArray)
definePoolArray(PoolVector2Array, GodotPoolVector2Array, Vector2,
godotPoolVector2Array, newPoolVector2Array,
initGodotPoolVector2Array)
definePoolArray(PoolVector3Array, GodotPoolVector3Array, Vector3,
godotPoolVector3Array, newPoolVector3Array,
initGodotPoolVector3Array)
definePoolArray(PoolColorArray, GodotPoolColorArray, Color,
godotPoolColorArray, newPoolColorArray,
initGodotPoolColorArray)
definePoolArray(PoolStringArray, GodotPoolStringArray, string,
godotPoolStringArray, newPoolStringArray,
initGodotPoolStringArray, true)
proc add*(self: PoolStringArray; data: string) =
var s = data.toGodotString()
self.godotPoolStringArray.add(s)
s.deinit()
proc insert*(self: PoolStringArray; idx: int; data: string): Error =
var s = data.toGodotString()
result = self.godotPoolStringArray.insert(idx.cint, s)
s.deinit()
proc `[]=`*(self: PoolStringArray; idx: int; data: string) =
var s = data.toGodotString()
self.godotPoolStringArray[idx.cint] = s
s.deinit()
proc `[]`*(self: PoolStringArray; idx: int): string =
var s = self.godotPoolStringArray[idx.cint]
result = $s
s.deinit()
iterator items*(arr: PoolStringArray): string =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: PoolStringArray): tuple[key: int, val: string] =
for i in 0..<arr.len:
yield (i, arr[i])

114
godot/core/quat.nim Normal file
View file

@ -0,0 +1,114 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, vector3, strings
type
Quat* {.importc: "godot_quat", header: "godot_quat.h", byref.} = object
proc initQuat(dest: var Quat; x, y, z, w: float32) {.
importc: "godot_quat_new", header: "godot_quat.h".}
proc initQuat(dest: var Quat; axis: Vector3; angle: float32) {.
importc: "godot_quat_new_with_axis_angle",
header: "godot_quat.h".}
proc initQuat*(x, y, z, w: float32): Quat {.inline.} =
initQuat(result, x, y, z, w)
proc initQuat*(axis: Vector3; angle: float32): Quat {.inline.} =
initQuat(result, axis, angle)
proc x*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_get_x", header: "godot_quat.h".}
proc `x=`*(self: var Quat; val: float32) {.
noSideEffect,
importc: "godot_quat_set_x", header: "godot_quat.h".}
proc y*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_get_y", header: "godot_quat.h".}
proc `y=`*(self: var Quat; val: float32) {.
noSideEffect,
importc: "godot_quat_set_y", header: "godot_quat.h".}
proc z*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_get_z", header: "godot_quat.h".}
proc `z=`*(self: var Quat; val: float32) {.
noSideEffect,
importc: "godot_quat_set_z", header: "godot_quat.h".}
proc w*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_get_w", header: "godot_quat.h".}
proc `w=`*(self: var Quat; val: float32) {.
noSideEffect,
importc: "godot_quat_set_w", header: "godot_quat.h".}
proc toGodotString*(self: Quat): GodotString {.
noSideEffect,
importc: "godot_quat_as_string", header: "godot_quat.h".}
proc `$`*(self: Quat): string {.inline.} =
$self.toGodotString()
proc length*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_length", header: "godot_quat.h".}
proc lengthSquared*(self: Quat): float32 {.
noSideEffect,
importc: "godot_quat_length_squared", header: "godot_quat.h".}
proc normalized*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_normalized", header: "godot_quat.h".}
proc isNormalized*(self: Quat): bool {.
noSideEffect,
importc: "godot_quat_is_normalized", header: "godot_quat.h".}
proc inverse*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_inverse", header: "godot_quat.h".}
proc dot*(a, b: Quat): float32 {.
noSideEffect,
importc: "godot_quat_dot", header: "godot_quat.h".}
proc xform*(self: Quat; v: Vector3): Vector3 {.
noSideEffect,
importc: "godot_quat_xform", header: "godot_quat.h".}
proc slerp*(self: Quat; b: Quat; t: float32): Quat {.
noSideEffect,
importc: "godot_quat_slerp", header: "godot_quat.h".}
proc slerpni*(self: Quat; b: Quat; t: float32): Quat {.
noSideEffect,
importc: "godot_quat_slerpni", header: "godot_quat.h".}
proc cubicSlerp*(self, b, pre_a, post_b: Quat;
t: float32): Quat {.
noSideEffect,
importc: "godot_quat_cubic_slerp",
header: "godot_quat.h".}
proc `*`*(a: Quat, b: float32): Quat {.
noSideEffect,
importc: "godot_quat_operator_multiply",
header: "godot_quat.h".}
proc `*=`*(a: var Quat, b: float32) {.inline.} =
a = a * b
proc `+`*(a, b: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_add", header: "godot_quat.h".}
proc `+=`*(a: var Quat, b: Quat) {.inline.} =
a = a + b
proc `-`*(a, b: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_substract",
header: "godot_quat.h".}
proc `-=`* (a: var Quat, b: Quat) {.inline.} =
a = a - b
proc `/`*(self: Quat; b: float32): Quat {.
noSideEffect,
importc: "godot_quat_operator_divide", header: "godot_quat.h".}
proc `/=`*(self: var Quat, b: float32) {.inline.} =
self = self / b
proc `==`*(a, b: Quat): bool {.
noSideEffect,
importc: "godot_quat_operator_equal", header: "godot_quat.h".}
proc `-`*(self: Quat): Quat {.
noSideEffect,
importc: "godot_quat_operator_neg", header: "godot_quat.h".}

View file

@ -1,84 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import hashes
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
proc initQuat*(x, y, z, w: float32): Quat {.inline.} =
result = Quat(
x: x,
y: y,
z: z,
w: w
)
proc initQuat*(axis: Vector3; angle: float32): Quat {.inline.} =
getGDNativeAPI().quatNewWithAxisAngle(result, axis, angle)
proc `$`*(self: Quat): string {.inline.} =
$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 `*=`*(a: var Quat, b: float32) {.inline.} =
a = a * b
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 {.inline.} =
getGDNativeAPI().quatOperatorSubtract(a, b).toQuat()
proc `-=`* (a: var Quat, b: Quat) {.inline.} =
a = a - b
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 {.inline.} =
getGDNativeAPI().quatOperatorEqual(a, b)
proc `-`*(self: Quat): Quat {.inline.} =
getGDNativeAPI().quatOperatorNeg(self).toQuat()

View file

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

100
godot/core/rect3.nim Normal file
View file

@ -0,0 +1,100 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase, plane, vector3, strings
type
Rect3* {.importc: "godot_rect3", header: "godot_rect3.h", byref.} = object
proc initRect3(dest: var Rect3; pos, size: Vector3) {.
importc: "godot_rect3_new", header: "godot_rect3.h".}
proc initRect3*(pos, size: Vector3): Rect3 {.inline.} =
initRect3(result, pos, size)
proc position*(self: Rect3): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_position", header: "godot_rect3.h".}
proc setPosition*(self: var Rect3; v: Vector3) {.
noSideEffect
importc: "godot_rect3_set_position", header: "godot_rect3.h".}
proc size*(self: Rect3): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_size", header: "godot_rect3.h".}
proc setSize*(self: var Rect3; v: Vector3) {.
noSideEffect,
importc: "godot_rect3_set_size", header: "godot_rect3.h".}
proc toGodotString*(self: Rect3): GodotString {.
noSideEffect,
importc: "godot_rect3_as_string", header: "godot_rect3.h".}
proc `$`*(self: Rect3): string {.inline.} =
$self.toGodotString()
proc area*(self: Rect3): float32 {.
noSideEffect,
importc: "godot_rect3_get_area", header: "godot_rect3.h".}
proc hasNoArea*(self: Rect3): bool {.
noSideEffect,
importc: "godot_rect3_has_no_area", header: "godot_rect3.h".}
proc hasNoSurface*(self: Rect3): bool {.
noSideEffect,
importc: "godot_rect3_has_no_surface", header: "godot_rect3.h".}
proc intersects*(a, b: Rect3): bool {.
noSideEffect,
importc: "godot_rect3_intersects", header: "godot_rect3.h".}
proc encloses*(self, other: Rect3): bool {.
noSideEffect,
importc: "godot_rect3_encloses", header: "godot_rect3.h".}
proc merge*(self, other: Rect3): Rect3 {.
noSideEffect,
importc: "godot_rect3_merge", header: "godot_rect3.h".}
proc intersection*(self, other: Rect3): Rect3 {.
noSideEffect,
importc: "godot_rect3_intersection", header: "godot_rect3.h".}
proc intersectsPlane*(self: Rect3; plane: Plane): bool {.
noSideEffect,
importc: "godot_rect3_intersects_plane",
header: "godot_rect3.h".}
proc intersectsSegment*(self: Rect3; start, to: Vector3): bool {.
noSideEffect,
importc: "godot_rect3_intersects_segment",
header: "godot_rect3.h".}
proc contains*(self: Rect3; point: Vector3): bool {.
noSideEffect,
importc: "godot_rect3_has_point", header: "godot_rect3.h".}
proc getSupport*(self: Rect3; dir: Vector3): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_support", header: "godot_rect3.h".}
proc getLongestAxis*(self: Rect3): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_longest_axis", header: "godot_rect3.h".}
proc getLongestAxisIndex*(self: Rect3): cint {.
noSideEffect,
importc: "godot_rect3_get_longest_axis_index",
header: "godot_rect3.h".}
proc getLongestAxisSize*(self: Rect3): float32 {.
noSideEffect,
importc: "godot_rect3_get_longest_axis_size",
header: "godot_rect3.h".}
proc getShortestAxis*(self: Rect3): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_shortest_axis", header: "godot_rect3.h".}
proc getShortestAxisIndex*(self: Rect3): cint {.
noSideEffect,
importc: "godot_rect3_get_shortest_axis_index",
header: "godot_rect3.h".}
proc getShortestAxisSize*(self: Rect3): float32 {.
noSideEffect,
importc: "godot_rect3_get_shortest_axis_size",
header: "godot_rect3.h".}
proc expand*(self: Rect3; toPoint: Vector3): Rect3 {.
noSideEffect,
importc: "godot_rect3_expand", header: "godot_rect3.h".}
proc grow*(self: Rect3; by: float32): Rect3 {.
noSideEffect,
importc: "godot_rect3_grow", header: "godot_rect3.h".}
proc getEndpoint*(self: Rect3; idx: cint): Vector3 {.
noSideEffect,
importc: "godot_rect3_get_endpoint", header: "godot_rect3.h".}
proc `==`*(a, b: Rect3): bool {.
noSideEffect,
importc: "godot_rect3_operator_equal",
header: "godot_rect3.h".}

28
godot/core/rid.nim Normal file
View file

@ -0,0 +1,28 @@
import godotbase
type
RID* {.importc: "godot_rid", header: "godot_rid.h", byref.} = object
proc initRID(dest: var RID) {.
importc: "godot_rid_new",
header: "godot_rid.h".}
proc initRID(dest: var RID; obj: ptr GodotObject) {.
importc: "godot_rid_new_with_resource", header: "godot_rid.h".}
proc initRID*(): RID {.inline.} =
initRID(result)
proc initRID*(obj: ptr GodotObject): RID {.inline.} =
initRID(result, obj)
proc idCInt(self: RID): cint {.
noSideEffect,
importc: "godot_rid_get_id", header: "godot_rid.h".}
proc id*(self: RID): uint32 {.inline.} =
cast[uint32](self.idCInt())
proc `==`*(a, b: RID): bool {.
importc: "godot_rid_operator_equal", header: "godot_rid.h".}
proc `<`*(a, b: RID): bool {.
importc: "godot_rid_operator_less", header: "godot_rid.h".}

View file

@ -1,26 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import hashes
import godotcoretypes, internal/godotinternaltypes, gdnativeapi
proc initRID*(): RID {.inline.} =
getGDNativeAPI().ridNew(result)
proc initRID*(obj: ptr GodotObject): RID {.inline.} =
getGDNativeAPI().ridNewWithResource(result, obj)
proc id*(self: RID): uint32 {.inline.} =
cast[uint32](getGDNativeAPI().ridGetId(self))
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)

58
godot/core/strings.nim Normal file
View file

@ -0,0 +1,58 @@
# Copyright (c) 2017 Xored Software, Inc.
import godotbase
type
GodotString* {.importc: "godot_string", header: "godot_string.h",
byref.} = object
proc initGodotString(dest: var GodotString) {.
importc: "godot_string_new", header: "godot_string.h".}
proc initGodotString(dest: var GodotString; src: GodotString) {.
importc: "godot_string_new_copy", header: "godot_string.h".}
proc initGodotString(dest: var GodotString; contents: cstring;
size: cint) {.
importc: "godot_string_new_data", header: "godot_string.h".}
## Initializes ``dest`` from UTF-8 ``contents``
proc getData(self: GodotString; dest: cstring;
size: var cint) {.
noSideEffect
importc: "godot_string_get_data",
header: "godot_string.h".}
## Converts ``self`` into UTF-8 encoding, putting the result into ``dest``.
proc len*(self: GodotString): cint {.inline.} =
## Returns the length of string in bytes if it is represented as UTF-8.
getData(self, nil, result)
proc cstring*(self: GodotString): cstring {.
importc: "godot_string_c_str", header: "godot_string.h".}
proc `==`*(self, b: GodotString): bool {.
importc: "godot_string_operator_equal",
header: "godot_string.h".}
proc `<`*(self, b: GodotString): bool {.
importc: "godot_string_operator_less",
header: "godot_string.h".}
proc `&`*(self, b: GodotString): GodotString {.
importc: "godot_string_operator_plus",
header: "godot_string.h".}
proc deinit*(self: var GodotString) {.importc: "godot_string_destroy",
header: "godot_string.h".}
proc `=destroy`(self: GodotString) {.inline.} =
unsafeAddr(self).deinit()
proc `=`(self: var GodotString, other: GodotString) {.inline.} =
initGodotString(self, other)
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')
proc toGodotString*(s: string): GodotString {.inline.} =
## Converts the Nim string into ``GodotString``
initGodotString(result, unsafeAddr s[0], cint(s.len + 1))

82
godot/core/transform.nim Normal file
View file

@ -0,0 +1,82 @@
# Copyright (c) 2017 Xored Software, Inc.
type
Transform* {.importc: "godot_transform", header: "godot_transform.h",
byref.} = object
import godotbase, basis, variant, vector3, strings, plane, rect3
proc initTransform(dest: var Transform) {.
importc: "godot_transform_new_identity", header: "godot_transform.h".}
## Initializes the ``dest`` as identity transform.
proc initTransform(dest: var Transform;
xAxis, yAxis, zAxis, origin: Vector3) {.
importc: "godot_transform_new_with_axis_origin",
header: "godot_transform.h".}
proc initTransform(dest: var Transform; basis: Basis;
origin: Vector3) {.
importc: "godot_transform_new",
header: "godot_transform.h".}
proc initTransform*(): Transform {.inline.} =
initTransform(result)
proc initTransform*(xAxis, yAxis, zAxis,
origin: Vector3): Transform {.inline.} =
initTransform(result, xAxis, yAxis, zAxis, origin)
proc initTransform*(basis: Basis, origin: Vector3): Transform {.inline.} =
initTransform(result, basis, origin)
proc basis*(self: Transform): Basis {.
importc: "godot_transform_get_basis", header: "godot_transform.h".}
proc `basis=`*(self: var Transform; v: Basis) {.
importc: "godot_transform_set_basis", header: "godot_transform.h".}
proc origin*(self: Transform): Vector3 {.
importc: "godot_transform_get_origin", header: "godot_transform.h".}
proc `origin=`*(self: var Transform; v: Vector3) {.
importc: "godot_transform_set_origin", header: "godot_transform.h".}
proc toGodotString*(self: Transform): GodotString {.
importc: "godot_transform_as_string", header: "godot_transform.h".}
proc `$`*(self: Transform): string {.inline.} =
$self.toGodotString()
proc inverse*(self: Transform): Transform {.
importc: "godot_transform_inverse", header: "godot_transform.h".}
proc affineInverse*(self: Transform): Transform {.
importc: "godot_transform_affine_inverse",
header: "godot_transform.h".}
proc orthonormalized*(self: Transform): Transform {.
importc: "godot_transform_orthonormalized",
header: "godot_transform.h".}
proc rotated*(self: Transform; axis: Vector3;
phi: float32): Transform {.
importc: "godot_transform_rotated", header: "godot_transform.h".}
proc scaled*(self: Transform; scale: Vector3): Transform {.
importc: "godot_transform_scaled", header: "godot_transform.h".}
proc translated*(self: Transform; offset: Vector3): Transform {.
importc: "godot_transform_translated", header: "godot_transform.h".}
proc lookingAt*(self: Transform;
target, up: Vector3): Transform {.
importc: "godot_transform_looking_at", header: "godot_transform.h".}
proc xformPlane*(self: Transform; v: Plane): Plane {.
importc: "godot_transform_xform_plane", header: "godot_transform.h".}
proc xformInvPlane*(self: Transform; v: Plane): Plane {.
importc: "godot_transform_xform_inv_plane", header: "godot_transform.h".}
proc xformVector3*(self: Transform; v: Vector3): Vector3 {.
importc: "godot_transform_xform_vector3", header: "godot_transform.h".}
proc xformInvVector3*(self: Transform; v: Vector3): Vector3 {.
importc: "godot_transform_xform_inv_vector3", header: "godot_transform.h".}
proc xformRect3*(self: Transform; v: Vector3): Rect3 {.
importc: "godot_transform_xform_rect3", header: "godot_transform.h".}
proc xformInvRect3*(self: Transform; v: Vector3): Vector3 {.
importc: "godot_transform_xform_inv_rect3", header: "godot_transform.h".}
proc `==`*(self: Transform; b: Transform): bool {.
importc: "godot_transform_operator_equal", header: "godot_transform.h".}
proc `*`*(a, b: Transform): Transform {.
importc: "godot_transform_operator_multiply", header: "godot_transform.h".}
proc `*=`*(a: var Transform, b: Transform) {.inline.} =
a = a * b

View file

@ -1,79 +1,92 @@
# Copyright (c) 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import hashes, vector2
type
Transform2D* {.importc: "godot_transform2d", header: "godot_transform2d.h",
byref.} = object
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
import godotbase, strings, variant, vector2, rect2
proc initTransform2D(dest: var Transform2D) {.
importc: "godot_transform2d_new_identity", header: "godot_transform2d.h".}
proc initTransform2D(dest: var Transform2D; rot: float32; pos: Vector2) {.
importc: "godot_transform2d_new", header: "godot_transform2d.h".}
proc initTransform2D(dest: var Transform2D; xAxis, yAxis, origin: Vector2) {.
importc: "godot_transform2d_new_axis_origin",
header: "godot_transform2d.h".}
proc initTransform2D*(): Transform2D {.inline.} =
getGDNativeAPI().transform2DNewIdentity(result)
initTransform2D(result)
proc initTransform2D*(rot: float32; pos: Vector2): Transform2D {.inline.} =
getGDNativeAPI().transform2DNew(result, rot, pos)
initTransform2D(result, rot, pos)
proc initTransform2D*(xAxis, yAxis, origin: Vector2): Transform2D {.inline.} =
getGDNativeAPI().transform2DNewAxisOrigin(result, xAxis, yAxis, origin)
initTransform2D(result, xAxis, yAxis, origin)
proc toGodotString*(self: Transform2D): GodotString {.
importc: "godot_transform2d_as_string",
header: "godot_transform2d.h".}
proc `$`*(self: Transform2D): string {.inline.} =
$getGDNativeAPI().transform2DAsString(self)
$self.toGodotString()
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 inverse*(self: Transform2D): Transform2D {.
importc: "godot_transform2d_inverse", header: "godot_transform2d.h".}
proc affineInverse*(self: Transform2D): Transform2D {.
importc: "godot_transform2d_affine_inverse",
header: "godot_transform2d.h".}
proc rotation*(self: Transform2D): float32 {.
importc: "godot_transform2d_get_rotation",
header: "godot_transform2d.h".}
proc origin*(self: Transform2D): Vector2 {.
importc: "godot_transform2d_get_origin",
header: "godot_transform2d.h".}
proc scale*(self: Transform2D): Vector2 {.
importc: "godot_transform2d_get_scale",
header: "godot_transform2d.h".}
proc orthonormalized*(self: Transform2D): Transform2D {.
importc: "godot_transform2d_orthonormalized",
header: "godot_transform2d.h".}
proc rotated*(self: Transform2D; phi: float32): Transform2D {.
importc: "godot_transform2d_rotated",
header: "godot_transform2d.h".}
proc scaled*(self: Transform2D; scale: Vector2): Transform2D {.
importc: "godot_transform2d_scaled",
header: "godot_transform2d.h".}
proc translated*(self: Transform2D;
offset: Vector2): Transform2D {.
importc: "godot_transform2d_translated",
header: "godot_transform2d.h".}
proc xformVector2*(self: Transform2D; v: Vector2): Vector2 {.
importc: "godot_transform2d_xform_vector2",
header: "godot_transform2d.h".}
proc xformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.
importc: "godot_transform2d_xform_inv_vector2",
header: "godot_transform2d.h".}
proc basisXformVector2*(self: Transform2D;
v: Vector2): Vector2 {.
importc: "godot_transform2d_basis_xform_vector2",
header: "godot_transform2d.h".}
proc basisXformInvVector2*(self: Transform2D;
v: Vector2): Vector2 {.
importc: "godot_transform2d_basis_xform_inv_vector2",
header: "godot_transform2d.h".}
proc xformRect2*(self: Transform2D; v: Rect2): Rect2 {.
importc: "godot_transform2d_xform_rect2", header: "godot_transform2d.h".}
proc xformInvRect2*(self: Transform2D; v: Rect2): Rect2 {.
importc: "godot_transform2d_xform_inv_rect2",
header: "godot_transform2d.h".}
proc interpolateWith*(self, m: Transform2D;
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()
c: float32): Transform2D {.
importc: "godot_transform2d_interpolate_with",
header: "godot_transform2d.h".}
proc `==`*(a, b: Transform2D): bool {.
importc: "godot_transform2d_operator_equal",
header: "godot_transform2d.h".}
proc `*`*(a, b: Transform2D): Transform2D {.
importc: "godot_transform2d_operator_multiply",
header: "godot_transform2d.h".}
proc `*=`*(a: var Transform2D, b: Transform2D) {.inline.} =
a = a * b

View file

@ -1,76 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import hashes
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
import basis, vector3
proc initTransform*(): Transform {.inline.} =
result.basis = initBasis()
proc initTransform*(xAxis, yAxis, zAxis,
origin: Vector3): Transform {.inline.} =
var basis: Basis
basis.setAxis(0, xAxis)
basis.setAxis(1, yAxis)
basis.setAxis(2, zAxis)
Transform(basis: basis, origin: origin)
proc initTransform*(basis: Basis, origin: Vector3): Transform {.inline.} =
Transform(basis: basis, origin: origin)
proc `$`*(self: Transform): string {.inline.} =
$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 rotated*(self: Transform; axis: Vector3;
phi: float32): Transform {.inline.} =
getGDNativeAPI().transformRotated(self, axis, phi).toTransform()
proc scaled*(self: Transform; scale: Vector3): Transform {.inline.} =
getGDNativeAPI().transformScaled(self, scale).toTransform()
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

291
godot/core/variant.nim Normal file
View file

@ -0,0 +1,291 @@
import godotbase
import arrays, basis, nodepath
import plane, poolarray, quat, rect2, rect3, rid
import strings, transform, transform2d, vector2
import vector3, color
type
VariantType* {.importc: "godot_variant_type", header: "godot_variant.h",
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
VariantCallErrorType* {.importc: "godot_variant_call_error_error",
header: "godot_variant.h",
size: sizeof(cint),
pure.} = enum
OK,
InvalidMethod,
InvalidArgument,
TooManyArguments,
TooFewArguments,
InstanceIsNull
VariantCallError* {.importc: "godot_variant_call_error",
header: "godot_variant.h".} = object
error* {.importc: "error".}: VariantCallErrorType
argument* {.importc: "argument".}: cint
expected* {.importc: "expected".}: VariantType
proc getType*(p: Variant): VariantType {.
importc: "godot_variant_get_type", header: "godot_variant.h".}
proc initNilVariant(dest: var Variant) {.
importc: "godot_variant_new_nil", header: "godot_variant.h".}
proc initVariant(dest: var Variant; b: bool) {.
importc: "godot_variant_new_bool", header: "godot_variant.h".}
proc initVariant(dest: var Variant; i: uint64) {.
importc: "godot_variant_new_uint", header: "godot_variant.h".}
proc initVariant(dest: var Variant; i: int64) {.
importc: "godot_variant_new_int", header: "godot_variant.h".}
proc initVariant(dest: var Variant; r: cdouble) {.
importc: "godot_variant_new_real", header: "godot_variant.h".}
proc initVariant(dest: var Variant; s: GodotString) {.
importc: "godot_variant_new_string", header: "godot_variant.h".}
proc initVariant(dest: var Variant; v2: Vector2) {.
importc: "godot_variant_new_vector2", header: "godot_variant.h".}
proc initVariant(dest: var Variant; rect2: Rect2) {.
importc: "godot_variant_new_rect2", header: "godot_variant.h".}
proc initVariant(dest: var Variant; v3: Vector3) {.
importc: "godot_variant_new_vector3", header: "godot_variant.h".}
proc initVariant(dest: var Variant; t2d: Transform2D) {.
importc: "godot_variant_new_transform2d",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; plane: Plane) {.
importc: "godot_variant_new_plane", header: "godot_variant.h".}
proc initVariant(dest: var Variant; quat: Quat) {.
importc: "godot_variant_new_quat", header: "godot_variant.h".}
proc initVariant(dest: var Variant; rect3: Rect3) {.
importc: "godot_variant_new_rect3", header: "godot_variant.h".}
proc initVariant(dest: var Variant; basis: Basis) {.
importc: "godot_variant_new_basis", header: "godot_variant.h".}
proc initVariant(dest: var Variant;
trans: Transform) {.
importc: "godot_variant_new_transform",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; color: Color) {.
importc: "godot_variant_new_color", header: "godot_variant.h".}
proc initVariant(dest: var Variant; nodePath: NodePath) {.
importc: "godot_variant_new_node_path",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; rid: RID) {.
importc: "godot_variant_new_rid", header: "godot_variant.h".}
proc initVariant(dest: var Variant; obj: ptr GodotObject) {.
importc: "godot_variant_new_object", header: "godot_variant.h".}
proc initVariant(dest: var Variant; arr: Array) {.
importc: "godot_variant_new_array", header: "godot_variant.h".}
proc initVariant(dest: var Variant; pba: PoolByteArray) {.
importc: "godot_variant_new_pool_byte_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; pia: PoolIntArray) {.
importc: "godot_variant_new_pool_int_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; pra: PoolRealArray) {.
importc: "godot_variant_new_pool_real_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; psa: PoolStringArray) {.
importc: "godot_variant_new_pool_string_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; pv2a: PoolVector2Array) {.
importc: "godot_variant_new_pool_vector2_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; pv3a: PoolVector3Array) {.
importc: "godot_variant_new_pool_vector3_array",
header: "godot_variant.h".}
proc initVariant(dest: var Variant; pca: PoolColorArray) {.
importc: "godot_variant_new_pool_color_array",
header: "godot_variant.h".}
proc variant*(): Variant {.inline.} =
initNilVariant(result)
proc variant*(b: bool): Variant {.inline.} =
initVariant(result, b)
proc variant*(i: uint64): Variant {.inline.} =
initVariant(result, i)
proc variant*(i: int64): Variant {.inline.} =
initVariant(result, i)
proc variant*(r: cdouble): Variant {.inline.} =
initVariant(result, r)
proc variant*(s: GodotString): Variant {.inline.} =
initVariant(result, s)
proc variant*(s: string): Variant {.inline.} =
let godotStr = s.toGodotString()
initVariant(result, godotStr)
proc variant*(v2: Vector2): Variant {.inline.} =
initVariant(result, v2)
proc variant*(rect2: Rect2): Variant {.inline.} =
initVariant(result, rect2)
proc variant*(v3: Vector3): Variant {.inline.} =
initVariant(result, v3)
proc variant*(t2d: Transform2D): Variant {.inline.} =
initVariant(result, t2d)
proc variant*(plane: Plane): Variant {.inline.} =
initVariant(result, plane)
proc variant*(quat: Quat): Variant {.inline.} =
initVariant(result, quat)
proc variant*(rect3: Rect3): Variant {.inline.} =
initVariant(result, rect3)
proc variant*(basis: Basis): Variant {.inline.} =
initVariant(result, basis)
proc variant*(trans: Transform): Variant {.inline.} =
initVariant(result, trans)
proc variant*(color: Color): Variant {.inline.} =
initVariant(result, color)
proc variant*(nodePath: NodePath): Variant {.inline.} =
initVariant(result, nodePath)
proc variant*(rid: RID): Variant {.inline.} =
initVariant(result, rid)
proc variant*(obj: ptr GodotObject): Variant {.inline.} =
initVariant(result, obj)
proc variant*(arr: Array): Variant {.inline.} =
initVariant(result, arr)
proc variant*(pba: PoolByteArray): Variant {.inline.} =
initVariant(result, pba)
proc variant*(pia: PoolIntArray): Variant {.inline.} =
initVariant(result, pia)
proc variant*(pra: PoolRealArray): Variant {.inline.} =
initVariant(result, pra)
proc variant*(psa: PoolStringArray): Variant {.inline.} =
initVariant(result, psa)
proc variant*(pv2a: PoolVector2Array): Variant {.inline.} =
initVariant(result, pv2a)
proc variant*(pv3a: PoolVector3Array): Variant {.inline.} =
initVariant(result, pv3a)
proc variant*(pca: PoolColorArray): Variant {.inline.} =
initVariant(result, pca)
proc asBool*(self: Variant): bool {.
importc: "godot_variant_as_bool", header: "godot_variant.h".}
proc asUint*(self: Variant): uint64 {.
importc: "godot_variant_as_uint", header: "godot_variant.h".}
proc asInt*(self: Variant): int64 {.
importc: "godot_variant_as_int", header: "godot_variant.h".}
proc asReal*(self: Variant): cdouble {.
importc: "godot_variant_as_real", header: "godot_variant.h".}
proc asGodotString*(self: Variant): GodotString {.
importc: "godot_variant_as_string", header: "godot_variant.h".}
proc asString*(self: Variant): string =
let s = self.asGodotString()
result = $s
proc asVector2*(self: Variant): Vector2 {.
importc: "godot_variant_as_vector2", header: "godot_variant.h".}
proc asRect2*(self: Variant): Rect2 {.
importc: "godot_variant_as_rect2", header: "godot_variant.h".}
proc asVector3*(self: Variant): Vector3 {.
importc: "godot_variant_as_vector3", header: "godot_variant.h".}
proc asTransform2D*(self: Variant): Transform2D {.
importc: "godot_variant_as_transform2d", header: "godot_variant.h".}
proc asPlane*(self: Variant): Plane {.
importc: "godot_variant_as_plane", header: "godot_variant.h".}
proc asQuat*(self: Variant): Quat {.
importc: "godot_variant_as_quat", header: "godot_variant.h".}
proc asRect3*(self: Variant): Rect3 {.
importc: "godot_variant_as_rect3", header: "godot_variant.h".}
proc asBasis*(self: Variant): Basis {.
importc: "godot_variant_as_basis", header: "godot_variant.h".}
proc asTransform*(self: Variant): Transform {.
importc: "godot_variant_as_transform", header: "godot_variant.h".}
proc asColor*(self: Variant): Color {.
importc: "godot_variant_as_color", header: "godot_variant.h".}
proc asNodePath*(self: Variant): NodePath {.
importc: "godot_variant_as_node_path", header: "godot_variant.h".}
proc asRid*(self: Variant): RID {.
importc: "godot_variant_as_rid", header: "godot_variant.h".}
proc asObject*(self: Variant): ptr GodotObject {.
importc: "godot_variant_as_object", header: "godot_variant.h".}
proc asArray*(self: Variant): Array {.
importc: "godot_variant_as_array", header: "godot_variant.h".}
proc asPoolByteArray*(self: Variant): PoolByteArray {.
importc: "godot_variant_as_pool_byte_array",
header: "godot_variant.h".}
proc asPoolIntArray*(self: Variant): PoolIntArray {.
importc: "godot_variant_as_pool_int_array",
header: "godot_variant.h".}
proc asPoolRealArray*(self: Variant): PoolRealArray {.
importc: "godot_variant_as_pool_real_array",
header: "godot_variant.h".}
proc asPoolStringArray*(self: Variant): PoolStringArray {.
importc: "godot_variant_as_pool_string_array",
header: "godot_variant.h".}
proc asPoolVector2Array*(self: Variant): PoolVector2Array {.
importc: "godot_variant_as_pool_vector2_array",
header: "godot_variant.h".}
proc asPoolVector3Array*(self: Variant): PoolVector3Array {.
importc: "godot_variant_as_pool_vector3_array",
header: "godot_variant.h".}
proc asPoolColorArray*(self: Variant): PoolColorArray {.
importc: "godot_variant_as_pool_color_array",
header: "godot_variant.h".}
proc call*(self: Variant; meth: GodotString;
args: var array[MAX_ARG_COUNT, Variant]; argCount: cint;
error: var VariantCallError): Variant {.
importc: "godot_variant_call", header: "godot_variant.h".}
proc hasMethod*(self: Variant; meth: GodotString): bool {.
importc: "godot_variant_has_method", header: "godot_variant.h".}
proc `==`*(self, other: Variant): bool {.
importc: "godot_variant_operator_equal", header: "godot_variant.h".}
proc `<`*(self, other: Variant): bool {.
importc: "godot_variant_operator_less", header: "godot_variant.h".}
proc hashCompare*(self, other: Variant): bool {.
importc: "godot_variant_hash_compare", header: "godot_variant.h".}
proc booleanize*(self: Variant; isValid: var bool): bool {.
importc: "godot_variant_booleanize", header: "godot_variant.h".}

View file

@ -1,308 +0,0 @@
import tables, hashes
import godotcoretypes
import internal/godotinternaltypes, internal/godotvariants,
internal/godotstrings, internal/godotdictionaries,
internal/godotarrays
type
Variant* = ref object
godotVariant: GodotVariant
noDeinit: bool # used to avoid copying when passing the variant to Godot
export VariantType, VariantCallErrorType, VariantCallError
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 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)
proc newVariant*(v: Variant): Variant {.inline.} =
## Makes a copy
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, v.godotVariant)
proc newVariant*(v: GodotVariant): Variant {.inline.} =
new(result, variantFinalizer)
result.godotVariant = v
proc newVariant*(b: bool): Variant {.inline.} =
new(result, variantFinalizer)
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))
numConstructor(uint8, uint64)
numConstructor(uint16, uint64)
numConstructor(uint32, uint64)
numConstructor(uint64, uint64)
numConstructor(uint, uint64)
numConstructor(int8, int64)
numConstructor(int16, int64)
numConstructor(int32, int64)
numConstructor(int64, int64)
numConstructor(int, int64)
proc newVariant*(r: cdouble): Variant {.inline.} =
new(result, variantFinalizer)
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)
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)
proc newVariant*(rect2: Rect2): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, rect2)
proc newVariant*(v3: Vector3): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, v3)
proc newVariant*(t2d: Transform2D): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, t2d)
proc newVariant*(plane: Plane): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, plane)
proc newVariant*(quat: Quat): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, quat)
proc newVariant*(aabb: AABB): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, aabb)
proc newVariant*(basis: Basis): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, basis)
proc newVariant*(trans: Transform): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, trans)
proc newVariant*(color: Color): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, color)
proc newVariant*(nodePath: NodePath): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, nodePath.godotNodePath[])
proc newVariant*(godotNodePath: GodotNodePath): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, godotNodePath)
proc newVariant*(rid: RID): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, rid)
proc newVariant*(obj: ptr GodotObject): Variant {.inline.} =
new(result, variantFinalizer)
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[])
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)
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
proc `<`*(self, other: Variant): bool =
result = self.godotVariant < other.godotVariant
proc hashCompare*(self, other: Variant): bool =
self.godotVariant.hashCompare(other.godotVariant)
proc booleanize*(self: Variant): bool =
self.godotVariant.booleanize()

View file

@ -1,214 +1,117 @@
# Copyright (c) 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import math, godotbase, hashes
type
Vector2* {.importc: "godot_vector2", header: "godot_vector2.h",
byref.} = object
import internal/godotinternaltypes, internal/godotstrings
import godotcoretypes, gdnativeapi
import godotbase, strings
const EPSILON = 0.00001'f32
proc initVector2(dest: var Vector2; x, y: float32) {.
importc: "godot_vector2_new", header: "godot_vector2.h".}
{.push stackTrace: off.}
proc vec2*(x, y: float32): Vector2 {.inline.} =
initVector2(result, x, y)
proc vec2*(): Vector2 {.inline, noinit.} =
Vector2()
proc toGodotString*(self: Vector2): GodotString {.
importc: "godot_vector2_as_string", header: "godot_vector2.h".}
proc `$`*(self: Vector2): string {.inline.} =
$self.toGodotString()
proc vec2*(x, y: float32): Vector2 {.inline, noinit.} =
Vector2(x: x, y: y)
proc normalized*(self: Vector2): Vector2 {.
importc: "godot_vector2_normalized", header: "godot_vector2.h".}
proc length*(self: Vector2): float32 {.
importc: "godot_vector2_length", header: "godot_vector2.h".}
proc angle*(self: Vector2): float32 {.
importc: "godot_vector2_angle", header: "godot_vector2.h".}
proc lengthSquared*(self: Vector2): float32 {.
importc: "godot_vector2_length_squared", header: "godot_vector2.h".}
proc isNormalized*(self: Vector2): bool {.
importc: "godot_vector2_is_normalized", header: "godot_vector2.h".}
proc distanceTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_distance_to",
header: "godot_vector2.h".}
proc distanceSquaredTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_distance_squared_to",
header: "godot_vector2.h".}
proc angleTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_angle_to", header: "godot_vector2.h".}
proc angleToPoint*(self, to: Vector2): float32 {.
importc: "godot_vector2_angle_to_point",
header: "godot_vector2.h".}
proc lerp*(self, b: Vector2; t: float32): Vector2 {.
importc: "godot_vector2_linear_interpolate",
header: "godot_vector2.h".}
proc cubicInterpolate*(self, b, pre_a, post_b: Vector2; t: float32): Vector2 {.
importc: "godot_vector2_cubic_interpolate",
header: "godot_vector2.h".}
proc rotated*(self: Vector2; phi: float32): Vector2 {.
importc: "godot_vector2_rotated", header: "godot_vector2.h".}
proc tangent*(self: Vector2): Vector2 {.
importc: "godot_vector2_tangent", header: "godot_vector2.h".}
proc floor*(self: Vector2): Vector2 {.
importc: "godot_vector2_floor", header: "godot_vector2.h".}
proc snapped*(self: Vector2; by: Vector2): Vector2 {.
importc: "godot_vector2_snapped", header: "godot_vector2.h".}
proc aspect*(self: Vector2): float32 {.
importc: "godot_vector2_aspect", header: "godot_vector2.h".}
proc dot*(a, b: Vector2): float32 {.
importc: "godot_vector2_dot", header: "godot_vector2.h".}
proc slide*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_slide", header: "godot_vector2.h".}
proc bounce*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_bounce", header: "godot_vector2.h".}
proc reflect*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_reflect", header: "godot_vector2.h".}
proc abs*(self: Vector2): Vector2 {.
importc: "godot_vector2_abs", header: "godot_vector2.h".}
proc clamped*(self: Vector2; length: float32): Vector2 {.
importc: "godot_vector2_clamped", header: "godot_vector2.h".}
proc `$`*(self: Vector2): string {.inline, noinit.} =
$getGDNativeAPI().vector2AsString(self)
proc `+`*(a, b: Vector2): Vector2 {.
importc: "godot_vector2_operator_add", header: "godot_vector2.h".}
proc `+=`*(a: var Vector2, b: Vector2) {.inline.} =
a += b
proc hash*(self: Vector2): Hash {.inline, noinit.} =
!$(self.x.hash() !& self.y.hash())
proc `-`*(a, b: Vector2): Vector2 {.
importc: "godot_vector2_operator_substract", header: "godot_vector2.h".}
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",
header: "godot_vector2.h".}
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",
header: "godot_vector2.h".}
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", header: "godot_vector2.h".}
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: 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 `*`*(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.} =
proc `/`*(self: Vector2; scalar: float32): Vector2 {.
importc: "godot_vector2_operator_divide_scalar", header: "godot_vector2.h".}
proc `/=`*(self: var Vector2; scalar: float32) {.inline.} =
self = self / scalar
proc `==`*(self, other: Vector2): bool {.inline, noinit.} =
self.x == other.x and self.y == other.y
proc `==`*(a, b: Vector2): bool {.
importc: "godot_vector2_operator_equal", header: "godot_vector2.h".}
proc `<`*(a, b: Vector2): bool {.
importc: "godot_vector2_operator_less", header: "godot_vector2.h".}
proc `-`*(self: Vector2): Vector2 {.
importc: "godot_vector2_operator_neg", header: "godot_vector2.h".}
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
proc `x=`*(self: var Vector2; x: float32) {.
importc: "godot_vector2_set_x", header: "godot_vector2.h".}
proc `y=`*(self: var Vector2; y: float32) {.
importc: "godot_vector2_set_y", header: "godot_vector2.h".}
proc x*(self: Vector2): float32 {.
importc: "godot_vector2_get_x", header: "godot_vector2.h".}
proc y*(self: Vector2): float32 {.
importc: "godot_vector2_get_y", header: "godot_vector2.h".}

View file

@ -1,254 +1,148 @@
# Copyright (c) 2018 Xored Software, Inc.
# Copyright (c) 2017 Xored Software, Inc.
import math, hashes
import godotbase, godotcoretypes
type
Vector3* {.importc: "godot_vector3", header: "godot_vector3.h",
byref.} = object
const EPSILON = 0.00001'f32
import godotbase, basis, strings
{.push stackTrace: off.}
type
Vector3Axis {.importc: "godot_vector3_axis", header: "godot_vector3.h",
size: sizeof(cint), pure.} = enum
X,
Y,
Z
proc vec3*(): Vector3 {.inline.} =
Vector3()
proc initVector3*(dest: var Vector3; x, y, z: float32) {.
importc: "godot_vector3_new", header: "godot_vector3.h".}
proc vec3*(x, y, z: float32): Vector3 {.inline.} =
Vector3(x: x, y: y, z: z)
initVector3(result, x, y, z)
proc toGodotString*(self: Vector3): GodotString {.
importc: "godot_vector3_as_string", header: "godot_vector3.h".}
proc `$`*(self: Vector3): string {.inline.} =
result = newStringOfCap(40)
result.add('(')
result.add($self.x)
result.add(", ")
result.add($self.y)
result.add(", ")
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
result.z = a.z + b.z
proc `+=`*(a: var Vector3, b: Vector3) {.inline.} =
a.x += b.x
a.y += b.y
a.z += b.z
proc `-`*(a, b: Vector3): Vector3 {.inline.} =
result.x = a.x - b.x
result.y = a.y - b.y
result.z = a.z - b.z
proc `-=`*(a: var Vector3, b: Vector3) {.inline.} =
a.x -= b.x
a.y -= b.y
a.z -= b.z
proc `*`*(a, b: Vector3): Vector3 {.inline.} =
result.x = a.x * b.x
result.y = a.y * b.y
result.z = a.z * b.z
proc `*=`*(a: var Vector3, b: Vector3) {.inline.}=
a.x *= b.x
a.y *= b.y
a.z *= b.z
proc `*`*(a: Vector3; b: float32): Vector3 {.inline.} =
result.x = a.x * b
result.y = a.y * b
result.z = a.z * b
proc `*`*(b: float32; a: Vector3): Vector3 {.inline.} =
a * b
proc `*=`*(a: var Vector3; b: float32) {.inline.} =
a.x *= b
a.y *= b
a.z *= b
proc `/`*(a, b: Vector3): Vector3 =
result.x = a.x / b.x
result.y = a.y / b.y
result.z = a.z / b.z
proc `/=`*(a: var Vector3; b: Vector3) {.inline.} =
a.x /= b.x
a.y /= b.y
a.z /= b.z
proc `/`*(a: Vector3; b: float32): Vector3 =
result.x = a.x / b
result.y = a.y / b
result.z = a.z / b
proc `/=`*(a: var Vector3; b: float32) {.inline.} =
a.x /= b
a.y /= b
a.z /= b
proc `==`*(a, b: Vector3): bool {.inline.} =
a.x == b.x and a.y == b.y and a.z == b.z
proc `<`*(a, b: Vector3): bool =
if a.x == b.x:
if a.y == b.y:
return a.z < b.z
return a.y < b.y
return a.x < b.x
proc `-`*(self: Vector3): Vector3 =
result.x = -self.x
result.y = -self.y
result.z = -self.z
proc `[]`*(self: Vector3, idx: range[0..2]): float32 {.inline.} =
cast[array[3, float32]](self)[idx]
proc `[]`*(self: var Vector3, idx: range[0..2]): var float32 {.inline.} =
cast[ptr array[3, float32]](addr self)[][idx]
proc `[]=`*(self: var Vector3, idx: range[0..2],
val: float32) {.inline.} =
case idx:
of 0: self.x = val
of 1: self.y = val
of 2: self.z = val
proc minAxis*(self: Vector3): int {.inline.} =
if self.x < self.y:
if self.x < self.z: 0 else: 2
else:
if self.y < self.z: 1 else: 2
proc maxAxis*(self: Vector3): int {.inline.} =
if self.x < self.y:
if self.y < self.z: 2 else: 1
else:
if self.x < self.z: 2 else: 0
proc length*(self: Vector3): float32 {.inline.} =
let x2 = self.x * self.x
let y2 = self.y * self.y
let z2 = self.z * self.z
result = sqrt(x2 + y2 + z2)
proc lengthSquared*(self: Vector3): float32 {.inline.} =
let x2 = self.x * self.x
let y2 = self.y * self.y
let z2 = self.z * self.z
result = x2 + y2 + z2
proc normalize*(self: var Vector3) {.inline.} =
let len = self.length()
if len == 0:
self.x = 0
self.y = 0
self.z = 0
else:
self.x /= len
self.y /= len
self.z /= len
proc normalized*(self: Vector3): Vector3 {.inline.} =
result = self
result.normalize()
proc isNormalized*(self: Vector3): bool {.inline.} =
self.lengthSquared().isEqualApprox(1.0'f32)
proc zero*(self: var Vector3) {.inline.} =
self.x = 0
self.y = 0
self.z = 0
proc inverse*(self: Vector3): Vector3 {.inline.} =
vec3(1.0'f32 / self.x, 1.0'f32 / self.y, 1.0'f32 / self.z)
proc cross*(self, other: Vector3): Vector3 {.inline.} =
vec3(
self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z,
self.x * other.y - self.y * other.x)
proc dot*(self, other: Vector3): float32 {.inline.} =
self.x * other.x + self.y * other.y + self.z * other.z
proc abs*(self: Vector3): Vector3 {.inline.} =
vec3(abs(self.x), abs(self.y), abs(self.z))
proc sign*(self: Vector3): Vector3 {.inline.} =
vec3(sign(self.x), sign(self.y), sign(self.z))
proc floor*(self: Vector3): Vector3 {.inline.} =
vec3(floor(self.x), floor(self.y), floor(self.z))
proc ceil*(self: Vector3): Vector3 {.inline.} =
vec3(ceil(self.x), ceil(self.y), ceil(self.z))
proc lerp*(self: Vector3, other: Vector3, t: float32): Vector3 {.inline.} =
vec3(
self.x + t * (other.x - self.x),
self.y + t * (other.y - self.y),
self.z + t * (other.z - self.z)
)
proc distanceTo*(self, other: Vector3): float32 {.inline.} =
(other - self).length()
proc distanceSquaredTo*(self, other: Vector3): float32 {.inline.} =
(other - self).lengthSquared()
proc angleTo*(self, other: Vector3): float32 {.inline.} =
arctan2(self.cross(other).length(), self.dot(other))
proc slide*(self, n: Vector3): Vector3 {.inline.} =
assert(n.isNormalized())
result = self - n * self.dot(n)
proc reflect*(self, n: Vector3): Vector3 {.inline.} =
assert(n.isNormalized())
result = 2.0'f32 * n * self.dot(n) - self
proc bounce*(self, n: Vector3): Vector3 {.inline.} =
-self.reflect(n)
proc snap*(self: var Vector3, other: Vector3) =
self.x = stepify(self.x, other.x)
self.y = stepify(self.y, other.y)
self.z = stepify(self.z, other.z)
proc snapped*(self: Vector3, other: Vector3): Vector3 =
result = self
result.snap(other)
$self.toGodotString()
proc minAxis*(self: Vector3): cint {.
importc: "godot_vector3_min_axis", header: "godot_vector3.h".}
proc maxAxis*(self: Vector3): cint {.
importc: "godot_vector3_max_axis", header: "godot_vector3.h".}
proc length*(self: Vector3): float32 {.
importc: "godot_vector3_length", header: "godot_vector3.h".}
proc lengthSquared*(self: Vector3): float32 {.
importc: "godot_vector3_length_squared", header: "godot_vector3.h".}
proc isNormalized*(self: Vector3): bool {.
importc: "godot_vector3_is_normalized", header: "godot_vector3.h".}
proc normalized*(self: Vector3): Vector3 {.
importc: "godot_vector3_normalized", header: "godot_vector3.h".}
proc inverse*(self: Vector3): Vector3 {.
importc: "godot_vector3_inverse", header: "godot_vector3.h".}
proc snapped*(self: Vector3; by: float32): Vector3 {.
importc: "godot_vector3_snapped", header: "godot_vector3.h".}
proc rotated*(self: Vector3; axis: Vector3;
phi: float32): Vector3 {.
importc: "godot_vector3_rotated", header: "godot_vector3.h".}
proc lerp*(self: Vector3; b: Vector3; t: float32): Vector3 {.
importc: "godot_vector3_linear_interpolate", header: "godot_vector3.h".}
proc cubicInterpolate*(self, b, preA, postB: Vector3;
t: float32): Vector3 =
let p0 = preA
let p1 = self
let p2 = b
let p3 = postB
t: float32): Vector3 {.
importc: "godot_vector3_cubic_interpolate", header: "godot_vector3.h".}
proc dot*(a, b: Vector3): float32 {.
importc: "godot_vector3_dot", header: "godot_vector3.h".}
proc cross*(a, b: Vector3): Vector3 {.
importc: "godot_vector3_cross", header: "godot_vector3.h".}
proc outer*(a, b: Vector3): Basis {.
importc: "godot_vector3_outer", header: "godot_vector3.h".}
proc toDiagonalMatrix*(self: Vector3): Basis {.
importc: "godot_vector3_to_diagonal_matrix", header: "godot_vector3.h".}
proc abs*(self: Vector3): Vector3 {.
importc: "godot_vector3_abs", header: "godot_vector3.h".}
proc floor*(self: Vector3): Vector3 {.
importc: "godot_vector3_floor", header: "godot_vector3.h".}
proc ceil*(self: Vector3): Vector3 {.
importc: "godot_vector3_ceil", header: "godot_vector3.h".}
proc distanceTo*(a, b: Vector3): float32 {.
importc: "godot_vector3_distance_to", header: "godot_vector3.h".}
proc distanceSquaredTo*(a, b: Vector3): float32 {.
importc: "godot_vector3_distance_squared_to", header: "godot_vector3.h".}
proc angleTo*(self, to: Vector3): float32 {.
importc: "godot_vector3_angle_to", header: "godot_vector3.h".}
proc slide*(self, n: Vector3): Vector3 {.
importc: "godot_vector3_slide", header: "godot_vector3.h".}
proc bounce*(self, n: Vector3): Vector3 {.
importc: "godot_vector3_bounce", header: "godot_vector3.h".}
proc reflect*(self, b: Vector3): Vector3 {.
importc: "godot_vector3_reflect", header: "godot_vector3.h".}
let t2 = t * t
let t3 = t2 * t
proc `+`*(a, b: Vector3): Vector3 {.
importc: "godot_vector3_operator_add", header: "godot_vector3.h".}
proc `+=`*(a: var Vector3, b: Vector3) {.inline.} =
a = a + b
result = 0.5 * ((p1 * 2.0) +
(-p0 + p2) * t +
(2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3)
proc `-`*(a, b: Vector3): Vector3 {.
importc: "godot_vector3_operator_substract", header: "godot_vector3.h".}
proc `-=`*(a: var Vector3, b: Vector3) {.inline.} =
a = a - b
proc moveToward*(vFrom, to: Vector3, delta: float32): Vector3 =
let
vd = to - vFrom
vLen = vd.length
proc `*`*(a, b: Vector3): Vector3 {.
importc: "godot_vector3_operator_multiply_vector",
header: "godot_vector3.h".}
proc `*=`*(a: var Vector3, b: Vector3) {.inline.}=
a = a * b
if vLen <= delta or vLen < EPSILON:
result = to
else:
result = vFrom + (vd / vLen) * delta
proc `*`*(self: Vector3; b: float32): Vector3 {.
importc: "godot_vector3_operator_multiply_scalar",
header: "godot_vector3.h".}
proc `*=`*(a: var Vector3; b: float32) {.inline.} =
a = a * b
{.pop.} # stackTrace: off
proc `/`*(a, b: Vector3): Vector3 {.
importc: "godot_vector3_operator_divide_vector",
header: "godot_vector3.h".}
proc `/=`*(a: var Vector3; b: Vector3) {.inline.} =
a = a / b
proc `/`*(self: Vector3; b: float32): Vector3 {.
importc: "godot_vector3_operator_divide_scalar",
header: "godot_vector3.h".}
proc `/=`*(a: var Vector3; b: float32) {.inline.} =
a = a / b
proc `==`*(a, b: Vector3): bool {.
importc: "godot_vector3_operator_equal", header: "godot_vector3.h".}
proc `<`*(a, b: Vector3): bool {.
importc: "godot_vector3_operator_less", header: "godot_vector3.h".}
proc `-`*(self: Vector3): Vector3 {.
importc: "godot_vector3_operator_neg", header: "godot_vector3.h".}
proc setAxis(self: var Vector3; axis: Vector3Axis;
val: float32) {.
importc: "godot_vector3_set_axis", header: "godot_vector3.h".}
proc getAxis(self: Vector3; axis: Vector3Axis): float32 {.
importc: "godot_vector3_get_axis", header: "godot_vector3.h".}
proc `[]`(self: Vector3, idx: range[0..2]): float32 {.inline.} =
self.getAxis(Vector3Axis(idx))
proc `[]=`(self: var Vector3, idx: range[0..2],
val: float32): float32 {.inline.} =
self.setAxis(Vector3Axis(idx), val)
proc x*(self: Vector3): float32 {.inline.} =
self.getAxis(Vector3Axis.X)
proc `x=`*(self: var Vector3, val: float32) {.inline.} =
self.setAxis(Vector3Axis.X, val)
proc y*(self: Vector3): float32 {.inline.} =
self.getAxis(Vector3Axis.Y)
proc `y=`*(self: var Vector3, val: float32) {.inline.} =
self.setAxis(Vector3Axis.Y, val)
proc z*(self: Vector3): float32 {.inline.} =
self.getAxis(Vector3Axis.Z)
proc `z=`*(self: var Vector3, val: float32) {.inline.} =
self.setAxis(Vector3Axis.Z, val)

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,16 @@
# Copyright 2018 Xored Software, Inc.
# Copyright 2017 Xored Software, Inc.
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 core.godotbase, core.godotcore
import core / [strings, vector2, rect2, vector3, transform2d, plane, quat]
import core / [rect3, basis, transform, color, nodepath, rid]
import core / [dictionary, arrays, poolarray, variant]
import nim/godotmacros, nim/godotnim
import nim / [godotmacros, godotnim]
export godotbase, godotcoretypes, vector2, rect2, vector3, transform2d, planes,
quats, aabb, basis, transforms, colors, nodepaths, rids, dictionaries,
arrays, poolarrays, variants
export godotbase, strings, vector2, rect2, vector3, transform2d, plane, quat,
rect3, basis, transform, color, nodepath, rid, dictionary, arrays,
poolarray, variant
export godotmacros, godotnim
export GodotPropertyHint, GodotPropertyUsage
# from godotcore
export print, printWarning, printError

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,122 +0,0 @@
# Copyright 2018 Xored Software, Inc.
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
proc getMethod*(className: cstring;
methodName: cstring): ptr GodotMethodBind {.inline.} =
getGDNativeAPI().methodBindGetMethod(className, methodName)
proc ptrCall*(methodBind: ptr GodotMethodBind;
instance: ptr GodotObject;
args: ptr array[MAX_ARG_COUNT, pointer];
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 {.inline.} =
getGDNativeAPI().methodBindCall(
methodBind, instance, args, argCount, callError)
proc nativeScriptRegisterClass*(libHandle: pointer; name, base: cstring;
createFunc: GodotInstanceCreateFunc;
destroyFunc: GodotInstanceDestroyFunc)
{.inline.} =
getGDNativeAPI().nativeScriptRegisterClass(
libHandle, name, base, createFunc, destroyFunc)
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) {.inline.} =
getGDNativeAPI().nativeScriptRegisterMethod(
libHandle, name, functionName, attr, meth)
proc nativeScriptRegisterProperty*(libHandle: pointer;
name, path: cstring;
attr: ptr GodotPropertyAttributes;
setFunc: GodotPropertySetFunc;
getFunc: GodotPropertyGetFunc) {.inline.} =
getGDNativeAPI().nativeScriptRegisterProperty(
libHandle, name, path, attr, setFunc, getFunc)
proc nativeScriptRegisterSignal*(libHandle: pointer; name: cstring;
signal: GodotSignal) {.inline.} =
getGDNativeAPI().nativeScriptRegisterSignal(libHandle, name, signal)
proc getUserdata*(instance: ptr GodotObject): pointer {.inline.} =
getGDNativeAPI().nativeScriptGetUserdata(instance)
proc getClassConstructor*(className: cstring): GodotClassConstructor
{.inline.} =
getGDNativeAPI().getClassConstructor(className)
proc deinit*(o: ptr GodotObject) {.inline.} =
getGDNativeAPI().objectDestroy(o)
# print using Godot's error handler list
proc godotPrintError*(description, function, file: cstring;
line: cint) {.inline.} =
getGDNativeAPI().printError(description, function, file, line)
proc godotPrintWarning*(description, function, file: cstring;
line: cint) {.inline.} =
getGDNativeAPI().printWarning(description, function, file, line)
proc godotPrint*(message: GodotString) {.inline.} =
getGDNativeAPI().print(message)
var getClassMethodBind: ptr GodotMethodBind
proc getClassName*(o: ptr GodotObject): string =
if getClassMethodBind.isNil:
getClassMethodBind = getMethod(cstring"Object", cstring"get_class")
var ret: GodotString
getClassMethodBind.ptrCall(o, nil, addr ret)
result = $ret
deinit(ret)
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

@ -1,19 +0,0 @@
# 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,162 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import godotinternaltypes, gdnativeapi, core/godotcoretypes
proc len*(self: GodotArray): cint {.inline.} =
getGDNativeAPI().arraySize(self)
import hashes
proc initGodotArray*(dest: var GodotArray) {.inline.} =
getGDNativeAPI().arrayNew(dest)
proc initGodotArray*(dest: var GodotArray;
pca: GodotPoolColorArray) {.inline.} =
getGDNativeAPI().arrayNewPoolColorArray(dest, pca)
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 find*(self: GodotArray; what: GodotVariant;
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 hash*(self: GodotArray): Hash {.inline.} =
hash(godotHash(self))
proc insert*(self: var GodotArray; pos: cint;
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 rfind*(self: GodotArray; what: GodotVariant;
fromIdx: cint): cint {.inline.} =
getGDNativeAPI().arrayRFind(self, what, fromIdx)
proc sort*(self: var GodotArray) {.inline.} =
getGDNativeAPI().arraySort(self)
proc sortCustom*(self: var GodotArray; obj: ptr GodotObject;
funcName: GodotString) {.inline.} =
getGDNativeAPI().arraySortCustom(self, obj, funcName)
proc binarySearch*(self: var GodotArray, val: ptr GodotVariant,
before: bool) {.inline.} =
getGDNativeAPI().arrayBSearch(self, val, before)
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,56 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import godotinternaltypes, gdnativeapi
proc initGodotDictionary*(dest: var GodotDictionary) {.inline.} =
getGDNativeAPI().dictionaryNew(dest)
proc initGodotDictionary*(dest: var GodotDictionary;
src: GodotDictionary) {.inline.} =
getGDNativeAPI().dictionaryNewCopy(dest, src)
proc deinit*(self: var GodotDictionary) {.inline.} =
getGDNativeAPI().dictionaryDestroy(self)
proc len*(self: GodotDictionary): cint {.inline.} =
getGDNativeAPI().dictionarySize(self)
proc isEmpty*(self: GodotDictionary): bool {.inline.} =
getGDNativeAPI().dictionaryEmpty(self)
proc clear*(self: var GodotDictionary) {.inline.} =
getGDNativeAPI().dictionaryClear(self)
proc contains*(self: GodotDictionary; key: GodotVariant): bool {.inline.} =
getGDNativeAPI().dictionaryHas(self, key)
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,313 +0,0 @@
# Copyright 2018 Xored Software, Inc.
const MAX_ARG_COUNT* = 256
type
GodotArray* {.byref.} = object
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[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,40 +0,0 @@
# Copyright 2018 Xored Software, Inc.
import godotinternaltypes, gdnativeapi
proc initGodotNodePath*(dest: var GodotNodePath; s: GodotString) {.inline.} =
getGDNativeAPI().nodePathNew(dest, s)
proc initGodotNodePath*(dest: var GodotNodePath;
src: GodotNodePath) {.inline.} =
getGDNativeAPI().nodePathNewCopy(dest, src)
proc deinit*(self: var GodotNodePath) {.inline.} =
getGDNativeAPI().nodePathDestroy(self)
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,269 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import godotinternaltypes, gdnativeapi
import core/godotcoretypes
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)
proc initIdent*(dest: var ArrayT; src: ArrayT) {.inline.} =
getGDNativeAPI().newCopyProc(dest, src)
proc initIdent*(dest: var ArrayT; arr: GodotArray) {.inline.} =
getGDNativeAPI().newWithArrayProc(dest, arr)
proc deinit*(self: var ArrayT) {.inline.} =
getGDNativeAPI().destroyProc(self)
proc add*(self: var ArrayT; data: DataT) {.inline.} =
getGDNativeAPI().pushBackProc(self, data)
proc add*(self: var ArrayT; arr: ArrayT) {.inline.} =
getGDNativeAPI().appendArrayProc(self, arr)
proc insert*(self: var ArrayT; idx: cint;
data: DataT): Error {.inline.} =
getGDNativeAPI().insertProc(self, idx, data)
proc delete*(self: var ArrayT; idx: cint) {.inline.} =
getGDNativeAPI().removeProc(self, idx)
proc reverse*(self: var ArrayT) {.inline.} =
getGDNativeAPI().invertProc(self)
proc setLen*(self: var ArrayT; size: cint) {.inline.} =
getGDNativeAPI().resizeProc(self, size)
proc `[]=`*(self: var ArrayT; idx: cint; data: DataT) {.inline.} =
getGDNativeAPI().setProc(self, idx, data)
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 len*(self: ArrayT): cint {.inline.} =
getGDNativeAPI().sizeProc(self)
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 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)
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)
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 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
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)
genPoolArrayAPI(GodotPoolByteArray, initGodotPoolByteArray, byte,
poolByteArrayNew,
poolByteArrayNewCopy,
poolByteArrayNewWithArray,
poolByteArrayAppend,
poolByteArrayAppendArray,
poolByteArrayInsert,
poolByteArrayInvert,
poolByteArrayPushBack,
poolByteArrayRemove,
poolByteArrayResize,
poolByteArraySet,
poolByteArrayGet,
poolByteArraySize,
poolByteArrayDestroy,
poolByteArrayRead,
poolByteArrayWrite,
poolByteArrayReadAccessPtr,
poolByteArrayWriteAccessPtr,
poolByteArrayReadAccessDestroy,
poolByteArrayWriteAccessDestroy)
genPoolArrayAPI(GodotPoolIntArray, initGodotPoolIntArray, cint,
poolIntArrayNew,
poolIntArrayNewCopy,
poolIntArrayNewWithArray,
poolIntArrayAppend,
poolIntArrayAppendArray,
poolIntArrayInsert,
poolIntArrayInvert,
poolIntArrayPushBack,
poolIntArrayRemove,
poolIntArrayResize,
poolIntArraySet,
poolIntArrayGet,
poolIntArraySize,
poolIntArrayDestroy,
poolIntArrayRead,
poolIntArrayWrite,
poolIntArrayReadAccessPtr,
poolIntArrayWriteAccessPtr,
poolIntArrayReadAccessDestroy,
poolIntArrayWriteAccessDestroy)
genPoolArrayAPI(GodotPoolRealArray, initGodotPoolRealArray, float32,
poolRealArrayNew,
poolRealArrayNewCopy,
poolRealArrayNewWithArray,
poolRealArrayAppend,
poolRealArrayAppendArray,
poolRealArrayInsert,
poolRealArrayInvert,
poolRealArrayPushBack,
poolRealArrayRemove,
poolRealArrayResize,
poolRealArraySet,
poolRealArrayGet,
poolRealArraySize,
poolRealArrayDestroy,
poolRealArrayRead,
poolRealArrayWrite,
poolRealArrayReadAccessPtr,
poolRealArrayWriteAccessPtr,
poolRealArrayReadAccessDestroy,
poolRealArrayWriteAccessDestroy)
genPoolArrayAPI(GodotPoolStringArray, initGodotPoolStringArray, GodotString,
poolStringArrayNew,
poolStringArrayNewCopy,
poolStringArrayNewWithArray,
poolStringArrayAppend,
poolStringArrayAppendArray,
poolStringArrayInsert,
poolStringArrayInvert,
poolStringArrayPushBack,
poolStringArrayRemove,
poolStringArrayResize,
poolStringArraySet,
poolStringArrayGet,
poolStringArraySize,
poolStringArrayDestroy,
poolStringArrayRead,
poolStringArrayWrite,
poolStringArrayReadAccessPtr,
poolStringArrayWriteAccessPtr,
poolStringArrayReadAccessDestroy,
poolStringArrayWriteAccessDestroy)
genPoolArrayAPI(GodotPoolVector2Array, initGodotPoolVector2Array, Vector2,
poolVector2ArrayNew,
poolVector2ArrayNewCopy,
poolVector2ArrayNewWithArray,
poolVector2ArrayAppend,
poolVector2ArrayAppendArray,
poolVector2ArrayInsert,
poolVector2ArrayInvert,
poolVector2ArrayPushBack,
poolVector2ArrayRemove,
poolVector2ArrayResize,
poolVector2ArraySet,
poolVector2ArrayGet,
poolVector2ArraySize,
poolVector2ArrayDestroy,
poolVector2ArrayRead,
poolVector2ArrayWrite,
poolVector2ArrayReadAccessPtr,
poolVector2ArrayWriteAccessPtr,
poolVector2ArrayReadAccessDestroy,
poolVector2ArrayWriteAccessDestroy)
genPoolArrayAPI(GodotPoolVector3Array, initGodotPoolVector3Array, Vector3,
poolVector3ArrayNew,
poolVector3ArrayNewCopy,
poolVector3ArrayNewWithArray,
poolVector3ArrayAppend,
poolVector3ArrayAppendArray,
poolVector3ArrayInsert,
poolVector3ArrayInvert,
poolVector3ArrayPushBack,
poolVector3ArrayRemove,
poolVector3ArrayResize,
poolVector3ArraySet,
poolVector3ArrayGet,
poolVector3ArraySize,
poolVector3ArrayDestroy,
poolVector3ArrayRead,
poolVector3ArrayWrite,
poolVector3ArrayReadAccessPtr,
poolVector3ArrayWriteAccessPtr,
poolVector3ArrayReadAccessDestroy,
poolVector3ArrayWriteAccessDestroy)
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,54 +0,0 @@
# Copyright (c) 2018 Xored Software, Inc.
import godotinternaltypes, gdnativeapi
proc initGodotString(dest: var GodotString) {.inline, raises: [].} =
getGDNativeAPI().stringNew(dest)
proc initGodotString(dest: var GodotString; contents: cstring;
size: cint) {.inline.} =
## Initializes ``dest`` from UTF-8 ``contents``
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.} =
getGDNativeAPI().stringLength(self)
proc dataPtr*(self: GodotString): ptr cwchar_t {.inline.} =
getGDNativeAPI().stringWideStr(self)
proc `$`*(self: GodotString): string =
## Converts the ``GodotString`` into Nim string
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, 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``
if s.isNil:
initGodotString(result)
else:
initGodotString(result, s, cint(s.len + 1))

View file

@ -1,217 +0,0 @@
# Copyright 2018 Xored Software, Inc.
import core/godotcoretypes, godotinternaltypes, gdnativeapi
proc getType*(p: GodotVariant): VariantType {.inline.} =
getGDNativeAPI().variantGetType(p)
proc initGodotVariant*(dest: var GodotVariant) {.inline.} =
getGDNativeAPI().variantNewNil(dest)
proc initGodotVariant*(dest: var GodotVariant, src: GodotVariant) {.inline.} =
getGDNativeAPI().variantNewCopy(dest, src)
proc initGodotVariant*(dest: var GodotVariant; b: bool) {.inline.} =
getGDNativeAPI().variantNewBool(dest, b)
proc initGodotVariant*(dest: var GodotVariant; i: uint64) {.inline.} =
getGDNativeAPI().variantNewUInt(dest, i)
proc initGodotVariant*(dest: var GodotVariant; i: int64) {.inline.} =
getGDNativeAPI().variantNewInt(dest, i)
proc initGodotVariant*(dest: var GodotVariant; r: cdouble) {.inline.} =
getGDNativeAPI().variantNewReal(dest, r)
proc initGodotVariant*(dest: var GodotVariant; s: GodotString) {.inline.} =
getGDNativeAPI().variantNewString(dest, s)
proc initGodotVariant*(dest: var GodotVariant; v2: Vector2) {.inline.} =
getGDNativeAPI().variantNewVector2(dest, v2)
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()

View file

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

View file

@ -1,8 +1,8 @@
# Copyright 2018 Xored Software, Inc.
# Copyright 2017 Xored Software, Inc.
import macros, tables, typetraits, strutils, sets, sequtils, options, algorithm
import godotinternal, internal/godotvariants
import godotnim, core/variants
import macros, tables, typetraits
import "../core/godotcore.nim"
import godotnim
type
VarDecl = ref object
@ -10,10 +10,9 @@ type
typ: NimNode
defaultValue: NimNode
isNoGodot: bool
hint: Option[string]
hintStr: Option[string]
usage: NimNode
isExported: bool
hint: string
hintTip: string
usage: string
MethodDecl = ref object
name: string
@ -28,45 +27,27 @@ 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.strVal
result.name = $(definition.ident)
else:
if not (definition.kind == nnkInfix and
definition[0].strVal == "of"):
if not (definition.kind == nnkInfix and definition[0].ident == !"of"):
parseError(definition, "invalid type definition")
result.name = definition[1].strVal
result.name = $(definition[1].ident)
case definition[2].kind:
of nnkIdent:
result.parentName = definition[2].strVal
result.parentName = $definition[2].ident
else:
parseError(definition[2], "parent type expected")
when not declared(newRStrLit):
proc newRStrLit(s: string): NimNode {.compileTime.} =
proc newRStrLit(s: string): NimNode {.compileTime.} =
result = newNimNode(nnkRStrLit)
result.strVal = s
@ -74,16 +55,42 @@ proc newCStringLit(s: string): NimNode {.compileTime.} =
newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s))
iterator pragmas(node: NimNode):
tuple[key: string, value: NimNode, index: int] =
tuple[key: NimIdent, value: string, index: int] =
assert node.kind in {nnkPragma, nnkEmpty}
for index in countdown(node.len - 1, 0):
if node[index].kind == nnkExprColonExpr:
yield (node[index][0].strVal, node[index][1], index)
let val = $(node[index][1])
yield (node[index][0].ident, val, index)
elif node[index].kind == nnkIdent:
yield (node[index].strVal, nil, index)
yield (node[index].ident, nil, index)
proc removePragmaNode(statement: NimNode,
pname: string): NimNode {.compileTime.} =
proc hasPragma(statement: NimNode, pname: string): bool =
## Checks if the pragma is present in the `statement`
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:
return true
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.} =
## 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
@ -93,30 +100,11 @@ proc removePragmaNode(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.eqIdent(pname):
if ident == pnameIdent:
pragmas.del(i)
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)
return (if val.isNil: "" else: val)
proc isExported(node: NimNode): bool {.compileTime.} =
if node.kind == nnkPragmaExpr:
@ -128,36 +116,38 @@ 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 hintStr = removeStrPragma(nameNode, "hintStr")
let usage = removePragmaNode(nameNode, "usage")
let hintTip = removeStrPragma(nameNode, "tip")
let usage = removeStrPragma(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: typ,
typ: identDefs[identDefs.len - 2],
defaultValue: identDefs[identDefs.len - 1],
hint: hint,
hintStr: hintStr,
isNoGodot: not isGdExport,
usage: usage,
isExported: nameNode.isExported()
hintTip: hintTip,
isNoGodot: isNoGodot,
usage: usage
))
proc parseMethod(meth: NimNode): MethodDecl =
assert(meth.kind in {nnkProcDef, nnkMethodDef})
let methName = meth[0]
let isGdExport = removePragma(meth, "gdExport")
let isNoGodot = (meth.kind != nnkMethodDef and not isGdExport) or
removePragma(meth, "noGdExport")
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")
result = MethodDecl(
name: $meth[0].basename,
args: newSeq[VarDecl](),
@ -172,33 +162,16 @@ proc parseMethod(meth: NimNode): MethodDecl =
proc parseVarSection(decl: NimNode): seq[VarDecl] =
assert(decl.kind == nnkVarSection)
for i in 0..<decl.len:
if i == 0:
result = identDefsToVarDecls(decl[i])
else:
result.add(identDefsToVarDecls(decl[i]))
result = identDefsToVarDecls(decl[0])
proc parseType(ast: NimNode): ObjectDecl =
let definition = ast[0]
let body = ast[^1]
proc parseType(definition, callSite: NimNode): ObjectDecl =
let body = callSite[^1]
result = ObjectDecl(
fields: newSeq[VarDecl](),
methods: newSeq[MethodDecl]()
)
(result.name, result.parentName) = extractNames(definition)
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"
if result.parentName.isNil: result.parentName = "Object"
for statement in body:
case statement.kind:
of nnkVarSection:
@ -215,7 +188,7 @@ proc parseType(ast: NimNode): ObjectDecl =
macro invokeVarArgs(procIdent, objIdent;
minArgs, maxArgs: static[int], numArgsIdent,
argSeqIdent; argTypes: seq[NimNode],
hasReturnValue, isStaticCall: static[bool]): untyped =
hasReturnValue: static[bool]): typed =
## Produces statement in form:
##
## .. code-block:: nim
@ -232,32 +205,22 @@ macro invokeVarArgs(procIdent, objIdent;
## error(...)
template conv(procLit, argT, argSeq, idx, argIdent, errIdent) =
let v = newVariant(argSeq[idx][])
v.markNoDeinit() # args will be destroyed externally
let (argIdent, errIdent) = godotToNim[argT](v)
let (argIdent, errIdent) = godotToNim[argT](argSeq[idx])
if errIdent != ConversionResult.OK:
let errorKind = if errIdent == ConversionResult.TypeError: "a type error"
else: "a range error"
printError(
"Failed to invoke Nim procedure " & $procLit &
": " & errorKind & " has occurred when converting argument " & $idx &
" of Godot type " & $argSeq[idx][].getType())
" of Godot type " & $argSeq[idx].getType())
return
# these help to avoid exporting internal modules
# thanks to closed symbol binding
template initGodotVariantCall(result) =
initGodotVariant(result)
template initGodotVariantCall(result, src) =
initGodotVariant(result, src)
result = newNimNode(nnkCaseStmt)
result.add(numArgsIdent)
for i in minArgs..maxArgs:
let branch = newNimNode(nnkOfBranch).add(newIntLitNode(i))
let branchBody = newStmtList()
var invocation = newNimNode(nnkCall)
let invocation = newNimNode(nnkCall)
invocation.add(procIdent)
invocation.add(objIdent) # self
for idx in 0..<i:
@ -267,21 +230,13 @@ 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(
resultVariant, ident("godotVariant")))
branchBody.add(getAst(initGodotVariantCall(ident("result"), theCall)))
branchBody.add(newNimNode(nnkAsgn).add(ident("result"),
newCall("toGodot", invocation)))
else:
branchBody.add(invocation)
branchBody.add(getAst(initGodotVariantCall(ident("result"))))
branchBody.add(newNimNode(nnkAsgn).add(ident("result"),
newCall("variant")))
branch.add(branchBody)
result.add(branch)
@ -292,106 +247,69 @@ macro invokeVarArgs(procIdent, objIdent;
" arguments, but got " & $numArgs)
result.add(newNimNode(nnkElse).add(getAst(
printInvokeErr(procIdent.strVal, minArgs, maxArgs, numArgsIdent))))
printInvokeErr($procIdent.ident, minArgs, maxArgs, numArgsIdent))))
proc typeError(nimType: string, value: string, godotType: VariantType,
proc typeError(nimType: cstring, 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: string, value: string, className: cstring,
proc rangeError(nimType: cstring, 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
proc nimDestroyFunc(obj: ptr GodotObject, methData: pointer,
userData: pointer) {.noconv.} =
let nimObj = cast[NimGodotObject](userData)
let nimObj = cast[ref NimGodotObject](userData)
nimObj.removeGodotObject()
GC_unref(nimObj)
proc nimDestroyRefFunc(obj: ptr GodotObject, methData: pointer,
userData: pointer) {.noconv.} =
# references are destroyed by Godot when they are already destroyed by Nim,
# so nothing to do here.
discard
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: 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; isRefClass: bool;
baseNameLit, createFuncIdent; isTool: bool) =
template registerGodotClass(classNameIdent, classNameLit,
baseNameLit, createFuncIdent) =
proc createFuncIdent(obj: ptr GodotObject,
methData: pointer): pointer {.noconv.} =
var nimObj: classNameIdent
new(nimObj, nimGodotObjectFinalizer[classNameIdent])
nimObj.setGodotObject(obj)
nimObj.isRef = when isRefClass: true else: false
nimObj.setNativeObject(asNimGodotObject[NimGodotObject](
obj, forceNativeObject = true))
let nimObj = new(classNameIdent)
setGodotObject(nimObj, obj)
GC_ref(nimObj)
result = cast[pointer](nimObj)
when compiles(nimObj.init()):
nimObj.init()
let createFuncObj = GodotInstanceCreateFunc(
createFunc: createFuncIdent
)
let destroyFuncObj = GodotInstanceDestroyFunc(
destroyFunc: when isRefClass: nimDestroyRefFunc else: nimDestroyFunc
destroyFunc: nimDestroyFunc
)
registerClass(classNameIdent, classNameLit, false)
when isTool:
nativeScriptRegisterToolClass(getNativeLibHandle(), classNameLit,
baseNameLit, createFuncObj, destroyFuncObj)
else:
nativeScriptRegisterClass(getNativeLibHandle(), classNameLit,
baseNameLit, createFuncObj, destroyFuncObj)
godotScriptRegisterClass(classNameLit, baseNameLit,
createFuncObj, destroyFuncObj)
template registerGodotField(classNameLit, classNameIdent, propNameLit,
propNameIdent, propTypeLit, propTypeIdent,
setFuncIdent, getFuncIdent, hintStrLit,
hintIdent, usageExpr, hasDefaultValue,
setFuncIdent, getFuncIdent, hintTipLit,
hintIdent, usageIdent, hasDefaultValue,
defaultValueNode) =
proc setFuncIdent(obj: ptr GodotObject, methData: pointer,
nimPtr: pointer, val: GodotVariant) {.noconv.} =
let variant = newVariant(val)
variant.markNoDeinit()
let (nimVal, err) = godotToNim[propTypeIdent](variant)
nimPtr: pointer, val: Variant) {.noconv.} =
let (nimVal, err) = godotToNim[propTypeIdent](val)
case err:
of ConversionResult.OK:
cast[classNameIdent](nimPtr).propNameIdent = nimVal
of ConversionResult.TypeError:
let errStr = typeError(propTypeLit, $val, val.getType(),
classNameLit, astToStr(propNameIdent))
classNameLit, propNameLit)
printError(errStr)
of ConversionResult.RangeError:
let errStr = rangeError(propTypeLit, $val,
classNameLit, astToStr(propNameIdent))
classNameLit, propNameLit)
printError(errStr)
proc getFuncIdent(obj: ptr GodotObject, methData: pointer,
nimPtr: pointer): GodotVariant {.noconv.} =
let variant = nimToGodot(cast[classNameIdent](nimPtr).propNameIdent)
variant.markNoDeinit()
result = variant.godotVariant[]
nimPtr: pointer): Variant {.noconv.} =
result = nimToGodot(cast[classNameIdent](nimPtr).propNameIdent)
let setFunc = GodotPropertySetFunc(
setFunc: setFuncIdent
@ -399,35 +317,18 @@ 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(variantType),
hint: hint,
hintString: hintStrGodot,
usage: usageExpr
typ: ord(godotVariantType(propTypeIdent)),
hintString: hintTipLit.toGodotString(),
hint: GodotPropertyHint.hintIdent,
usage: GodotPropertyUsageFlags.usageIdent
)
{.push warning[ProveInit]: on.}
when hasDefaultValue:
attr.defaultValue = (defaultValueNode).toVariant().godotVariant[]
nativeScriptRegisterProperty(getNativeLibHandle(), classNameLit, propNameLit,
unsafeAddr attr, setFunc, getFunc)
hintStrGodot.deinit()
attr.defaultValue = (defaultValueNode).toGodot()
godotScriptRegisterProperty(classNameLit, propNameLit,
attr, setFunc, getFunc)
static:
import strutils
proc toGodotStyle(s: string): string {.compileTime.} =
result = newStringOfCap(s.len + 10)
for c in s:
@ -440,7 +341,7 @@ proc toGodotStyle(s: string): string {.compileTime.} =
proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
result = newNimNode(nnkStmtList)
# Nim type definition
# 1. Nim type definition
let typeDef = newNimNode(nnkTypeDef)
result.add(newNimNode(nnkTypeSection).add(typeDef))
typeDef.add(postfix(ident(obj.name), "*"))
@ -448,50 +349,25 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let objTy = newNimNode(nnkObjectTy)
typeDef.add(newNimNode(nnkRefTy).add(objTy))
objTy.add(newEmptyNode())
if obj.parentName.len == 0:
if obj.parentName.isNil:
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:
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))
parseError(decl.defaultValue,
"Default values are not supported for fields for now.")
recList.add(newIdentDefs(decl.name, decl.typ))
# 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
# 2. {.this: self.} for convenience
result.add(newNimNode(nnkPragma).add(newNimNode(nnkExprColonExpr).add(
ident("this"), ident("self")
)))
# Nim proc defintions
# 3. Nim proc defintions
var decls = newSeqOfCap[NimNode](obj.methods.len)
for meth in obj.methods:
let selfArg = newIdentDefs(ident("self"), ident(obj.name))
@ -508,91 +384,64 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
for meth in obj.methods:
result.add(meth.nimNode)
# Register Godot object
let parentName = if obj.parentName.len == 0: newStrLitNode("Object")
# 4. Register Godot object
let parentName = if obj.parentName.isNil: newNilLit()
else: newStrLitNode(obj.parentName)
let classNameLit = newStrLitNode(obj.name)
let classNameLit = newCStringLit(obj.name)
let classNameIdent = ident(obj.name)
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, newLit(isRef), parentName,
genSym(nskProc, "createFunc"), newLit(obj.isTool))))
registerGodotClass(classNameIdent, classNameLit, parentName,
genSym(nskProc, "createFunc"))))
# Register fields (properties)
# 5. Register fields (properties)
for field in obj.fields:
if field.isNoGodot: continue
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))
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"
else: field.usage
let hasDefaultValue = not field.defaultValue.isNil and
field.defaultValue.kind != nnkEmpty
let hintIdent = ident(hint)
let nimType = repr field.typ
let usageIdent = ident(usage)
result.add(getAst(
registerGodotField(classNameLit, classNameIdent,
newCStringLit(toGodotStyle($field.name.basename())),
ident(field.name), nimType,
newCStringLit($field.name.basename()),
ident(field.name), newCStringLit($field.typ),
field.typ, genSym(nskProc, "setFunc"),
genSym(nskProc, "getFunc"),
newStrLitNode(hintStr), hintIdent, usage,
newStrLitNode(hintTip), hintIdent, usageIdent,
ident($hasDefaultValue), field.defaultValue)))
# Register methods
# 6. 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)
args: var ptr array[MAX_ARG_COUNT, Variant]):
Variant {.noconv.} =
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, isStaticCall)
args, argTypes, hasReturnValue)
else:
try:
invokeVarArgs(methodNameIdent, self, minArgs, maxArgs, numArgs,
args, argTypes, hasReturnValue, isStaticCall)
args, argTypes, hasReturnValue)
except:
let ex = getCurrentException()
printError("Unhandled Nim exception (" & $ex.name & "): " &
printError("Unhandled Nim exception (" &
$ex.name & "): " &
ex.msg & "\n" & ex.getStackTrace())
let meth = GodotInstanceMethod(
meth: methFuncIdent
)
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit,
methodNameLit, GodotMethodAttributes(), meth)
godotScriptRegisterMethod(classNameLit, methodNameLit,
GodotMethodAttributes(), meth)
for meth in obj.methods:
if meth.isNoGodot: continue
@ -609,8 +458,7 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom);
else: toGodotStyle(meth.name)
let hasReturnValueBool = not (meth.returnType.isNil or
meth.returnType.kind == nnkEmpty or
(meth.returnType.kind == nnkIdent and
meth.returnType.strVal == "void"))
$meth.returnType == "void")
let hasReturnValue = if hasReturnValueBool: ident("true")
else: ident("false")
result.add(getAst(
@ -619,66 +467,6 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom);
argTypes, genSym(nskProc, "methFunc"),
hasReturnValue)))
if isRef:
# add ref/unref for types inherited from Reference
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*(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)
macro gdobj*(definition: untyped, body: untyped): typed =
let typeDef = parseType(definition, callsite())
result = genType(typeDef)

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,5 +0,0 @@
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>
"""

14
godot/nimruntime.nim Normal file
View file

@ -0,0 +1,14 @@
# Copyright 2017 Xored Software, Inc.
import asyncdispatch
import godot, node
gdobj NimRuntime of Node:
method process*(delta: float32) =
if asyncdispatch.hasPendingOperations():
poll(0)
GC_step(2000, false, 0)
when not defined(release):
onUnhandledException = proc(errorMsg: string) =
printError("Unhandled Nim exception: " & errorMsg)