Compare commits

..

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

43 changed files with 2163 additions and 6556 deletions

View file

@ -27,7 +27,7 @@ addons:
- libxrandr-dev - libxrandr-dev
before_install: before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then rvm --default use 2.3; brew update; brew install scons ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install scons ; fi
install: install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export GODOT_PLATFORM=osx; else export GODOT_PLATFORM=x11; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export GODOT_PLATFORM=osx; else export GODOT_PLATFORM=x11; fi
@ -49,5 +49,6 @@ script:
- set -e - set -e
- mkdir godotapi - mkdir godotapi
- nim c -d:release -r godot/godotapigen.nim "$GODOT_BIN" godotapi - nim c -d:release -r godot/godotapigen.nim "$GODOT_BIN" godotapi
- nim c -d:useRealtimeGc --path:godot -c godotapi/godotall.nim - nimble install -y
- nim c -d:useRealtimeGc -c godotapi/godotall.nim
- nim c -d:release -r docs/docpublish.nim - nim c -d:release -r docs/docpublish.nim

View file

@ -9,7 +9,7 @@
"godot/godotapigen.nim"], "godot/godotapigen.nim"],
"nim.buildOnSave": false, "nim.buildOnSave": false,
"nim.lintOnSave": true, "nim.lintOnSave": true,
"nim.licenseString": "# Copyright 2018 Xored Software, Inc.\n\n", "nim.licenseString": "# Copyright 2017 Xored Software, Inc.\n\n",
"files.exclude": { "files.exclude": {
"**/nimcache/**": true "**/nimcache/**": true
} }

View file

@ -2,7 +2,7 @@ godot-nim - Nim bindings for Godot Engine
The MIT License 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 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, associated documentation files (the "Software"), to deal in the Software without restriction,

View file

@ -1,6 +1,6 @@
# Nim bindings for Godot Engine # Nim bindings for Godot Engine [![Build Status](https://travis-ci.org/pragmagic/godot-nim.svg?branch=master)](https://travis-ci.org/pragmagic/godot-nim)
Nim bindings for Godot 3 based on [GDNative](https://godotengine.org/article/dlscript-here). Nim bindings for Godot 3.0 based on [GDNative](https://godotengine.org/article/dlscript-here).
Documentation: https://pragmagic.github.io/godot-nim/ Documentation: https://pragmagic.github.io/godot-nim/
@ -13,4 +13,4 @@ Documentation: https://pragmagic.github.io/godot-nim/
This project is licensed under the MIT license. Read [LICENSE](LICENSE) file for details. This project is licensed under the MIT license. Read [LICENSE](LICENSE) file for details.
Copyright (c) 2018 Xored Software, Inc. Copyright (c) 2017 Xored Software, Inc.

View file

@ -1,4 +1,4 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import threadpool, os, osproc, strutils, sequtils, pegs import threadpool, os, osproc, strutils, sequtils, pegs
@ -71,7 +71,7 @@ proc fixupHrefs(file: string) =
proc getGitHash(): string = proc getGitHash(): string =
result = execProcess("git rev-parse HEAD") result = execProcess("git rev-parse HEAD")
if result.len > 0: if not result.isNil and result.len > 0:
result = result.replace("\L", "").replace("\r", "") result = result.replace("\L", "").replace("\r", "")
proc buildDocs*(outDir, godotNimDir, godotBin: string) = proc buildDocs*(outDir, godotNimDir, godotBin: string) =
@ -94,8 +94,7 @@ proc buildDocs*(outDir, godotNimDir, godotBin: string) =
allNimFiles.add(file) allNimFiles.add(file)
for file in allNimFiles: for file in allNimFiles:
spawn execOrFail( spawn execOrFail(
"nim doc -d:useRealtimeGc --path:godot -o:" & "nim doc -o:" & quoted(outName(outDirAbs, file)) &
quoted(outName(outDirAbs, file)) &
" --git.url:" & quoted(gitHubUrl) & " --git.url:" & quoted(gitHubUrl) &
" --git.commit:" & quoted(gitCommit) & " --git.commit:" & quoted(gitCommit) &
' ' & quoted(file)) ' ' & quoted(file))
@ -104,15 +103,14 @@ proc buildDocs*(outDir, godotNimDir, godotBin: string) =
createDir(godotApiFolder) createDir(godotApiFolder)
genApiFiles(godotApiFolder, godotBinAbs) genApiFiles(godotApiFolder, godotBinAbs)
for file in walkDirRec(godotApiFolder, {pcFile, pcDir}, [".nim"]): for file in walkDirRec(godotApiFolder, {pcFile, pcDir}, [".nim"]):
spawn execOrFail("nim doc -d:useRealtimeGc --path:godot -o:" & spawn execOrFail("nim doc " & quoted(file))
quoted(outName(godotApiFolder, file)) & ' ' & quoted(file))
sync() sync()
var gitHash: string var gitHash: string
withDir(godotBinAbs.parentDir()): withDir(godotBinAbs.parentDir()):
gitHash = getGitHash() gitHash = getGitHash()
if gitHash.len == 0: if gitHash.isNil or gitHash.len == 0:
raise newException(Exception, raise newException(Exception,
"Godot executable is not under Git repository") "Godot executable is not under Git repository")

View file

@ -1,4 +1,4 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import os, pegs, strutils import os, pegs, strutils
import docbuild import docbuild

View file

@ -5,7 +5,6 @@ Nim bindings for Godot Engine
:Author: Ruslan Mustakov :Author: Ruslan Mustakov
:Version: |godotnimversion| :Version: |godotnimversion|
:GitHub: `$GODOTNIM_GITHUB_URL <$GODOTNIM_GITHUB_URL>`_ :GitHub: `$GODOTNIM_GITHUB_URL <$GODOTNIM_GITHUB_URL>`_
:License: MIT
.. contents:: .. contents::
@ -33,16 +32,30 @@ which adds features for editing GDScript and Godot resource files.
Getting Started Getting Started
=============== ===============
Getting Godot Building Godot
-------------- --------------
The library requires Godot version 3.0, which you can get here: The library requires a not yet released Godot version 3.0, which you can
https://godotengine.org/download build yourself by running the commands below (requires
`Git <https://git-scm.com/downloads>`_,
`Python 2.7 <https://www.python.org/downloads/>`_,
`SCons <http://www.scons.org/>`_):
.. code-block:: bash
git clone https://github.com/godotengine/godot.git
cd godot
scons platform=<your_platform>
where ``<your_platform>`` can be ``windows``, ``osx``, ``x11``. After build
is finished, Godot binaries will be under the ``bin`` folder. More details
about compiling Godot can be found in `Godot documentation
<https://godot.readthedocs.io/en/stable/development/compiling/index.html>`_.
Installing Nim Installing Nim
------------- -------------
The library requires Nim version 0.18.0 or newer, which you can get here: The library requires Nim version 0.17.2 or newer, which you can get here:
https://nim-lang.org/install.html https://nim-lang.org/install.html
Make sure you also have ``nimble`` (Nim's package manager) installed. Make sure you also have ``nimble`` (Nim's package manager) installed.
@ -50,7 +63,7 @@ Make sure you also have ``nimble`` (Nim's package manager) installed.
Creating Project Creating Project
---------------- ----------------
The fastest way to set up a Godot-Nim project is to use the existing stub: The fastest way to set up a Godot-Nim project is to use an existing stub:
.. code-block:: bash .. code-block:: bash
git clone --depth=1 https://github.com/pragmagic/godot-nim-stub.git myproject git clone --depth=1 https://github.com/pragmagic/godot-nim-stub.git myproject
@ -75,7 +88,7 @@ If you would like to use Nim in an existing project:
build scripts (``nakefile.nim``, ``src/stub.nimble``) according to your build scripts (``nakefile.nim``, ``src/stub.nimble``) according to your
own project structure. own project structure.
2. Copy ``nimlib.gdnlib`` to your Godot project folder. It is a 2. Copy ``project/nimlib.tres`` to your Godot project folder. It is a
GDNative library resource that contains paths to dynamic libraries GDNative library resource that contains paths to dynamic libraries
compiled by Nim. compiled by Nim.
@ -139,7 +152,7 @@ exported and you don't have to import any of them directly.
* `quats <quats.html>`_ Defines ``Quat`` (quaternion) describing object * `quats <quats.html>`_ Defines ``Quat`` (quaternion) describing object
rotation in 3D space. rotation in 3D space.
* `rect2 <rect2.html>`_ Defines ``Rect2`` - a 2D rectangle. * `rect2 <rect2.html>`_ Defines ``Rect2`` - a 2D rectangle.
* `aabb <aabb.html>`_ Defines ``AABB`` - a 3D box. * `rect3 <rect3.html>`_ Defines ``Rect3`` - a 3D box.
* `rids <rids.html>`_ Defines ``RID`` - a resource identifier. * `rids <rids.html>`_ Defines ``RID`` - a resource identifier.
* `transform2d <transform2d.html>`_ Defines ``Transform2D``. * `transform2d <transform2d.html>`_ Defines ``Transform2D``.
* `transforms <transforms.html>`_ Defines ``Transform``. * `transforms <transforms.html>`_ Defines ``Transform``.

View file

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

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,7 +1,7 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import hashes import hashes
import internal/godotinternaltypes, internal/godotarrays import internal.godotarrays
type type
Array* = ref object Array* = ref object
@ -62,16 +62,16 @@ proc newArray*(pba: PoolByteArray): Array {.inline.} =
new(result, arrayFinalizer) new(result, arrayFinalizer)
initGodotArray(result.godotArray, pba.godotPoolByteArray[]) initGodotArray(result.godotArray, pba.godotPoolByteArray[])
proc `[]=`*(self: Array; idx: int; value: Variant) {.inline.} = proc `[]=`*(self: var Array; idx: int; value: Variant) {.inline.} =
self.godotArray[idx.cint] = value.godotVariant[] self.godotArray[idx.cint] = value.godotVariant[]
proc `[]`*(self: Array; idx: int): Variant {.inline.} = proc `[]`*(self: Array; idx: int): Variant {.inline.} =
newVariant(self.godotArray[idx.cint]) newVariant(self.godotArray[idx.cint])
proc add*(self: Array; value: Variant) {.inline.} = proc add*(self: var Array; value: Variant) {.inline.} =
self.godotArray.add(value.godotVariant[]) self.godotArray.add(value.godotVariant[])
proc clear*(self: Array) {.inline.} = proc clear*(self: var Array) {.inline.} =
self.godotArray.clear() self.godotArray.clear()
proc count*(self: Array; value: Variant): int {.inline.} = proc count*(self: Array; value: Variant): int {.inline.} =
@ -80,7 +80,7 @@ proc count*(self: Array; value: Variant): int {.inline.} =
proc isEmpty*(self: Array): bool {.inline.} = proc isEmpty*(self: Array): bool {.inline.} =
self.godotArray.isEmpty() self.godotArray.isEmpty()
proc erase*(self: Array; value: Variant) {.inline.} = proc erase*(self: var Array; value: Variant) {.inline.} =
self.godotArray.erase(value.godotVariant[]) self.godotArray.erase(value.godotVariant[])
proc first*(self: Array): Variant {.inline.} = proc first*(self: Array): Variant {.inline.} =
@ -101,37 +101,37 @@ proc contains*(self: Array; value: Variant): bool {.inline.} =
proc hash*(self: Array): Hash {.inline.} = proc hash*(self: Array): Hash {.inline.} =
hash(self.godotArray.godotHash()) hash(self.godotArray.godotHash())
proc insert*(self: Array; pos: int; value: Variant) {.inline.} = proc insert*(self: var Array; pos: int; value: Variant) {.inline.} =
self.godotArray.insert(pos.cint, value.godotVariant[]) self.godotArray.insert(pos.cint, value.godotVariant[])
proc reverse*(self: Array) {.inline.} = proc reverse*(self: var Array) {.inline.} =
self.godotArray.reverse() self.godotArray.reverse()
proc popLast*(self: Array): Variant {.inline.} = proc popLast*(self: var Array): Variant {.inline.} =
newVariant(self.godotArray.popLast()) newVariant(self.godotArray.popLast())
proc popFirst*(self: Array): Variant {.inline.} = proc popFirst*(self: var Array): Variant {.inline.} =
newVariant(self.godotArray.popFirst()) newVariant(self.godotArray.popFirst())
proc addLast*(self: Array; value: Variant) {.inline.} = proc addLast*(self: var Array; value: Variant) {.inline.} =
self.godotArray.addLast(value.godotVariant[]) self.godotArray.addLast(value.godotVariant[])
proc addFirst*(self: Array; value: Variant) {.inline.} = proc addFirst*(self: var Array; value: Variant) {.inline.} =
self.godotArray.addFirst(value.godotVariant[]) self.godotArray.addFirst(value.godotVariant[])
proc delete*(self: Array; idx: int) {.inline.} = proc delete*(self: var Array; idx: int) {.inline.} =
self.godotArray.delete(idx.cint) self.godotArray.delete(idx.cint)
proc setLen*(self: Array; size: int) {.inline.} = proc setLen*(self: var Array; size: int) {.inline.} =
self.godotArray.setLen(size.cint) self.godotArray.setLen(size.cint)
proc rfind*(self: Array; what: Variant; fromIdx: int): int {.inline.} = proc rfind*(self: Array; what: Variant; f: int): int {.inline.} =
self.godotArray.rfind(what.godotVariant[], fromIdx.cint).int self.godotArray.rfind(what.godotVariant[], f.cint).int
proc len*(self: Array): int {.inline.} = proc len*(self: Array): int {.inline.} =
self.godotArray.len.int self.godotArray.len.int
proc sort*(self: Array) {.inline.} = proc sort*(self: var Array) {.inline.} =
self.godotArray.sort() self.godotArray.sort()
iterator items*(self: Array): Variant = iterator items*(self: Array): Variant =

View file

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

View file

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

View file

@ -1,8 +1,8 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import hashes import hashes
import internal/godotinternaltypes, internal/godotdictionaries, import internal.godotstrings, internal.godotdictionaries,
internal/godotvariants, internal/godotstrings internal.godotvariants
type type
Dictionary* = ref object Dictionary* = ref object
@ -30,12 +30,9 @@ proc len*(self: Dictionary): int {.inline.} =
proc isEmpty*(self: Dictionary): bool {.inline.} = proc isEmpty*(self: Dictionary): bool {.inline.} =
self.godotDictionary.isEmpty() self.godotDictionary.isEmpty()
proc clear*(self: Dictionary) {.inline.} = proc clear*(self: var Dictionary) {.inline.} =
self.godotDictionary.clear() self.godotDictionary.clear()
proc hash*(self: Dictionary): Hash {.inline.} =
hash(self.godotDictionary.godotHash())
import variants, arrays import variants, arrays
proc newVariant*(dict: Dictionary): Variant {.inline.} = proc newVariant*(dict: Dictionary): Variant {.inline.} =
@ -43,7 +40,7 @@ proc newVariant*(dict: Dictionary): Variant {.inline.} =
initGodotVariant(result.godotVariant[], dict.godotDictionary) initGodotVariant(result.godotVariant[], dict.godotDictionary)
proc asDictionary*(self: Variant): Dictionary {.inline.} = proc asDictionary*(self: Variant): Dictionary {.inline.} =
newDictionary(self.godotVariant[].asGodotDictionary()) newDictionary(self.godotVariant[].asGodotDictionary)
proc contains*(self: Dictionary; key: Variant): bool {.inline.}= proc contains*(self: Dictionary; key: Variant): bool {.inline.}=
self.godotDictionary.contains(key.godotVariant[]) self.godotDictionary.contains(key.godotVariant[])
@ -51,9 +48,12 @@ proc contains*(self: Dictionary; key: Variant): bool {.inline.}=
proc contains*(self: Dictionary; keys: Array): bool {.inline.} = proc contains*(self: Dictionary; keys: Array): bool {.inline.} =
self.godotDictionary.contains(keys.godotArray[]) self.godotDictionary.contains(keys.godotArray[])
proc del*(self: Dictionary; key: Variant) {.inline.} = proc del*(self: var Dictionary; key: Variant) {.inline.} =
self.godotDictionary.del(key.godotVariant[]) self.godotDictionary.del(key.godotVariant[])
proc hash*(self: Dictionary): Hash {.inline.} =
hash(self.godotDictionary.godotHash())
proc keys*(self: Dictionary): Array {.inline.} = proc keys*(self: Dictionary): Array {.inline.} =
newArray(self.godotDictionary.keys()) newArray(self.godotDictionary.keys())
@ -71,7 +71,7 @@ proc `[]`*(self: Dictionary; keyStr: string): Variant {.inline.} =
godotStr.deinit() godotStr.deinit()
godotVariant.deinit() godotVariant.deinit()
proc `[]=`*(self: Dictionary; key, value: Variant) {.inline.} = proc `[]=`*(self: var Dictionary; key, value: Variant) {.inline.} =
self.godotDictionary[key.godotVariant[]] = value.godotVariant[] self.godotDictionary[key.godotVariant[]] = value.godotVariant[]
proc `==`*(self, other: Dictionary): bool {.inline.} = proc `==`*(self, other: Dictionary): bool {.inline.} =

View file

@ -1,64 +1,85 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import math, godotinternal import math
type
Error* {.size: sizeof(cint), pure.} = enum
OK,
Failed, ## Generic fail error
Unavailable, ## What is requested is unsupported/unavailable
Unconfigured, ## The object being used hasnt been properly set up yet
Unauthorized, ## Missing credentials for requested resource
ParameterRangeError, ## Parameter given out of range (5)
OutOfMemory, ## Out of memory
FileNotFound,
FileBadDrive,
FileBadPath,
FileNoPermission, ## (10)
FileAlreadyInUse,
FileCantOpen,
FileCantWrite,
FileCantRead,
FileUnrecognized, ## (15)
FileCorrupt,
FileMissingDependencies,
FileEOF,
CantOpen, ## Can't open a resource/socket/file
CantCreate, ## (20)
QueryFailed,
AlreadyInUse,
Locked, ## resource is locked
Timeout,
CantConnect, ## (25)
CantResolve,
ConnectionError,
CantAquireResource,
CantFork,
InvalidData, ## Data passed is invalid (30)
InvalidParameter, ## Parameter passed is invalid
AlreadyExists, ## When adding, item already exists
DoesNotExist, ## When retrieving/erasing, it item does not exist
DatabaseCantRead, ## Database is full
DatabaseCantWrite, ## Database is full (35)
CompilationFailed,
MethodNotFound,
LinkFailed,
ScriptFailed,
CyclicLink, ## (40)
InvalidDeclaration,
DuplicateSymbol,
PauseError,
Busy,
Skip, ## (45)
Help, ## user requested help!!
Bug,
## a bug in the software certainly happened, due to a double
## check failing or unexpected behavior.
PrinterOnFire, ## the parallel port printer is engulfed in flames
WTF ## shit happens, has never been used, though
# math helpers # math helpers
{.push stackTrace: off.}
const EPSILON = 0.00001'f32 const EPSILON = 0.00001'f32
proc isEqualApprox*(a, b: float32): bool {.inline, noinit.} = proc isEqualApprox*(a, b: float32): bool {.inline.} =
abs(a - b) < EPSILON abs(a - b) < EPSILON
proc isEqualApprox*(a, b: float64): bool {.inline, noinit.} = proc isEqualApprox*(a, b: float64): bool {.inline.} =
abs(a - b) < EPSILON abs(a - b) < EPSILON
proc sign*(a: float32): float32 {.inline, noinit.} = proc sign*(a: float32): float32 {.inline.} =
if a < 0: -1.0'f32 else: 1.0'f32 if a < 0: -1.0'f32 else: 1.0'f32
proc sign*(a: float64): float64 {.inline, noinit.} = proc sign*(a: float64): float64 {.inline.} =
if a < 0: -1.0'f64 else: 1.0'f64 if a < 0: -1.0'f64 else: 1.0'f64
proc stepify*(value, step: float64): float64 {.inline, noinit.} = proc stepify*(value, step: float64): float64 =
if step != 0'f64: if step != 0'f64:
floor(value / step + 0.5'f64) * step floor(value / step + 0.5'f64) * step
else: else:
value value
proc stepify*(value, step: float32): float32 {.inline, noinit.} = proc stepify*(value, step: float32): float32 =
if step != 0'f32: if step != 0'f32:
floor(value / step + 0.5'f32) * step floor(value / step + 0.5'f32) * step
else: else:
value value
when (NimMajor, NimMinor, NimPatch) < (0, 20, 4):
# Newer Nim has these procs in system module
proc min*(x, y: float32): float32 {.inline, noinit.} =
if x <= y: x else: y
proc abs*(x: float32): float32 {.inline, noinit.} =
if x < 0.0: -x else: x
proc max*(x, y: float32): float32 {.inline, noinit.} =
if y <= x: x else: y
{.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()

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,9 +1,6 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import hashes import internal.godotnodepaths, internal.godotstrings
import internal/godotinternaltypes, internal/godotnodepaths,
internal/godotstrings
type type
NodePath* = ref object NodePath* = ref object
@ -34,9 +31,6 @@ proc `$`*(self: NodePath): string {.inline.} =
result = $s result = $s
s.deinit() s.deinit()
proc hash*(self: NodePath): Hash {.inline.} =
($self).hash()
proc isAbsolute*(self: NodePath): bool {.inline.} = proc isAbsolute*(self: NodePath): bool {.inline.} =
self.path.isAbsolute() self.path.isAbsolute()
@ -56,8 +50,8 @@ proc getSubname*(self: NodePath; idx: int): string {.inline.} =
result = $s result = $s
s.deinit() s.deinit()
proc getConcatenatedSubnames*(self: NodePath): string {.inline.} = proc property*(self: NodePath): string {.inline.} =
var s = self.path.getConcatenatedSubnames() var s = self.path.property()
result = $s result = $s
s.deinit() s.deinit()

View file

@ -1,66 +1,73 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import hashes
import vector3 import vector3
import internal/godotinternaltypes, internal/godotstrings import internal.godotstrings
import godotcoretypes, gdnativeapi
proc initPlane*(a, b, c, d: float32): Plane {.inline.} = type
getGDNativeAPI().planeNewWithReals(result, a, b, c, d) Plane* {.byref.} = object
normal*: Vector3
d*: float32
proc initPlane*(v1, v2, v3: Vector3): Plane {.inline.} = proc initPlane(dest: var Plane; a, b, c, d: float32) {.
getGDNativeAPI().planeNewWithVectors(result, v1, v2, v3) importc: "godot_plane_new_with_reals".}
proc initPlane(dest: var Plane; v1, v2, v3: Vector3) {.
importc: "godot_plane_new_with_vectors".}
proc initPlane(dest: var Plane; normal: Vector3; d: float32) {.
importc: "godot_plane_new_with_normal".}
proc initPlane*(normal: Vector3; d: float32): Plane {.inline.} = proc initPlane*(a, b, c, d: float32): Plane =
result = Plane( initPlane(result, a, b, c, d)
normal: normal,
d: 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".}
proc `$`*(self: Plane): string {.inline.} = proc `$`*(self: Plane): string {.inline.} =
$getGDNativeAPI().planeAsString(self) $self.toGodotString()
proc hash*(self: Plane): Hash {.inline, noinit.} =
!$(self.normal.hash() !& self.d.hash())
proc normalized*(self: Plane): Plane {.inline.} =
getGDNativeAPI().planeNormalized(self).toPlane()
proc center*(self: Plane): Vector3 {.inline.} =
getGDNativeAPI().planeCenter(self).toVector3()
proc getAnyPoint*(self: Plane): Vector3 {.inline.} =
getGDNativeAPI().planeGetAnyPoint(self).toVector3()
proc isPointOver*(self: Plane; point: Vector3): bool {.inline.} =
getGDNativeAPI().planeIsPointOver(self, point)
proc distanceTo*(self: Plane; point: Vector3): float32 {.inline.} =
getGDNativeAPI().planeDistanceTo(self, point)
proc normalized*(self: Plane): Plane {.
noSideEffect,
importc: "godot_plane_normalized".}
proc center*(self: Plane): Vector3 {.
noSideEffect,
importc: "godot_plane_center".}
proc getAnyPoint*(self: Plane): Vector3 {.
noSideEffect,
importc: "godot_plane_get_any_point".}
proc isPointOver*(self: Plane; point: Vector3): bool {.
noSideEffect,
importc: "godot_plane_is_point_over".}
proc distanceTo*(self: Plane; point: Vector3): float32 {.
noSideEffect,
importc: "godot_plane_distance_to".}
proc contains*(self: Plane; point: Vector3; proc contains*(self: Plane; point: Vector3;
epsilon: float32): bool {.inline.} = epsilon: float32): bool {.
getGDNativeAPI().planeHasPoint(self, point, epsilon) noSideEffect,
importc: "godot_plane_has_point".}
proc project*(self: Plane; point: Vector3): Vector3 {.inline.} = proc project*(self: Plane; point: Vector3): Vector3 {.
getGDNativeAPI().planeProject(self, point).toVector3() noSideEffect,
importc: "godot_plane_project".}
proc intersect3*(self: Plane; dest: var Vector3; proc intersect3*(self: Plane; dest: var Vector3;
b, c: Plane): bool {.inline.} = b, c: Plane): bool {.
getGDNativeAPI().planeIntersect3(self, dest, b, c) noSideEffect,
importc: "godot_plane_intersect_3".}
proc intersectsRay*(self: Plane; dest: var Vector3; proc intersectsRay*(self: Plane; dest: var Vector3;
v, dir: Vector3): bool {.inline.} = v, dir: Vector3): bool {.
getGDNativeAPI().planeIntersectsRay(self, dest, v, dir) noSideEffect,
importc: "godot_plane_intersects_ray".}
proc intersectsSegment*(self: Plane; dest: var Vector3; proc intersectsSegment*(self: Plane; dest: var Vector3;
segmentBegin, segmentEnd: Vector3): bool {.inline.} = segmentBegin, segmentEnd: Vector3): bool {.
getGDNativeAPI().planeIntersectsSegment(self, dest, segmentBegin, segmentEnd) noSideEffect, importc: "godot_plane_intersects_segment".}
proc `-`*(self: Plane): Plane {.
proc `-`*(self: Plane): Plane {.inline.} = noSideEffect,
getGDNativeAPI().planeOperatorNeg(self).toPlane() importc: "godot_plane_operator_neg".}
proc `==`*(a, b: Plane): bool {.
proc `==`*(a, b: Plane): bool {.inline.} = noSideEffect,
getGDNativeAPI().planeOperatorEqual(a, b) importc: "godot_plane_operator_equal".}

View file

@ -1,11 +1,7 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import hashes
import godotcoretypes
import internal/godotinternaltypes, internal/godotpoolarrays,
internal/godotstrings
import vector2, vector3, colors import vector2, vector3, colors
import internal.godotpoolarrays, internal.godotstrings
template definePoolArrayBase(T, GodotT, DataT, fieldName, newProcName, template definePoolArrayBase(T, GodotT, DataT, fieldName, newProcName,
initProcName) = initProcName) =
@ -29,11 +25,51 @@ template definePoolArrayBase(T, GodotT, DataT, fieldName, newProcName,
new(result, poolArrayFinalizer) new(result, poolArrayFinalizer)
result.fieldName = arr result.fieldName = arr
proc hash*(arr: T): Hash = template definePoolArray(T, GodotT, DataT, fieldName, newProcName, initProcName;
for item in arr.fieldName.items(): noData = false) =
result = result !&
(when type(item) is GodotString: ($item).hash() else: item.hash()) proc newProcName*(arr: Array): T {.inline.} =
result = !$result new(result, poolArrayFinalizer)
initProcName(result.fieldName, arr.godotArray[])
proc add*(self: var T; arr: T) {.inline.} =
self.fieldName.add(arr.fieldName)
proc delete*(self: var T; idx: int) {.inline.} =
self.fieldName.delete(idx.cint)
proc reverse*(self: var T) {.inline.} =
self.fieldName.reverse()
proc setLen*(self: var T; size: int) {.inline.} =
self.fieldName.setLen(size.cint)
proc len*(self: T): int {.inline.} =
self.fieldName.len.int
when not noData:
proc add*(self: var T; data: DataT) {.inline.} =
self.fieldName.add(data)
proc addFirst*(self: var T, data: DataT) {.inline.} =
self.fieldName.addFirst(data)
proc insert*(self: var T; idx: int; data: DataT): Error {.inline.} =
self.fieldName.insert(idx.cint, data)
proc `[]=`*(self: var T; idx: int; data: DataT) {.inline.} =
self.fieldName[idx.cint] = data
proc `[]`*(self: T; idx: int): DataT {.inline.} =
self.fieldName[idx.cint]
iterator items*(arr: T): DataT =
for i in 0..<arr.len:
yield arr[i]
iterator pairs*(arr: T): tuple[key: int, val: DataT] =
for i in 0..<arr.len:
yield (i, arr[i])
definePoolArrayBase(PoolByteArray, GodotPoolByteArray, uint8, definePoolArrayBase(PoolByteArray, GodotPoolByteArray, uint8,
godotPoolByteArray, newPoolByteArray, godotPoolByteArray, newPoolByteArray,
@ -41,7 +77,7 @@ definePoolArrayBase(PoolByteArray, GodotPoolByteArray, uint8,
definePoolArrayBase(PoolIntArray, GodotPoolIntArray, cint, definePoolArrayBase(PoolIntArray, GodotPoolIntArray, cint,
godotPoolIntArray, newPoolIntArray, godotPoolIntArray, newPoolIntArray,
initGodotPoolIntArray) initGodotPoolIntArray)
definePoolArrayBase(PoolRealArray, GodotPoolRealArray, float32, definePoolArrayBase(PoolRealArray, GodotPoolRealArray, float64,
godotPoolRealArray, newPoolRealArray, godotPoolRealArray, newPoolRealArray,
initGodotPoolRealArray) initGodotPoolRealArray)
definePoolArrayBase(PoolVector2Array, GodotPoolVector2Array, Vector2, definePoolArrayBase(PoolVector2Array, GodotPoolVector2Array, Vector2,
@ -57,64 +93,7 @@ definePoolArrayBase(PoolStringArray, GodotPoolStringArray, string,
godotPoolStringArray, newPoolStringArray, godotPoolStringArray, newPoolStringArray,
initGodotPoolStringArray) initGodotPoolStringArray)
import arrays import godotbase, 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, definePoolArray(PoolByteArray, GodotPoolByteArray, uint8,
godotPoolByteArray, newPoolByteArray, godotPoolByteArray, newPoolByteArray,
@ -122,7 +101,7 @@ definePoolArray(PoolByteArray, GodotPoolByteArray, uint8,
definePoolArray(PoolIntArray, GodotPoolIntArray, cint, definePoolArray(PoolIntArray, GodotPoolIntArray, cint,
godotPoolIntArray, newPoolIntArray, godotPoolIntArray, newPoolIntArray,
initGodotPoolIntArray) initGodotPoolIntArray)
definePoolArray(PoolRealArray, GodotPoolRealArray, float32, definePoolArray(PoolRealArray, GodotPoolRealArray, float64,
godotPoolRealArray, newPoolRealArray, godotPoolRealArray, newPoolRealArray,
initGodotPoolRealArray) initGodotPoolRealArray)
definePoolArray(PoolVector2Array, GodotPoolVector2Array, Vector2, definePoolArray(PoolVector2Array, GodotPoolVector2Array, Vector2,
@ -138,17 +117,22 @@ definePoolArray(PoolStringArray, GodotPoolStringArray, string,
godotPoolStringArray, newPoolStringArray, godotPoolStringArray, newPoolStringArray,
initGodotPoolStringArray, true) initGodotPoolStringArray, true)
proc add*(self: PoolStringArray; data: string) = proc add*(self: var PoolStringArray; data: string) =
var s = data.toGodotString() var s = data.toGodotString()
self.godotPoolStringArray.add(s) self.godotPoolStringArray.add(s)
s.deinit() s.deinit()
proc insert*(self: PoolStringArray; idx: int; data: string): Error = proc addFirst*(self: var PoolStringArray, data: string) =
var s = data.toGodotString()
self.godotPoolStringArray.addFirst(s)
s.deinit()
proc insert*(self: var PoolStringArray; idx: int; data: string): Error =
var s = data.toGodotString() var s = data.toGodotString()
result = self.godotPoolStringArray.insert(idx.cint, s) result = self.godotPoolStringArray.insert(idx.cint, s)
s.deinit() s.deinit()
proc `[]=`*(self: PoolStringArray; idx: int; data: string) = proc `[]=`*(self: var PoolStringArray; idx: int; data: string) =
var s = data.toGodotString() var s = data.toGodotString()
self.godotPoolStringArray[idx.cint] = s self.godotPoolStringArray[idx.cint] = s
s.deinit() s.deinit()

View file

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

View file

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

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

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

View file

@ -1,26 +1,31 @@
# Copyright (c) 2018 Xored Software, Inc. import internal.godotobjects
import hashes type
RID* {.byref.} = object
data: array[sizeof(int), byte]
import godotcoretypes, internal/godotinternaltypes, gdnativeapi proc initRID(dest: var RID) {.
importc: "godot_rid_new".}
proc initRID(dest: var RID; obj: ptr GodotObject) {.
importc: "godot_rid_new_with_resource".}
proc initRID*(): RID {.inline.} = proc initRID*(): RID {.inline.} =
getGDNativeAPI().ridNew(result) initRID(result)
proc initRID*(obj: ptr GodotObject): RID {.inline.} = proc initRID*(obj: ptr GodotObject): RID {.inline.} =
getGDNativeAPI().ridNewWithResource(result, obj) initRID(result, obj)
proc idCInt(self: RID): cint {.
noSideEffect,
importc: "godot_rid_get_id".}
proc id*(self: RID): uint32 {.inline.} = proc id*(self: RID): uint32 {.inline.} =
cast[uint32](getGDNativeAPI().ridGetId(self)) cast[uint32](self.idCInt())
proc `$`*(self: RID): string {.inline.} = proc `$`*(self: RID): string =
$self.id $self.id
proc hash*(self: RID): Hash {.inline.} = proc `==`*(a, b: RID): bool {.
self.id.hash() importc: "godot_rid_operator_equal".}
proc `<`*(a, b: RID): bool {.
proc `==`*(a, b: RID): bool {.inline.} = importc: "godot_rid_operator_less".}
getGDNativeAPI().ridOperatorEqual(a, b)
proc `<`*(a, b: RID): bool {.inline.} =
getGDNativeAPI().ridOperatorLess(a, b)

View file

@ -1,79 +1,76 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import hashes, vector2 import vector2, rect2
import internal/godotinternaltypes, internal/godotstrings import internal.godotstrings
import godotcoretypes, gdnativeapi
type
Transform2D* {.byref.} = object
elements*: array[3, Vector2]
proc initTransform2D(dest: var Transform2D) {.
importc: "godot_transform2d_new_identity".}
proc initTransform2D(dest: var Transform2D; rot: float32; pos: Vector2) {.
importc: "godot_transform2d_new".}
proc initTransform2D(dest: var Transform2D; xAxis, yAxis, origin: Vector2) {.
importc: "godot_transform2d_new_axis_origin".}
proc initTransform2D*(): Transform2D {.inline.} = proc initTransform2D*(): Transform2D {.inline.} =
getGDNativeAPI().transform2DNewIdentity(result) initTransform2D(result)
proc initTransform2D*(rot: float32; pos: Vector2): Transform2D {.inline.} = 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.} = 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".}
proc `$`*(self: Transform2D): string {.inline.} = proc `$`*(self: Transform2D): string {.inline.} =
$getGDNativeAPI().transform2DAsString(self) $self.toGodotString()
proc hash*(self: Transform2D): Hash {.inline, noinit.} = proc inverse*(self: Transform2D): Transform2D {.
!$(self.elements[0].hash() !& self.elements[1].hash() !& self.elements[2].hash()) importc: "godot_transform2d_inverse".}
proc affineInverse*(self: Transform2D): Transform2D {.
proc inverse*(self: Transform2D): Transform2D {.inline.} = importc: "godot_transform2d_affine_inverse".}
getGDNativeAPI().transform2DInverse(self).toTransform2D() proc rotation*(self: Transform2D): float32 {.
importc: "godot_transform2d_get_rotation".}
proc affineInverse*(self: Transform2D): Transform2D {.inline.} = proc origin*(self: Transform2D): Vector2 {.
getGDNativeAPI().transform2DAffineInverse(self).toTransform2D() importc: "godot_transform2d_get_origin".}
proc scale*(self: Transform2D): Vector2 {.
proc rotation*(self: Transform2D): float32 {.inline.} = importc: "godot_transform2d_get_scale".}
getGDNativeAPI().transform2DGetRotation(self) proc orthonormalized*(self: Transform2D): Transform2D {.
importc: "godot_transform2d_orthonormalized".}
proc origin*(self: Transform2D): Vector2 {.inline.} = proc rotated*(self: Transform2D; phi: float32): Transform2D {.
getGDNativeAPI().transform2DGetOrigin(self).toVector2() importc: "godot_transform2d_rotated".}
proc scaled*(self: Transform2D; scale: Vector2): Transform2D {.
proc scale*(self: Transform2D): Vector2 {.inline.} = importc: "godot_transform2d_scaled".}
getGDNativeAPI().transform2DGetScale(self).toVector2() proc translated*(self: Transform2D;
offset: Vector2): Transform2D {.
proc orthonormalized*(self: Transform2D): Transform2D {.inline.} = importc: "godot_transform2d_translated".}
getGDNativeAPI().transform2DOrthonormalized(self).toTransform2D() proc xformVector2*(self: Transform2D; v: Vector2): Vector2 {.
importc: "godot_transform2d_xform_vector2".}
proc rotated*(self: Transform2D; phi: float32): Transform2D {.inline.} = proc xformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.
getGDNativeAPI().transform2DRotated(self, phi).toTransform2D() importc: "godot_transform2d_xform_inv_vector2".}
proc basisXformVector2*(self: Transform2D;
proc scaled*(self: Transform2D; scale: Vector2): Transform2D {.inline.} = v: Vector2): Vector2 {.
getGDNativeAPI().transform2DScaled(self, scale).toTransform2D() importc: "godot_transform2d_basis_xform_vector2".}
proc basisXformInvVector2*(self: Transform2D;
proc translated*(self: Transform2D; offset: Vector2): Transform2D {.inline.} = v: Vector2): Vector2 {.
getGDNativeAPI().transform2DTranslated(self, offset).toTransform2D() importc: "godot_transform2d_basis_xform_inv_vector2".}
proc xformRect2*(self: Transform2D; v: Rect2): Rect2 {.
proc xformVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} = importc: "godot_transform2d_xform_rect2".}
getGDNativeAPI().transform2DXformVector2(self, v).toVector2() proc xformInvRect2*(self: Transform2D; v: Rect2): Rect2 {.
importc: "godot_transform2d_xform_inv_rect2".}
proc xformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} =
getGDNativeAPI().transform2DXformInvVector2(self, v).toVector2()
proc basisXformVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} =
getGDNativeAPI().transform2DBasisXformVector2(self, v).toVector2()
proc basisXformInvVector2*(self: Transform2D; v: Vector2): Vector2 {.inline.} =
getGDNativeAPI().transform2DBasisXformInvVector2(self, v).toVector2()
proc xformRect2*(self: Transform2D; rect: Rect2): Rect2 {.inline.} =
getGDNativeAPI().transform2DXformRect2(self, rect).toRect2()
proc xformInvRect2*(self: Transform2D; rect: Rect2): Rect2 {.inline.} =
getGDNativeAPI().transform2DXformInvRect2(self, rect).toRect2()
proc interpolateWith*(self, m: Transform2D; proc interpolateWith*(self, m: Transform2D;
c: float32): Transform2D {.inline.} = c: float32): Transform2D {.
getGDNativeAPI().transform2DInterpolateWith(self, m, c).toTransform2D() importc: "godot_transform2d_interpolate_with".}
proc `==`*(a, b: Transform2D): bool {.
proc `==`*(a, b: Transform2D): bool {.inline.} = importc: "godot_transform2d_operator_equal".}
getGDNativeAPI().transform2DOperatorEqual(a, b) proc `*`*(a, b: Transform2D): Transform2D {.
importc: "godot_transform2d_operator_multiply".}
proc `*`*(a, b: Transform2D): Transform2D {.inline.} =
getGDNativeAPI().transform2DOperatorMultiply(a, b).toTransform2D()
proc `*=`*(a: var Transform2D, b: Transform2D) {.inline.} = proc `*=`*(a: var Transform2D, b: Transform2D) {.inline.} =
a = a * b a = a * b

View file

@ -1,10 +1,13 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import hashes import basis, vector3, planes, rect3
import internal/godotinternaltypes, internal/godotstrings import internal.godotstrings
import godotcoretypes, gdnativeapi
import basis, vector3 type
Transform* {.byref.} = object
basis*: Basis
origin*: Vector3
proc initTransform*(): Transform {.inline.} = proc initTransform*(): Transform {.inline.} =
result.basis = initBasis() result.basis = initBasis()
@ -20,57 +23,45 @@ proc initTransform*(xAxis, yAxis, zAxis,
proc initTransform*(basis: Basis, origin: Vector3): Transform {.inline.} = proc initTransform*(basis: Basis, origin: Vector3): Transform {.inline.} =
Transform(basis: basis, origin: origin) Transform(basis: basis, origin: origin)
proc toGodotString(self: Transform): GodotString {.
importc: "godot_transform_as_string".}
proc `$`*(self: Transform): string {.inline.} = proc `$`*(self: Transform): string {.inline.} =
$getGDNativeAPI().transformAsString(self) $self.toGodotString()
proc hash*(self: Transform): Hash {.inline.} =
!$(self.basis.hash() !& self.origin.hash())
proc inverse*(self: Transform): Transform {.inline.} =
getGDNativeAPI().transformInverse(self).toTransform()
proc affineInverse*(self: Transform): Transform {.inline.} =
getGDNativeAPI().transformAffineInverse(self).toTransform()
proc orthonormalized*(self: Transform): Transform {.inline.} =
getGDNativeAPI().transformOrthonormalized(self).toTransform()
proc inverse*(self: Transform): Transform {.
importc: "godot_transform_inverse".}
proc affineInverse*(self: Transform): Transform {.
importc: "godot_transform_affine_inverse".}
proc orthonormalized*(self: Transform): Transform {.
importc: "godot_transform_orthonormalized".}
proc rotated*(self: Transform; axis: Vector3; proc rotated*(self: Transform; axis: Vector3;
phi: float32): Transform {.inline.} = phi: float32): Transform {.
getGDNativeAPI().transformRotated(self, axis, phi).toTransform() importc: "godot_transform_rotated".}
proc scaled*(self: Transform; scale: Vector3): Transform {.
importc: "godot_transform_scaled".}
proc translated*(self: Transform; offset: Vector3): Transform {.
importc: "godot_transform_translated".}
proc lookingAt*(self: Transform;
target, up: Vector3): Transform {.
importc: "godot_transform_looking_at".}
proc scaled*(self: Transform; scale: Vector3): Transform {.inline.} = proc xformPlane*(self: Transform; v: Plane): Plane {.
getGDNativeAPI().transformScaled(self, scale).toTransform() importc: "godot_transform_xform_plane".}
proc xformInvPlane*(self: Transform; v: Plane): Plane {.
importc: "godot_transform_xform_inv_plane".}
proc xformVector3*(self: Transform; v: Vector3): Vector3 {.
importc: "godot_transform_xform_vector3".}
proc xformInvVector3*(self: Transform; v: Vector3): Vector3 {.
importc: "godot_transform_xform_inv_vector3".}
proc xformRect3*(self: Transform; v: Rect3): Rect3 {.
importc: "godot_transform_xform_rect3".}
proc xformInvRect3*(self: Transform; v: Rect3): Rect3 {.
importc: "godot_transform_xform_inv_rect3".}
proc translated*(self: Transform; offset: Vector3): Transform {.inline.} = proc `==`*(self: Transform; b: Transform): bool {.
getGDNativeAPI().transformTranslated(self, offset).toTransform() importc: "godot_transform_operator_equal".}
proc `*`*(a, b: Transform): Transform {.
proc lookingAt*(self: Transform; target, up: Vector3): Transform {.inline.} = importc: "godot_transform_operator_multiply".}
getGDNativeAPI().transformLookingAt(self, target, up).toTransform() proc `*=`*(a: var Transform, b: Transform) {.inline.} =
a = a * b
proc xformPlane*(self: Transform; plane: Plane): Plane {.inline.} =
getGDNativeAPI().transformXformPlane(self, plane).toPlane()
proc xformInvPlane*(self: Transform; plane: Plane): Plane {.inline.} =
getGDNativeAPI().transformXformInvPlane(self, plane).toPlane()
proc xformVector3*(self: Transform; v: Vector3): Vector3 {.inline.} =
getGDNativeAPI().transformXformVector3(self, v).toVector3()
proc xformInvVector3*(self: Transform; v: Vector3): Vector3 {.inline.} =
getGDNativeAPI().transformXformInvVector3(self, v).toVector3()
proc xformAABB*(self: Transform; rect: AABB): AABB {.inline.} =
getGDNativeAPI().transformXformAABB(self, rect).toAABB()
proc xformInvAABB*(self: Transform; rect: AABB): AABB {.inline.} =
getGDNativeAPI().transformXformInvAABB(self, rect).toAABB()
proc `==`*(self: Transform; b: Transform): bool {.inline.} =
getGDNativeAPI().transformOperatorEqual(self, b)
proc `*`*(self, other: Transform): Transform {.inline.} =
getGDNativeAPI().transformOperatorMultiply(self, other).toTransform()
proc `*=`*(self: var Transform, other: Transform) {.inline.} =
self = self * other

View file

@ -1,9 +1,7 @@
import tables, hashes import tables
import godotcoretypes import internal.godotobjects, internal.godotvariants, internal.godotpoolarrays,
import internal/godotinternaltypes, internal/godotvariants, internal.godotstrings, internal.godotnodepaths
internal/godotstrings, internal/godotdictionaries,
internal/godotarrays
type type
Variant* = ref object Variant* = ref object
@ -73,16 +71,15 @@ proc newVariant*(r: cdouble): Variant {.inline.} =
proc newVariant*(s: string): Variant {.inline.} = proc newVariant*(s: string): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
if s.isNil: if s.isNil:
initGodotVariant(result.godotVariant) initGodotVariant(result.godotVariant)
return else:
var godotStr = s.toGodotString() var godotStr = s.toGodotString()
initGodotVariant(result.godotVariant, godotStr) initGodotVariant(result.godotVariant, godotStr)
godotStr.deinit() godotStr.deinit()
import basis, nodepaths import basis, nodepaths
import planes, quats, rect2, aabb, rids import planes, quats, rect2, rect3, rids
import transforms, transform2d, vector2 import transforms, transform2d, vector2
import vector3, colors import vector3, colors
@ -110,9 +107,9 @@ proc newVariant*(quat: Quat): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
initGodotVariant(result.godotVariant, quat) initGodotVariant(result.godotVariant, quat)
proc newVariant*(aabb: AABB): Variant {.inline.} = proc newVariant*(rect3: Rect3): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
initGodotVariant(result.godotVariant, aabb) initGodotVariant(result.godotVariant, rect3)
proc newVariant*(basis: Basis): Variant {.inline.} = proc newVariant*(basis: Basis): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
@ -142,7 +139,11 @@ proc newVariant*(obj: ptr GodotObject): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
initGodotVariant(result.godotVariant, obj) initGodotVariant(result.godotVariant, obj)
import poolarrays import arrays, poolarrays
proc newVariant*(arr: Array): Variant {.inline.} =
new(result, variantFinalizer)
initGodotVariant(result.godotVariant, arr.godotArray[])
proc newVariant*(pba: PoolByteArray): Variant {.inline.} = proc newVariant*(pba: PoolByteArray): Variant {.inline.} =
new(result, variantFinalizer) new(result, variantFinalizer)
@ -175,119 +176,81 @@ proc newVariant*(pca: PoolColorArray): Variant {.inline.} =
proc asBool*(self: Variant): bool {.inline.} = proc asBool*(self: Variant): bool {.inline.} =
self.godotVariant.asBool() self.godotVariant.asBool()
proc asUInt*(self: Variant): uint64 {.inline.} = proc asUInt*(self: Variant): uint64 =
self.godotVariant.asUInt() self.godotVariant.asUInt()
proc asInt*(self: Variant): int64 {.inline.} = proc asInt*(self: Variant): int64 =
self.godotVariant.asInt() self.godotVariant.asInt()
proc asReal*(self: Variant): cdouble {.inline.} = proc asReal*(self: Variant): cdouble =
self.godotVariant.asReal() self.godotVariant.asReal()
proc asString*(self: Variant): string {.inline.} = proc asString*(self: Variant): string =
$self $self
proc asVector2*(self: Variant): Vector2 {.inline.} = proc asVector2*(self: Variant): Vector2 =
self.godotVariant.asVector2() self.godotVariant.asVector2()
proc asRect2*(self: Variant): Rect2 {.inline.} = proc asRect2*(self: Variant): Rect2 =
self.godotVariant.asRect2() self.godotVariant.asRect2()
proc asVector3*(self: Variant): Vector3 {.inline.} = proc asVector3*(self: Variant): Vector3 =
self.godotVariant.asVector3() self.godotVariant.asVector3()
proc asTransform2D*(self: Variant): Transform2D {.inline.} = proc asTransform2D*(self: Variant): Transform2D =
self.godotVariant.asTransform2D() self.godotVariant.asTransform2D()
proc asPlane*(self: Variant): Plane {.inline.} = proc asPlane*(self: Variant): Plane =
self.godotVariant.asPlane() self.godotVariant.asPlane()
proc asQuat*(self: Variant): Quat {.inline.} = proc asQuat*(self: Variant): Quat =
self.godotVariant.asQuat() self.godotVariant.asQuat()
proc asAABB*(self: Variant): AABB {.inline.} = proc asRect3*(self: Variant): Rect3 =
self.godotVariant.asAABB() self.godotVariant.asRect3()
proc asBasis*(self: Variant): Basis {.inline.} = proc asBasis*(self: Variant): Basis =
self.godotVariant.asBasis() self.godotVariant.asBasis()
proc asTransform*(self: Variant): Transform {.inline.} = proc asTransform*(self: Variant): Transform =
self.godotVariant.asTransform() self.godotVariant.asTransform()
proc asColor*(self: Variant): Color {.inline.} = proc asColor*(self: Variant): Color =
self.godotVariant.asColor() self.godotVariant.asColor()
proc asNodePath*(self: Variant): NodePath {.inline.} = proc asNodePath*(self: Variant): NodePath =
result = newNodePath(self.godotVariant.asNodePath()) result = newNodePath(self.godotVariant.asNodePath())
proc asRID*(self: Variant): RID {.inline.} = proc asRID*(self: Variant): RID =
self.godotVariant.asRID() self.godotVariant.asRID()
proc asGodotObject*(self: Variant): ptr GodotObject {.inline.} = proc asGodotObject*(self: Variant): ptr GodotObject =
self.godotVariant.asGodotObject() self.godotVariant.asGodotObject()
proc asPoolByteArray*(self: Variant): PoolByteArray {.inline.} = proc asArray*(self: Variant): Array =
newArray(self.godotVariant.asGodotArray())
proc asPoolByteArray*(self: Variant): PoolByteArray =
newPoolByteArray(self.godotVariant.asGodotPoolByteArray()) newPoolByteArray(self.godotVariant.asGodotPoolByteArray())
proc asPoolIntArray*(self: Variant): PoolIntArray {.inline.} = proc asPoolIntArray*(self: Variant): PoolIntArray =
newPoolIntArray(self.godotVariant.asGodotPoolIntArray()) newPoolIntArray(self.godotVariant.asGodotPoolIntArray())
proc asPoolRealArray*(self: Variant): PoolRealArray {.inline.} = proc asPoolRealArray*(self: Variant): PoolRealArray =
newPoolRealArray(self.godotVariant.asGodotPoolRealArray()) newPoolRealArray(self.godotVariant.asGodotPoolRealArray())
proc asPoolStringArray*(self: Variant): PoolStringArray {.inline.} = proc asPoolStringArray*(self: Variant): PoolStringArray =
newPoolStringArray(self.godotVariant.asGodotPoolStringArray()) newPoolStringArray(self.godotVariant.asGodotPoolStringArray())
proc asPoolVector2Array*(self: Variant): PoolVector2Array {.inline.} = proc asPoolVector2Array*(self: Variant): PoolVector2Array =
newPoolVector2Array(self.godotVariant.asGodotPoolVector2Array()) newPoolVector2Array(self.godotVariant.asGodotPoolVector2Array())
proc asPoolVector3Array*(self: Variant): PoolVector3Array {.inline.} = proc asPoolVector3Array*(self: Variant): PoolVector3Array =
newPoolVector3Array(self.godotVariant.asGodotPoolVector3Array()) newPoolVector3Array(self.godotVariant.asGodotPoolVector3Array())
proc asPoolColorArray*(self: Variant): PoolColorArray {.inline.} = proc asPoolColorArray*(self: Variant): PoolColorArray =
newPoolColorArray(self.godotVariant.asGodotPoolColorArray()) 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 = proc hasMethod*(self: Variant; meth: string): bool =
var s = meth.toGodotString() var s = meth.toGodotString()
result = self.godotVariant.hasMethod(s) result = self.godotVariant.hasMethod(s)
@ -304,5 +267,5 @@ proc `<`*(self, other: Variant): bool =
proc hashCompare*(self, other: Variant): bool = proc hashCompare*(self, other: Variant): bool =
self.godotVariant.hashCompare(other.godotVariant) self.godotVariant.hashCompare(other.godotVariant)
proc booleanize*(self: Variant): bool = proc booleanize*(self: Variant; isValid: var bool): bool =
self.godotVariant.booleanize() self.godotVariant.booleanize(isValid)

View file

@ -1,214 +1,109 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import math, godotbase, hashes import internal.godotstrings
import internal/godotinternaltypes, internal/godotstrings type
import godotcoretypes, gdnativeapi Vector2* {.byref.} = object
x*: float32
y*: float32
const EPSILON = 0.00001'f32 proc vec2*(x, y: float32): Vector2 {.inline.} =
{.push stackTrace: off.}
proc vec2*(): Vector2 {.inline, noinit.} =
Vector2()
proc vec2*(x, y: float32): Vector2 {.inline, noinit.} =
Vector2(x: x, y: y) Vector2(x: x, y: y)
proc `$`*(self: Vector2): string {.inline, noinit.} = proc toGodotString(self: Vector2): GodotString {.
$getGDNativeAPI().vector2AsString(self) importc: "godot_vector2_as_string".}
proc hash*(self: Vector2): Hash {.inline, noinit.} = proc `$`*(self: Vector2): string {.inline.} =
!$(self.x.hash() !& self.y.hash()) $self.toGodotString()
proc `+`*(self, other: Vector2): Vector2 {.inline, noinit.} = proc normalized*(self: Vector2): Vector2 {.
Vector2(x: self.x + other.x, y: self.y + other.y) importc: "godot_vector2_normalized".}
proc length*(self: Vector2): float32 {.
importc: "godot_vector2_length".}
proc angle*(self: Vector2): float32 {.
importc: "godot_vector2_angle".}
proc lengthSquared*(self: Vector2): float32 {.
importc: "godot_vector2_length_squared".}
proc isNormalized*(self: Vector2): bool {.
importc: "godot_vector2_is_normalized".}
proc distanceTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_distance_to".}
proc distanceSquaredTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_distance_squared_to".}
proc angleTo*(self, to: Vector2): float32 {.
importc: "godot_vector2_angle_to".}
proc angleToPoint*(self, to: Vector2): float32 {.
importc: "godot_vector2_angle_to_point".}
proc lerp*(self, b: Vector2; t: float32): Vector2 {.
importc: "godot_vector2_linear_interpolate".}
proc cubicInterpolate*(self, b, pre_a, post_b: Vector2; t: float32): Vector2 {.
importc: "godot_vector2_cubic_interpolate".}
proc rotated*(self: Vector2; phi: float32): Vector2 {.
importc: "godot_vector2_rotated".}
proc tangent*(self: Vector2): Vector2 {.
importc: "godot_vector2_tangent".}
proc floor*(self: Vector2): Vector2 {.
importc: "godot_vector2_floor".}
proc snapped*(self: Vector2; by: Vector2): Vector2 {.
importc: "godot_vector2_snapped".}
proc aspect*(self: Vector2): float32 {.
importc: "godot_vector2_aspect".}
proc dot*(a, b: Vector2): float32 {.
importc: "godot_vector2_dot".}
proc slide*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_slide".}
proc bounce*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_bounce".}
proc reflect*(self, n: Vector2): Vector2 {.
importc: "godot_vector2_reflect".}
proc abs*(self: Vector2): Vector2 {.
importc: "godot_vector2_abs".}
proc clamped*(self: Vector2; length: float32): Vector2 {.
importc: "godot_vector2_clamped".}
proc `+=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = proc `+`*(a, b: Vector2): Vector2 {.
self.x += other.x importc: "godot_vector2_operator_add".}
self.y += other.y proc `+=`*(a: var Vector2, b: Vector2) {.inline.} =
a += b
proc `-`*(self, other: Vector2): Vector2 {.inline, noinit.} = proc `-`*(a, b: Vector2): Vector2 {.
Vector2(x: self.x - other.x, y: self.y - other.y) importc: "godot_vector2_operator_substract".}
proc `-=`*(a: var Vector2, b: Vector2) {.inline.} =
a = a - b
proc `-=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = proc `*`*(a, b: Vector2): Vector2 {.
self.x -= other.x importc: "godot_vector2_operator_multiply_vector".}
self.y -= other.y
proc `*`*(self, other: Vector2): Vector2 {.inline, noinit.} = proc `*=`*(a: var Vector2, b: Vector2) {.inline.} =
Vector2(x: self.x * other.x, y: self.y * other.y) a = a * b
proc `*=`*(self: var Vector2, other: Vector2) {.inline, noinit.} = proc `*`*(self: Vector2, scalar: float32): Vector2 {.
self.x *= other.x importc: "godot_vector2_operator_multiply_scalar".}
self.y *= other.y proc `*=`*(self: var Vector2, scalar: float32) {.inline.} =
self = self * scalar
proc `*`*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} = proc `/`*(a, b: Vector2): Vector2 {.
Vector2(x: self.x * scalar, y: self.y * scalar) importc: "godot_vector2_operator_divide_vector".}
proc `/=`*(a: var Vector2, b: Vector2) {.inline.} =
a = a / b
proc `*`*(scalar: float32, v: Vector2): Vector2 {.inline, noinit.} = proc `/`*(self: Vector2; scalar: float32): Vector2 {.
v * scalar importc: "godot_vector2_operator_divide_scalar".}
proc `/=`*(self: var Vector2; scalar: float32) {.inline.} =
proc `*=`*(self: var Vector2, scalar: float32) {.inline, noinit.} =
self.x *= scalar
self.y *= scalar
proc `/`*(self, other: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: self.x / other.x, y: self.y / other.y)
proc `/=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
self.x /= other.x
self.y /= other.y
proc `/`*(self: Vector2; scalar: float32): Vector2 {.inline, noinit.} =
Vector2(x: self.x / scalar, y: self.y / scalar)
proc `/=`*(self: var Vector2; scalar: float32) {.inline, noinit.} =
self = self / scalar self = self / scalar
proc `==`*(self, other: Vector2): bool {.inline, noinit.} = proc `==`*(a, b: Vector2): bool {.
self.x == other.x and self.y == other.y importc: "godot_vector2_operator_equal".}
proc `<`*(a, b: Vector2): bool {.
importc: "godot_vector2_operator_less".}
proc `-`*(self: Vector2): Vector2 {.
importc: "godot_vector2_operator_neg".}
proc `<`*(self, other: Vector2): bool {.inline, noinit.} = proc `x=`*(self: var Vector2; x: float32) {.
if self.x == other.x: importc: "godot_vector2_set_x".}
self.y < other.y proc `y=`*(self: var Vector2; y: float32) {.
else: importc: "godot_vector2_set_y".}
self.x < other.x proc x*(self: Vector2): float32 {.
importc: "godot_vector2_get_x".}
proc `>`*(self, other: Vector2): bool {.inline, noinit.} = proc y*(self: Vector2): float32 {.
if self.x == other.x: importc: "godot_vector2_get_y".}
self.y > other.y
else:
self.x > other.x
proc `-`*(self: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: -self.x, y: -self.y)
proc length*(self: Vector2): float32 {.inline, noinit.} =
sqrt(self.x * self.x + self.y * self.y)
proc lengthSquared*(self: Vector2): float32 {.inline, noinit.} =
self.x * self.x + self.y * self.y
proc normalize*(self: var Vector2) {.inline.} =
var len = self.x * self.x + self.y * self.y
if len != 0:
len = sqrt(len)
self.x /= len
self.y /= len
proc normalized*(self: Vector2): Vector2 {.inline, noinit.} =
result = self
result.normalize()
proc angle*(self: Vector2): float32 {.inline, noinit.} =
arctan2(self.y, self.x)
proc isNormalized*(self: Vector2): bool {.inline, noinit.} =
isEqualApprox(self.lengthSquared(), 1.0)
proc distanceTo*(self, to: Vector2): float32 {.inline, noinit.} =
sqrt((self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y))
proc distanceSquaredTo*(self, to: Vector2): float32 {.inline, noinit.} =
(self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y)
proc dot*(a, b: Vector2): float32 {.inline, noinit.} =
a.x * b.x + a.y * b.y
proc cross*(a, b: Vector2): float32 {.inline, noinit.} =
a.x * b.y - a.y * b.x
proc cross*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} =
Vector2(x: scalar * self.y, y: -scalar * self.x)
proc angleTo*(self, to: Vector2): float32 {.noinit.} =
arctan2(cross(self, to), dot(self, to))
proc angleToPoint*(self, to: Vector2): float32 {.inline, noinit.} =
arctan2(self.y - to.y, self.x - to.x)
proc floor*(self: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: floor(self.x), y: floor(self.y))
proc planeProject*(self: Vector2, d: float32,
vec: Vector2): Vector2 {.noinit.} =
vec - self * (self.dot(vec) - d)
proc project*(self, other: Vector2): Vector2 {.noinit.} =
self * (other.dot(self) / self.dot(self))
proc lerp*(self, b: Vector2; t: float32): Vector2 {.inline, noinit.} =
result = self
result.x += t * (b.x - self.x)
result.y += t * (b.y - self.y)
proc cubicInterpolate*(self, b, preA, postB: Vector2;
t: float32): Vector2 {.noinit.} =
let p0 = preA
let p1 = self
let p2 = b
let p3 = postB
let t2 = t * t
let t3 = t2 * t
result = 0.5'f32 * ((p1 * 2.0'f32)) +
(-p0 + p2) * t +
(2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3
proc setRotation*(self: var Vector2, radians: float32) {.inline, noinit.} =
self.x = cos(radians)
self.y = sin(radians)
proc rotated*(self: Vector2; phi: float32): Vector2 {.inline, noinit.} =
result.setRotation(phi)
result *= self.length()
proc tangent*(self: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: self.y, y: -self.x)
proc snapped*(self: Vector2; by: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: stepify(self.x, by.x), y: stepify(self.y, by.y))
proc aspect*(self: Vector2): float32 {.inline, noinit.} =
self.x / self.y
proc slide*(self, n: Vector2): Vector2 {.noinit.} =
when not defined(release):
if not n.isNormalized():
printError("Normal not normalized in slide. " & getStackTrace())
return vec2()
result = self - n * self.dot(n)
proc reflect*(self, n: Vector2): Vector2 {.noinit.} =
when not defined(release):
if not n.isNormalized():
printError("Normal not normalized in bounce. " & getStackTrace())
return vec2()
result = 2.0 * n * self.dot(n) - self
proc bounce*(self, n: Vector2): Vector2 {.inline, noinit.} =
-self.reflect(n)
proc abs*(self: Vector2): Vector2 {.inline, noinit.} =
Vector2(x: abs(self.x), y: abs(self.y))
proc clamped*(self: Vector2; length: float32): Vector2 {.noinit.} =
let len = self.length()
result = self
if len > 0 and length < len:
result /= len
result *= length
proc moveToward*(vFrom, to: Vector2, delta: float32): Vector2 =
let
vd = to - vFrom
vLen = vd.length
if vLen <= delta or vLen < EPSILON:
result = to
else:
result = vFrom + (vd / vLen) * delta
{.pop.} # stackTrace: off

View file

@ -1,11 +1,13 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import math, hashes import math
import godotbase, godotcoretypes import godotbase
const EPSILON = 0.00001'f32 type
Vector3* {.byref.} = object
{.push stackTrace: off.} x*: float32
y*: float32
z*: float32
proc vec3*(): Vector3 {.inline.} = proc vec3*(): Vector3 {.inline.} =
Vector3() Vector3()
@ -23,9 +25,6 @@ proc `$`*(self: Vector3): string {.inline.} =
result.add($self.z) result.add($self.z)
result.add(')') result.add(')')
proc hash*(self: Vector3): Hash {.inline, noinit.} =
!$(self.x.hash() !& self.y.hash() !& self.z.hash())
proc `+`*(a, b: Vector3): Vector3 {.inline.} = proc `+`*(a, b: Vector3): Vector3 {.inline.} =
result.x = a.x + b.x result.x = a.x + b.x
result.y = a.y + b.y result.y = a.y + b.y
@ -240,15 +239,3 @@ proc cubicInterpolate*(self, b, preA, postB: Vector3;
(-p0 + p2) * t + (-p0 + p2) * t +
(2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3) (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3)
proc moveToward*(vFrom, to: Vector3, delta: float32): Vector3 =
let
vd = to - vFrom
vLen = vd.length
if vLen <= delta or vLen < EPSILON:
result = to
else:
result = vFrom + (vd / vLen) * delta
{.pop.} # stackTrace: off

File diff suppressed because it is too large Load diff

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,85 +1,259 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import internal/godotinternaltypes, internal/godotarrays, import internal.godotobjects, internal.godotarrays, internal.godotnodepaths,
internal/godotnodepaths, internal/godotpoolarrays, internal/godotstrings, internal.godotpoolarrays, internal.godotstrings, internal.godotvariants,
internal/godotvariants, internal/godotdictionaries internal.godotdictionaries
import gdnativeapi export godotobjects, godotarrays, godotnodepaths, godotpoolarrays,
export godotinternaltypes, godotarrays, godotnodepaths, godotpoolarrays,
godotstrings, godotvariants, godotdictionaries godotstrings, godotvariants, godotdictionaries
proc getMethod*(className: cstring; const MAX_ARG_COUNT* = 128
methodName: cstring): ptr GodotMethodBind {.inline.} =
getGDNativeAPI().methodBindGetMethod(className, methodName)
# MethodBind API
type GodotMethodBind* = object
proc getMethod*(className: cstring; methodName: cstring): ptr GodotMethodBind {.
importc: "godot_method_bind_get_method".}
proc ptrCall*(methodBind: ptr GodotMethodBind; proc ptrCall*(methodBind: ptr GodotMethodBind;
instance: ptr GodotObject; instance: ptr GodotObject;
args: ptr array[MAX_ARG_COUNT, pointer]; args: ptr array[MAX_ARG_COUNT, pointer];
ret: pointer) {.inline.} = ret: pointer) {.
getGDNativeAPI().methodBindPtrCall(methodBind, instance, args, ret) importc: "godot_method_bind_ptrcall".}
proc call*(methodBind: ptr GodotMethodBind; proc call*(methodBind: ptr GodotMethodBind;
instance: ptr GodotObject; instance: ptr GodotObject;
args: ptr array[MAX_ARG_COUNT, ptr GodotVariant]; argCount: cint; args: ptr array[MAX_ARG_COUNT, ptr GodotVariant]; argCount: cint;
callError: var VariantCallError): GodotVariant {.inline.} = callError: var VariantCallError): GodotVariant {.
getGDNativeAPI().methodBindCall( importc: "godot_method_bind_call".}
methodBind, instance, args, argCount, callError)
proc nativeScriptRegisterClass*(libHandle: pointer; name, base: cstring; # Script API
type
GodotNativeInitOptions* = object
inEditor*: bool
coreApiHash*: uint64
editorApiHash*: uint64
noApiHash*: uint64
gdNativeLibrary*: ptr GodotObject
GodotNativeTerminateOptions* = object
inEditor*: bool
GodotMethodRPCMode* {.size: sizeof(cint), pure.} = enum
Disabled,
Remote,
Sync,
Master,
Slave
GodotMethodAttributes* = object
rpcMode*: GodotMethodRPCMode
GodotPropertyHint* {.size: sizeof(cint), pure.} = enum
None, ## no hint provided.
Range, ## hint_text = "min,max,step,slider; // slider is optional"
ExpRange, ## hint_text = "min,max,step", exponential edit
Enum, ## hint_text= "val1,val2,val3,etc"
ExpEasing, ## exponential easing funciton (Math::ease)
Length, ## hint_text= "length" (as integer)
SpriteFrame,
KeyAccel, ## hint_text= "length" (as integer)
Flags, ## hint_text= "flag1,flag2,etc" (as bit flags)
Layers2DRender,
Layers2DPhysics,
Layers3DRender,
Layers3DPhysics,
File, ## a file path must be passed, hint_text (optionally)
## is a filter "*.png,*.wav,*.doc,"
Dir, ## a directort path must be passed
GlobalFile, ## a file path must be passed, hint_text (optionally) is a
## filter "*.png,*.wav,*.doc,"
GlobalDir, ## a directort path must be passed
ResourceType, ## a resource object type
MultilineText, ## used for string properties that can contain multiple lines
ColorNoAlpha, ## used for ignoring alpha component when editing a color
ImageCompressLossy,
ImageCompressLossless,
ObjectId,
TypeString, ## a type string, the hint is the base type to choose
NodePathToEditedNode, ## so something else can provide this
## (used in scripts)
MethodOfVariantType, ## a method of a type
MethodOfBaseType, ## a method of a base type
MethodOfInstance, ## a method of an instance
MethodOfScript, ## a method of a script & base
PropertyOfVariantType, ## a property of a type
PropertyOfBaseType, ## a property of a base type
PropertyOfInstance, ## a property of an instance
PropertyOfScript, ## a property of a script & base
PropertyHintMax
const
GODOT_PROPERTY_USAGE_STORAGE_VALUE = 1.cint
GODOT_PROPERTY_USAGE_EDITOR_VALUE = 2.cint
GODOT_PROPERTY_USAGE_NETWORK_VALUE = 4.cint
GODOT_PROPERTY_USAGE_EDITOR_HELPER_VALUE = 8.cint
GODOT_PROPERTY_USAGE_CHECKABLE_VALUE = 16.cint
GODOT_PROPERTY_USAGE_CHECKED_VALUE = 32.cint
GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE = 64.cint
GODOT_PROPERTY_USAGE_GROUP_VALUE = 128.cint
GODOT_PROPERTY_USAGE_CATEGORY_VALUE = 256.cint
GODOT_PROPERTY_USAGE_STORE_IF_NONZERO_VALUE = 512.cint
GODOT_PROPERTY_USAGE_STORE_IF_NONONE_VALUE = 1024.cint
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE_VALUE = 2048.cint
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED_VALUE = 4096.cint
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE_VALUE = 8192.cint
GODOT_PROPERTY_USAGE_STORE_IF_NULL_VALUE = 16384.cint
GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER_VALUE = 32768.cint
GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED_VALUE = 65536.cint
GODOT_PROPERTY_USAGE_DEFAULT_VALUE: cint =
GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_EDITOR_VALUE or
GODOT_PROPERTY_USAGE_NETWORK_VALUE
GODOT_PROPERTY_USAGE_DEFAULT_INTL_VALUE: cint =
GODOT_PROPERTY_USAGE_STORAGE_VALUE or
GODOT_PROPERTY_USAGE_EDITOR_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE or
GODOT_PROPERTY_USAGE_INTERNATIONALIZED_VALUE
GODOT_PROPERTY_USAGE_NOEDITOR_VALUE: cint =
GODOT_PROPERTY_USAGE_STORAGE_VALUE or GODOT_PROPERTY_USAGE_NETWORK_VALUE
type
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.}
proc godotScriptRegisterClass*(libHandle: pointer; name, base: cstring;
create_func: GodotInstanceCreateFunc;
destroy_func: GodotInstanceDestroyFunc) {.
importc: "godot_nativescript_register_class".}
proc godotScriptRegisterToolClass*(libHandle: pointer; name, base: cstring;
createFunc: GodotInstanceCreateFunc; createFunc: GodotInstanceCreateFunc;
destroyFunc: GodotInstanceDestroyFunc) destroyFunc: GodotInstanceDestroyFunc) {.
{.inline.} = importc: "godot_nativescript_register_tool_class".}
getGDNativeAPI().nativeScriptRegisterClass( type
libHandle, name, base, createFunc, destroyFunc) GodotInstanceMethod* {.bycopy.} = object
meth*:
proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer; numArgs: cint;
args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
GodotVariant {.noconv.}
methodData*: pointer
freeFunc*: proc (a2: pointer) {.noconv.}
proc nativeScriptRegisterToolClass*(libHandle: pointer; name, base: cstring; proc godotScriptRegisterMethod*(libHandle: pointer;
createFunc: GodotInstanceCreateFunc;
destroyFunc: GodotInstanceDestroyFunc)
{.inline.} =
getGDNativeAPI().nativeScriptRegisterToolClass(
libHandle, name, base, createFunc, destroyFunc)
proc nativeScriptRegisterMethod*(libHandle: pointer;
name: cstring; function_name: cstring; name: cstring; function_name: cstring;
attr: GodotMethodAttributes; attr: GodotMethodAttributes;
meth: GodotInstanceMethod) {.inline.} = meth: GodotInstanceMethod) {.
getGDNativeAPI().nativeScriptRegisterMethod( importc: "godot_nativescript_register_method".}
libHandle, name, functionName, attr, meth) type
GodotPropertySetFunc* {.bycopy.} = object
setFunc*: proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer; value: GodotVariant) {.noconv.}
methodData*: pointer
freeFunc*: proc (a2: pointer) {.noconv.}
proc nativeScriptRegisterProperty*(libHandle: pointer; GodotPropertyGetFunc* {.bycopy.} = object
name, path: cstring; getFunc*: proc (obj: ptr GodotObject; methodData: pointer;
userData: pointer): GodotVariant {.noconv.}
methodData*: pointer
freeFunc*: proc (a2: pointer) {.noconv.}
proc godotScriptRegisterProperty*(libHandle: pointer;
name: cstring; path: cstring;
attr: ptr GodotPropertyAttributes; attr: ptr GodotPropertyAttributes;
setFunc: GodotPropertySetFunc; setFunc: GodotPropertySetFunc;
getFunc: GodotPropertyGetFunc) {.inline.} = getFunc: GodotPropertyGetFunc) {.
getGDNativeAPI().nativeScriptRegisterProperty( importc: "godot_nativescript_register_property".}
libHandle, name, path, attr, setFunc, getFunc)
proc nativeScriptRegisterSignal*(libHandle: pointer; name: cstring; type
signal: GodotSignal) {.inline.} = GodotSignalArgument* {.bycopy.} = object
getGDNativeAPI().nativeScriptRegisterSignal(libHandle, name, signal) name*: GodotString
typ*: cint
hint*: GodotPropertyHint
hintString*: GodotString
usage*: cint
defaultValue*: GodotVariant
proc getUserdata*(instance: ptr GodotObject): pointer {.inline.} = GodotSignal* = object
getGDNativeAPI().nativeScriptGetUserdata(instance) name*: GodotString
numArgs*: cint
args*: ptr GodotSignalArgument
numDefaultArgs*: cint
defaultArgs*: ptr GodotVariant
proc getClassConstructor*(className: cstring): GodotClassConstructor
{.inline.} =
getGDNativeAPI().getClassConstructor(className)
proc deinit*(o: ptr GodotObject) {.inline.} = proc godotScriptRegisterSignal*(libHandle: pointer; name: cstring;
getGDNativeAPI().objectDestroy(o) signal: GodotSignal) {.
importc: "godot_nativescript_register_signal".}
proc getUserdata*(instance: ptr GodotObject): pointer {.
importc: "godot_nativescript_get_userdata".}
type ClassConstructor = proc (): ptr GodotObject {.noconv.}
proc getClassConstructor*(className: cstring): ClassConstructor {.
importc: "godot_get_class_constructor".}
proc deinit*(o: ptr GodotObject) {.
importc: "godot_object_destroy".}
# print using Godot's error handler list # print using Godot's error handler list
proc godotPrintError*(description, function, file: cstring; proc godotPrintError*(description: cstring; function: cstring; file: cstring;
line: cint) {.inline.} = line: cint) {.
getGDNativeAPI().printError(description, function, file, line) importc: "godot_print_error".}
proc godotPrintWarning*(description, function, file: cstring; proc godotPrintWarning*(description: cstring; function: cstring;
line: cint) {.inline.} = file: cstring; line: cint) {.
getGDNativeAPI().printWarning(description, function, file, line) importc: "godot_print_warning".}
proc godotPrint*(message: GodotString) {.inline.} = proc godotPrint*(message: GodotString) {.
getGDNativeAPI().print(message) importc: "godot_print".}
var getClassMethodBind: ptr GodotMethodBind var getClassMethodBind: ptr GodotMethodBind
proc getClassName*(o: ptr GodotObject): string = proc getClassName*(o: ptr GodotObject): string =
@ -93,30 +267,22 @@ proc getClassName*(o: ptr GodotObject): string =
# There are physics type not known by ClassDB # There are physics type not known by ClassDB
result = result[0..result.len-3] result = result[0..result.len-3]
proc getClassNameRaw*(o: ptr GodotObject): GodotString = proc getGodotSingleton*(name: cstring): ptr GodotObject {.
if getClassMethodBind.isNil: importc: "godot_global_get_singleton".}
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 # System Functions
proc godotAlloc*(bytes: cint): pointer {.inline.} = proc godotAlloc*(bytes: cint): pointer {.
importc: "godot_alloc".}
## Allocates the specified number of bytes. ## Allocates the specified number of bytes.
## Using this instead of stdlib proc will help Godot track how much memory ## Using this instead of stdlib proc will help Godot track how much memory
## is in use in debug mode. ## is in use in debug mode.
getGDNativeAPI().alloc(bytes) proc godotRealloc*(p: pointer; bytes: cint): pointer {.
importc: "godot_realloc".}
proc godotRealloc*(p: pointer; bytes: cint): pointer {.inline.} =
## Reallocates the pointer for the specified number of bytes. ## Reallocates the pointer for the specified number of bytes.
## Using this instead of stdlib proc will help Godot track how much memory ## Using this instead of stdlib proc will help Godot track how much memory
## is in use in debug mode. ## is in use in debug mode.
getGDNativeAPI().realloc(p, bytes) proc godotFree*(p: pointer) {.importc: "godot_free".}
proc godotFree*(p: pointer) {.inline.} =
## Frees the memory pointed to by the pointer. ## Frees the memory pointed to by the pointer.
## Using this instead of stdlib proc will help Godot track how much memory ## Using this instead of stdlib proc will help Godot track how much memory
## is in use in debug mode. ## 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,155 +1,123 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import godotinternaltypes, gdnativeapi, core/godotcoretypes type
GodotArray* {.byref.} = object
data: array[sizeof(int), byte]
proc len*(self: GodotArray): cint {.inline.} = proc len*(self: GodotArray): cint {.
getGDNativeAPI().arraySize(self) noSideEffect,
importc: "godot_array_size".}
import hashes import hashes
import godotobjects, godotpoolarrays, godotvariants, godotstrings
proc initGodotArray*(dest: var GodotArray) {.inline.} = proc initGodotArray*(dest: var GodotArray) {.
getGDNativeAPI().arrayNew(dest) importc: "godot_array_new".}
proc initGodotArray*(dest: var GodotArray; pca: GodotPoolColorArray) {.
importc: "godot_array_new_pool_coloarray".}
proc initGodotArray*(dest: var GodotArray; pv3a: GodotPoolVector3Array) {.
importc: "godot_array_new_pool_vector3_array".}
proc initGodotArray*(dest: var GodotArray; pv2a: GodotPoolVector2Array) {.
importc: "godot_array_new_pool_vector2_array".}
proc initGodotArray*(dest: var GodotArray; psa: GodotPoolStringArray) {.
importc: "godot_array_new_pool_string_array".}
proc initGodotArray*(dest: var GodotArray; pra: GodotPoolRealArray) {.
importc: "godot_array_new_pool_real_array".}
proc initGodotArray*(dest: var GodotArray; pia: GodotPoolIntArray) {.
importc: "godot_array_new_pool_int_array".}
proc initGodotArray*(dest: var GodotArray; pba: GodotPoolByteArray) {.
importc: "godot_array_new_pool_byte_array".}
proc iniGodotArray*(dest: var GodotArray; src: GodotArray) {.
importc: "godot_array_new_copy".}
proc initGodotArray*(dest: var GodotArray; proc deinit*(self: var GodotArray) {.importc: "godot_array_destroy".}
pca: GodotPoolColorArray) {.inline.} =
getGDNativeAPI().arrayNewPoolColorArray(dest, pca)
proc initGodotArray*(dest: var GodotArray; proc `[]=`*(self: var GodotArray; idx: cint;
pv3a: GodotPoolVector3Array) {.inline.} = value: GodotVariant) {.
getGDNativeAPI().arrayNewPoolVector3Array(dest, pv3a) noSideEffect,
importc: "godot_array_set".}
proc initGodotArray*(dest: var GodotArray; proc `[]`*(self: GodotArray; idx: cint): GodotVariant {.
pv2a: GodotPoolVector2Array) {.inline.} = noSideEffect,
getGDNativeAPI().arrayNewPoolVector2Array(dest, pv2a) importc: "godot_array_get".}
proc mget*(self: var GodotArray; idx: cint): ptr GodotVariant {.
proc initGodotArray*(dest: var GodotArray; importc: "godot_array_operator_index".}
psa: GodotPoolStringArray) {.inline.} =
getGDNativeAPI().arrayNewPoolStringArray(dest, psa)
proc initGodotArray*(dest: var GodotArray;
pra: GodotPoolRealArray) {.inline.} =
getGDNativeAPI().arrayNewPoolRealArray(dest, pra)
proc initGodotArray*(dest: var GodotArray;
pia: GodotPoolIntArray) {.inline.} =
getGDNativeAPI().arrayNewPoolIntArray(dest, pia)
proc initGodotArray*(dest: var GodotArray;
pba: GodotPoolByteArray) {.inline.} =
getGDNativeAPI().arrayNewPoolByteArray(dest, pba)
proc initGodotArray*(dest: var GodotArray; src: GodotArray) {.inline.} =
getGDNativeAPI().arrayNewCopy(dest, src)
proc deinit*(self: var GodotArray) {.inline.} =
getGDNativeAPI().arrayDestroy(self)
proc `[]=`*(self: var GodotArray; idx: cint; value: GodotVariant) {.inline.} =
getGDNativeAPI().arraySet(self, idx, value)
proc `[]`*(self: GodotArray; idx: cint): GodotVariant {.inline.} =
getGDNativeAPI().arrayGet(self, idx)
proc mget*(self: var GodotArray; idx: cint): ptr GodotVariant {.inline.} =
getGDNativeAPI().arrayOperatorIndex(self, idx)
proc add*(self: var GodotArray; value: GodotVariant) {.inline.} =
getGDNativeAPI().arrayPushBack(self, value)
proc clear*(self: var GodotArray) {.inline.} =
getGDNativeAPI().arrayClear(self)
proc count*(self: GodotArray; value: GodotVariant): cint {.inline.} =
getGDNativeAPI().arrayCount(self, value)
proc isEmpty*(self: GodotArray): bool {.inline.} =
getGDNativeAPI().arrayEmpty(self)
proc erase*(self: var GodotArray; value: GodotVariant) {.inline.} =
getGDNativeAPI().arrayErase(self, value)
proc first*(self: GodotArray): GodotVariant {.inline.} =
getGDNativeAPI().arrayFront(self)
proc last*(self: GodotArray): GodotVariant {.inline.} =
getGDNativeAPI().arrayBack(self)
proc add*(self: var GodotArray; value: GodotVariant) {.
noSideEffect,
importc: "godot_array_append".}
proc clear*(self: var GodotArray) {.importc: "godot_array_clear".}
proc count*(self: GodotArray; value: GodotVariant): cint {.
noSideEffect,
importc: "godot_array_count".}
proc isEmpty*(self: GodotArray): bool {.
noSideEffect,
importc: "godot_array_empty".}
proc erase*(self: var GodotArray; value: GodotVariant) {.
importc: "godot_array_erase".}
proc first*(self: GodotArray): GodotVariant {.
noSideEffect,
importc: "godot_array_front".}
proc last*(self: GodotArray): GodotVariant {.
noSideEffect,
importc: "godot_array_back".}
proc find*(self: GodotArray; what: GodotVariant; proc find*(self: GodotArray; what: GodotVariant;
fromIdx: cint): cint {.inline.} = f: cint): cint {.
getGDNativeAPI().arrayFind(self, what, fromIdx) noSideEffect,
importc: "godot_array_find".}
proc findLast*(self: GodotArray; what: GodotVariant): cint {.inline.} = proc findLast*(self: GodotArray; what: GodotVariant): cint {.
getGDNativeAPI().arrayFindLast(self, what) noSideEffect,
importc: "godot_array_find_last".}
proc contains*(self: GodotArray; value: GodotVariant): bool {.inline.} = proc contains*(self: GodotArray; value: GodotVariant): bool {.
getGDNativeAPI().arrayHas(self, value) noSideEffect,
importc: "godot_array_has".}
proc godotHash*(self: GodotArray): cint {.inline.} =
getGDNativeAPI().arrayHash(self)
proc godotHash*(self: GodotArray): cint {.
noSideEffect,
importc: "godot_array_hash".}
proc hash*(self: GodotArray): Hash {.inline.} = proc hash*(self: GodotArray): Hash {.inline.} =
hash(godotHash(self)) hash(godotHash(self))
proc insert*(self: var GodotArray; pos: cint; proc insert*(self: var GodotArray; pos: cint;
value: GodotVariant): Error {.discardable, inline.} = value: GodotVariant) {.
getGDNativeAPI().arrayInsert(self, pos, value) importc: "godot_array_insert".}
proc reverse*(self: var GodotArray) {.importc: "godot_array_invert".}
proc reverse*(self: var GodotArray) {.inline.} = proc popLast*(self: var GodotArray): GodotVariant {.
getGDNativeAPI().arrayInvert(self) importc: "godot_array_pop_back".}
proc popFirst*(self: var GodotArray): GodotVariant {.
proc popLast*(self: var GodotArray): GodotVariant {.inline.} = importc: "godot_array_pop_front".}
getGDNativeAPI().arrayPopBack(self) proc addLast*(self: var GodotArray; value: GodotVariant) {.
importc: "godot_array_push_back".}
proc popFirst*(self: var GodotArray): GodotVariant {.inline.} = proc addFirst*(self: var GodotArray; value: GodotVariant) {.
getGDNativeAPI().arrayPopFront(self) importc: "godot_array_push_front".}
proc addLast*(self: var GodotArray; value: GodotVariant) {.inline.} =
getGDNativeAPI().arrayPushBack(self, value)
proc addFirst*(self: var GodotArray; value: GodotVariant) {.inline.} =
getGDNativeAPI().arrayPushFront(self, value)
proc delete*(self: var GodotArray; idx: cint) {.inline.} =
getGDNativeAPI().arrayRemove(self, idx)
proc setLen*(self: var GodotArray; size: cint) {.inline.} =
getGDNativeAPI().arrayResize(self, size)
proc delete*(self: var GodotArray; idx: cint) {.
importc: "godot_array_remove".}
proc setLen*(self: var GodotArray; size: cint) {.
importc: "godot_array_resize".}
proc rfind*(self: GodotArray; what: GodotVariant; proc rfind*(self: GodotArray; what: GodotVariant;
fromIdx: cint): cint {.inline.} = f: cint): cint {.
getGDNativeAPI().arrayRFind(self, what, fromIdx) noSideEffect,
importc: "godot_array_rfind".}
proc sort*(self: var GodotArray) {.inline.} = proc sort*(self: var GodotArray) {.importc: "godot_array_sort".}
getGDNativeAPI().arraySort(self) proc sortCustom*(self: var GodotArray; obj: var GodotObject;
funcName: GodotString) {.
proc sortCustom*(self: var GodotArray; obj: ptr GodotObject; importc: "godot_array_sort_custom".}
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 = iterator items*(self: GodotArray): GodotVariant =
for i in 0.cint..<self.len: for i in 0..<self.len:
yield self[i] yield self[i]
iterator mitems*(self: var GodotArray): var GodotVariant = iterator mitems*(self: var GodotArray): var GodotVariant =
for i in 0.cint..<self.len: for i in 0..<self.len:
yield self.mget(i)[] yield self.mget(i)[]
iterator pairs*(self: GodotArray): tuple[key: cint, val: GodotVariant] = iterator pairs*(self: GodotArray): tuple[key: cint, val: GodotVariant] =
for i in 0.cint..<self.len: for i in 0..<self.len:
yield (i, self[i]) yield (i, self[i])
iterator mpairs*(self: var GodotArray): tuple[key: cint, iterator mpairs*(self: var GodotArray): tuple[key: cint,
val: var GodotVariant] = val: var GodotVariant] =
for i in 0.cint..<self.len: for i in 0..<self.len:
yield (i, self.mget(i)[]) yield (i, self.mget(i)[])
proc `$`*(self: GodotArray): string = proc `$`*(self: GodotArray): string =

View file

@ -1,56 +1,48 @@
# Copyright (c) 2018 Xored Software, Inc. # Copyright (c) 2017 Xored Software, Inc.
import godotinternaltypes, gdnativeapi type
GodotDictionary* {.byref.} = object
data: array[sizeof(int), byte]
proc initGodotDictionary*(dest: var GodotDictionary) {.inline.} = import godotarrays, godotvariants, godotstrings
getGDNativeAPI().dictionaryNew(dest)
proc initGodotDictionary*(dest: var GodotDictionary; proc initGodotDictionary*(dest: var GodotDictionary; src: GodotDictionary) {.
src: GodotDictionary) {.inline.} = importc: "godot_dictionary_new_copy".}
getGDNativeAPI().dictionaryNewCopy(dest, src)
proc deinit*(self: var GodotDictionary) {.inline.} = proc deinit*(self: var GodotDictionary) {.
getGDNativeAPI().dictionaryDestroy(self) importc: "godot_dictionary_destroy".}
proc len*(self: GodotDictionary): cint {.inline.} = proc initGodotDictionary*(dest: var GodotDictionary) {.
getGDNativeAPI().dictionarySize(self) importc: "godot_dictionary_new".}
proc isEmpty*(self: GodotDictionary): bool {.inline.} = proc len*(self: GodotDictionary): cint {.
getGDNativeAPI().dictionaryEmpty(self) importc: "godot_dictionary_size".}
proc isEmpty*(self: GodotDictionary): bool {.
importc: "godot_dictionary_empty".}
proc clear*(self: var GodotDictionary) {.
importc: "godot_dictionary_clear".}
proc contains*(self: GodotDictionary; key: GodotVariant): bool {.
importc: "godot_dictionary_has".}
proc contains*(self: GodotDictionary; keys: GodotArray): bool {.
importc: "godot_dictionary_has_all".}
proc del*(self: var GodotDictionary; key: GodotVariant) {.
importc: "godot_dictionary_erase".}
proc clear*(self: var GodotDictionary) {.inline.} = proc godotHash*(self: GodotDictionary): cint {.
getGDNativeAPI().dictionaryClear(self) importc: "godot_dictionary_hash".}
proc keys*(self: GodotDictionary): GodotArray {.
importc: "godot_dictionary_keys".}
proc values*(self: GodotDictionary): GodotArray {.
importc: "godot_dictionary_values".}
proc `[]`*(self: GodotDictionary; key: GodotVariant): GodotVariant {.
importc: "godot_dictionary_get".}
proc `[]=`*(self: var GodotDictionary; key, value: GodotVariant) {.
importc: "godot_dictionary_set".}
proc mget*(self: var GodotDictionary; key: GodotVariant): ptr GodotVariant {.
importc: "godot_dictionary_operator_index".}
proc contains*(self: GodotDictionary; key: GodotVariant): bool {.inline.} = proc `==`*(self, other: GodotDictionary): bool {.
getGDNativeAPI().dictionaryHas(self, key) importc: "godot_dictionary_operator_equal".}
proc contains*(self: GodotDictionary; keys: GodotArray): bool {.inline.} = proc toJson*(self: GodotDictionary): GodotString {.
getGDNativeAPI().dictionaryHasAll(self, keys) importc: "godot_dictionary_to_json".}
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 +1,32 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import godotinternaltypes, gdnativeapi import godotstrings
proc initGodotNodePath*(dest: var GodotNodePath; s: GodotString) {.inline.} = type
getGDNativeAPI().nodePathNew(dest, s) GodotNodePath* {.byref.} = object
data: array[sizeof(int), byte]
proc initGodotNodePath*(dest: var GodotNodePath; proc initGodotNodePath*(dest: var GodotNodePath; s: GodotString) {.
src: GodotNodePath) {.inline.} = importc: "godot_node_path_new".}
getGDNativeAPI().nodePathNewCopy(dest, src) proc deinit*(self: var GodotNodePath) {.
importc: "godot_node_path_destroy".}
proc toGodotString*(self: GodotNodePath): GodotString {.
importc: "godot_node_path_as_string".}
proc deinit*(self: var GodotNodePath) {.inline.} = proc isAbsolute*(self: GodotNodePath): bool {.
getGDNativeAPI().nodePathDestroy(self) noSideEffect, importc: "godot_node_path_is_absolute".}
proc nameCount*(self: GodotNodePath): cint {.
noSideEffect, importc: "godot_node_path_get_name_count".}
proc getName*(self: GodotNodePath; idx: cint): GodotString {.
noSideEffect, importc: "godot_node_path_get_name".}
proc subnameCount*(self: GodotNodePath): cint {.
noSideEffect, importc: "godot_node_path_get_subname_count".}
proc getSubname*(self: GodotNodePath; idx: cint): GodotString {.
noSideEffect, importc: "godot_node_path_get_subname".}
proc property*(self: GodotNodePath): GodotString {.
noSideEffect, importc: "godot_node_path_get_property".}
proc isEmpty*(self: GodotNodePath): bool {.
noSideEffect, importc: "godot_node_path_is_empty".}
proc toGodotString*(self: GodotNodePath): GodotString {.inline.} = proc `==`*(a, b: GodotNodePath): bool {.
getGDNativeAPI().nodePathAsString(self) noSideEffect, importc: "godot_node_path_operator_equal".}
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

@ -0,0 +1,4 @@
# Copyright 2017 Xored Software, Inc.
type
GodotObject* = object

View file

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

View file

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

View file

@ -1,216 +1,197 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
type
VariantType* {.size: sizeof(cint), pure.} = enum
Nil, ## atomic types
Bool,
Int,
Real,
String,
# math types
Vector2, ## 5
Rect2,
Vector3,
Transform2D,
Plane,
Quat, ## 10
Rect3,
Basis,
Transform, ## misc types
Color,
NodePath, ## 15
RID,
Object,
Dictionary,
Array, ## 20
# arrays
PoolByteArray,
PoolIntArray,
PoolRealArray,
PoolStringArray,
PoolVector2Array, ## 25
PoolVector3Array,
PoolColorArray
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[4 + sizeof(int) div 4, float32]
import godotobjects, godotarrays, godotpoolarrays,
godotstrings, godotnodepaths, godotdictionaries
import core.vector2, core.rect2,
core.vector3, core.transform2d, core.planes,
core.quats, core.rect3, core.basis,
core.transforms, core.colors, core.rids,
core.rect2
proc getType*(p: GodotVariant): VariantType {.
importc: "godot_variant_get_type".}
proc initGodotVariant*(dest: var GodotVariant) {.
importc: "godot_variant_new_nil".}
proc initGodotVariant*(dest: var GodotVariant, src: GodotVariant) {.
importc: "godot_variant_new_copy".}
proc initGodotVariant*(dest: var GodotVariant; b: bool) {.
importc: "godot_variant_new_bool".}
proc initGodotVariant*(dest: var GodotVariant; i: uint64) {.
importc: "godot_variant_new_uint".}
proc initGodotVariant*(dest: var GodotVariant; i: int64) {.
importc: "godot_variant_new_int".}
proc initGodotVariant*(dest: var GodotVariant; r: cdouble) {.
importc: "godot_variant_new_real".}
proc initGodotVariant*(dest: var GodotVariant; s: GodotString) {.
importc: "godot_variant_new_string".}
proc initGodotVariant*(dest: var GodotVariant; v2: Vector2) {.
importc: "godot_variant_new_vector2".}
proc initGodotVariant*(dest: var GodotVariant; rect2: Rect2) {.
importc: "godot_variant_new_rect2".}
proc initGodotVariant*(dest: var GodotVariant; v3: Vector3) {.
importc: "godot_variant_new_vector3".}
proc initGodotVariant*(dest: var GodotVariant; t2d: Transform2D) {.
importc: "godot_variant_new_transform2d".}
proc initGodotVariant*(dest: var GodotVariant; plane: Plane) {.
importc: "godot_variant_new_plane".}
proc initGodotVariant*(dest: var GodotVariant; quat: Quat) {.
importc: "godot_variant_new_quat".}
proc initGodotVariant*(dest: var GodotVariant; rect3: Rect3) {.
importc: "godot_variant_new_rect3".}
proc initGodotVariant*(dest: var GodotVariant; basis: Basis) {.
importc: "godot_variant_new_basis".}
proc initGodotVariant*(dest: var GodotVariant; trans: Transform) {.
importc: "godot_variant_new_transform".}
proc initGodotVariant*(dest: var GodotVariant; color: Color) {.
importc: "godot_variant_new_color".}
proc initGodotVariant*(dest: var GodotVariant; nodePath: GodotNodePath) {.
importc: "godot_variant_new_node_path".}
proc initGodotVariant*(dest: var GodotVariant; rid: RID) {.
importc: "godot_variant_new_rid".}
proc initGodotVariant*(dest: var GodotVariant; obj: ptr GodotObject) {.
importc: "godot_variant_new_object".}
proc initGodotVariant*(dest: var GodotVariant; arr: GodotArray) {.
importc: "godot_variant_new_array".}
proc initGodotVariant*(dest: var GodotVariant; pba: GodotPoolByteArray) {.
importc: "godot_variant_new_pool_byte_array".}
proc initGodotVariant*(dest: var GodotVariant; pia: GodotPoolIntArray) {.
importc: "godot_variant_new_pool_int_array".}
proc initGodotVariant*(dest: var GodotVariant; pra: GodotPoolRealArray) {.
importc: "godot_variant_new_pool_real_array".}
proc initGodotVariant*(dest: var GodotVariant; psa: GodotPoolStringArray) {.
importc: "godot_variant_new_pool_string_array".}
proc initGodotVariant*(dest: var GodotVariant; pv2a: GodotPoolVector2Array) {.
importc: "godot_variant_new_pool_vector2_array".}
proc initGodotVariant*(dest: var GodotVariant; pv3a: GodotPoolVector3Array) {.
importc: "godot_variant_new_pool_vector3_array".}
proc initGodotVariant*(dest: var GodotVariant; pca: GodotPoolColorArray) {.
importc: "godot_variant_new_pool_color_array".}
proc initGodotVariant*(dest: var GodotVariant; dict: GodotDictionary) {.
importc: "godot_variant_new_dictionary".}
proc deinit*(v: var GodotVariant) {.importc: "godot_variant_destroy".}
proc asBool*(self: GodotVariant): bool {.
importc: "godot_variant_as_bool".}
proc asUInt*(self: GodotVariant): uint64 {.
importc: "godot_variant_as_uint".}
proc asInt*(self: GodotVariant): int64 {.
importc: "godot_variant_as_int".}
proc asReal*(self: GodotVariant): cdouble {.
importc: "godot_variant_as_real".}
proc asGodotString*(self: GodotVariant): GodotString {.
importc: "godot_variant_as_string".}
proc asVector2*(self: GodotVariant): Vector2 {.
importc: "godot_variant_as_vector2".}
proc asRect2*(self: GodotVariant): Rect2 {.
importc: "godot_variant_as_rect2".}
proc asVector3*(self: GodotVariant): Vector3 {.
importc: "godot_variant_as_vector3".}
proc asTransform2D*(self: GodotVariant): Transform2D {.
importc: "godot_variant_as_transform2d".}
proc asPlane*(self: GodotVariant): Plane {.
importc: "godot_variant_as_plane".}
proc asQuat*(self: GodotVariant): Quat {.
importc: "godot_variant_as_quat".}
proc asRect3*(self: GodotVariant): Rect3 {.
importc: "godot_variant_as_rect3".}
proc asBasis*(self: GodotVariant): Basis {.
importc: "godot_variant_as_basis".}
proc asTransform*(self: GodotVariant): Transform {.
importc: "godot_variant_as_transform".}
proc asColor*(self: GodotVariant): Color {.
importc: "godot_variant_as_color".}
proc asNodePath*(self: GodotVariant): GodotNodePath {.
importc: "godot_variant_as_node_path".}
proc asRID*(self: GodotVariant): RID {.
importc: "godot_variant_as_rid".}
proc asGodotObject*(self: GodotVariant): ptr GodotObject {.
importc: "godot_variant_as_object".}
proc asGodotArray*(self: GodotVariant): GodotArray {.
importc: "godot_variant_as_array".}
proc asGodotPoolByteArray*(self: GodotVariant): GodotPoolByteArray {.
importc: "godot_variant_as_pool_byte_array".}
proc asGodotPoolIntArray*(self: GodotVariant): GodotPoolIntArray {.
importc: "godot_variant_as_pool_int_array".}
proc asGodotPoolRealArray*(self: GodotVariant): GodotPoolRealArray {.
importc: "godot_variant_as_pool_real_array".}
proc asGodotPoolStringArray*(self: GodotVariant): GodotPoolStringArray {.
importc: "godot_variant_as_pool_string_array".}
proc asGodotPoolVector2Array*(self: GodotVariant): GodotPoolVector2Array {.
importc: "godot_variant_as_pool_vector2_array".}
proc asGodotPoolVector3Array*(self: GodotVariant): GodotPoolVector3Array {.
importc: "godot_variant_as_pool_vector3_array".}
proc asGodotPoolColorArray*(self: GodotVariant): GodotPoolColorArray {.
importc: "godot_variant_as_pool_color_array".}
proc asGodotDictionary*(self: GodotVariant): GodotDictionary {.
importc: "godot_variant_as_dictionary".}
proc call*(self: GodotVariant; meth: GodotString;
args: var array[128, GodotVariant]; argCount: cint;
error: var VariantCallError): GodotVariant {.
importc: "godot_variant_call".}
proc hasMethod*(self: GodotVariant; meth: GodotString): bool {.
importc: "godot_variant_has_method".}
proc `==`*(self, other: GodotVariant): bool {.
importc: "godot_variant_operator_equal".}
proc `<`*(self, other: GodotVariant): bool {.
importc: "godot_variant_operator_less".}
proc hashCompare*(self, other: GodotVariant): bool {.
importc: "godot_variant_hash_compare".}
proc booleanize*(self: GodotVariant; isValid: var bool): bool {.
importc: "godot_variant_booleanize".}
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 = proc `$`*(self: GodotVariant): string =
var s = self.asGodotString() var s = self.asGodotString()
result = $s result = $s

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 macros, tables, typetraits
import godotinternal, internal/godotvariants import godotinternal, internal.godotvariants
import godotnim, core/variants import godotnim, core.variants
type type
VarDecl = ref object VarDecl = ref object
@ -10,8 +10,8 @@ type
typ: NimNode typ: NimNode
defaultValue: NimNode defaultValue: NimNode
isNoGodot: bool isNoGodot: bool
hint: Option[string] hint: string
hintStr: Option[string] hintStr: string
usage: NimNode usage: NimNode
isExported: bool isExported: bool
@ -32,8 +32,6 @@ type
ParseError = object of Exception ParseError = object of Exception
include "internal/backwardcompat.inc.nim"
proc godotToNim[T](val: Variant): (T, ConversionResult) = proc godotToNim[T](val: Variant): (T, ConversionResult) =
mixin fromVariant mixin fromVariant
result[1] = fromVariant(result[0], val) result[1] = fromVariant(result[0], val)
@ -53,15 +51,14 @@ template parseError(node: NimNode, msg: string) =
proc extractNames(definition: NimNode): proc extractNames(definition: NimNode):
tuple[name, parentName: string] = tuple[name, parentName: string] =
if definition.kind == nnkIdent: if definition.kind == nnkIdent:
result.name = definition.strVal result.name = $(definition.ident)
else: else:
if not (definition.kind == nnkInfix and if not (definition.kind == nnkInfix and definition[0].ident == !"of"):
definition[0].strVal == "of"):
parseError(definition, "invalid type definition") parseError(definition, "invalid type definition")
result.name = definition[1].strVal result.name = $(definition[1].ident)
case definition[2].kind: case definition[2].kind:
of nnkIdent: of nnkIdent:
result.parentName = definition[2].strVal result.parentName = $definition[2].ident
else: else:
parseError(definition[2], "parent type expected") parseError(definition[2], "parent type expected")
@ -74,13 +71,13 @@ proc newCStringLit(s: string): NimNode {.compileTime.} =
newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s)) newNimNode(nnkCallStrLit).add(ident("cstring"), newRStrLit(s))
iterator pragmas(node: NimNode): iterator pragmas(node: NimNode):
tuple[key: string, value: NimNode, index: int] = tuple[key: NimIdent, value: NimNode, index: int] =
assert node.kind in {nnkPragma, nnkEmpty} assert node.kind in {nnkPragma, nnkEmpty}
for index in countdown(node.len - 1, 0): for index in countdown(node.len - 1, 0):
if node[index].kind == nnkExprColonExpr: if node[index].kind == nnkExprColonExpr:
yield (node[index][0].strVal, node[index][1], index) yield (node[index][0].ident, node[index][1], index)
elif node[index].kind == nnkIdent: elif node[index].kind == nnkIdent:
yield (node[index].strVal, nil, index) yield (node[index].ident, nil, index)
proc removePragmaNode(statement: NimNode, proc removePragmaNode(statement: NimNode,
pname: string): NimNode {.compileTime.} = pname: string): NimNode {.compileTime.} =
@ -93,8 +90,9 @@ proc removePragmaNode(statement: NimNode,
result = nil result = nil
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma() var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
else: statement[1] else: statement[1]
let pnameIdent = !pname
for ident, val, i in pragmas(pragmas): for ident, val, i in pragmas(pragmas):
if ident.eqIdent(pname): if ident == pnameIdent:
pragmas.del(i) pragmas.del(i)
return val return val
@ -105,18 +103,19 @@ proc removePragma(statement: NimNode, pname: string): bool =
return false return false
var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma() var pragmas = if RoutineNodes.contains(statement.kind): statement.pragma()
else: statement[1] else: statement[1]
let pnameIdent = !pname
for ident, val, i in pragmas(pragmas): for ident, val, i in pragmas(pragmas):
if ident.eqIdent(pname): if ident == pnameIdent:
pragmas.del(i) pragmas.del(i)
return true return true
proc removeStrPragma(statement: NimNode, proc removeStrPragma(statement: NimNode,
pname: string): Option[string] {.compileTime.} = pname: string): string {.compileTime.} =
## Removes the pragma from the node and returns value of the pragma ## Removes the pragma from the node and returns value of the pragma
## Works for routine nodes or nnkPragmaExpr ## Works for routine nodes or nnkPragmaExpr
let node = removePragmaNode(statement, pname) let node = removePragmaNode(statement, pname)
result = if node.isNil: none(string) result = if node.isNil: nil
else: some($node) else: $node
proc isExported(node: NimNode): bool {.compileTime.} = proc isExported(node: NimNode): bool {.compileTime.} =
if node.kind == nnkPragmaExpr: if node.kind == nnkPragmaExpr:
@ -172,15 +171,10 @@ proc parseMethod(meth: NimNode): MethodDecl =
proc parseVarSection(decl: NimNode): seq[VarDecl] = proc parseVarSection(decl: NimNode): seq[VarDecl] =
assert(decl.kind == nnkVarSection) assert(decl.kind == nnkVarSection)
for i in 0..<decl.len: result = identDefsToVarDecls(decl[0])
if i == 0:
result = identDefsToVarDecls(decl[i])
else:
result.add(identDefsToVarDecls(decl[i]))
proc parseType(ast: NimNode): ObjectDecl = proc parseType(definition, callSite: NimNode): ObjectDecl =
let definition = ast[0] let body = callSite[^1]
let body = ast[^1]
result = ObjectDecl( result = ObjectDecl(
fields: newSeq[VarDecl](), fields: newSeq[VarDecl](),
methods: newSeq[MethodDecl]() methods: newSeq[MethodDecl]()
@ -188,17 +182,17 @@ proc parseType(ast: NimNode): ObjectDecl =
(result.name, result.parentName) = extractNames(definition) (result.name, result.parentName) = extractNames(definition)
var isTool = false var isTool = false
for i in 1..(ast.len - 2): for i in 2..(callSite.len - 2):
let option = ast[i] let option = callSite[i]
if option.kind != nnkIdent: if option.kind != nnkIdent:
parseError(option, "type specifier expected") parseError(option, "type specifier expected")
if option.strVal == "tool": if option.ident == !"tool":
isTool = true isTool = true
else: else:
parseError(option, "valid type specifier expected") parseError(option, "valid type specifier expected")
result.isTool = isTool result.isTool = isTool
if result.parentName.len == 0: result.parentName = "Object" if result.parentName.isNil: result.parentName = "Object"
for statement in body: for statement in body:
case statement.kind: case statement.kind:
of nnkVarSection: of nnkVarSection:
@ -215,7 +209,7 @@ proc parseType(ast: NimNode): ObjectDecl =
macro invokeVarArgs(procIdent, objIdent; macro invokeVarArgs(procIdent, objIdent;
minArgs, maxArgs: static[int], numArgsIdent, minArgs, maxArgs: static[int], numArgsIdent,
argSeqIdent; argTypes: seq[NimNode], argSeqIdent; argTypes: seq[NimNode],
hasReturnValue, isStaticCall: static[bool]): untyped = hasReturnValue, isStaticCall: static[bool]): typed =
## Produces statement in form: ## Produces statement in form:
## ##
## .. code-block:: nim ## .. code-block:: nim
@ -272,12 +266,8 @@ macro invokeVarArgs(procIdent, objIdent;
invocation = newNimNode(nnkCall).add(ident("procCall"), invocation) invocation = newNimNode(nnkCall).add(ident("procCall"), invocation)
if hasReturnValue: 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( let theCall = newNimNode(nnkBracketExpr).add(newNimNode(nnkDotExpr).add(
resultVariant, ident("godotVariant"))) newCall("toVariant", invocation), ident("godotVariant")))
branchBody.add(getAst(initGodotVariantCall(ident("result"), theCall))) branchBody.add(getAst(initGodotVariantCall(ident("result"), theCall)))
else: else:
branchBody.add(invocation) branchBody.add(invocation)
@ -292,7 +282,7 @@ macro invokeVarArgs(procIdent, objIdent;
" arguments, but got " & $numArgs) " arguments, but got " & $numArgs)
result.add(newNimNode(nnkElse).add(getAst( 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: string, value: string, godotType: VariantType,
className: cstring, propertyName: cstring): string = className: cstring, propertyName: cstring): string =
@ -359,11 +349,11 @@ template registerGodotClass(classNameIdent, classNameLit; isRefClass: bool;
) )
registerClass(classNameIdent, classNameLit, false) registerClass(classNameIdent, classNameLit, false)
when isTool: when isTool:
nativeScriptRegisterToolClass(getNativeLibHandle(), classNameLit, godotScriptRegisterToolClass(getNativeLibHandle(), classNameLit, baseNameLit,
baseNameLit, createFuncObj, destroyFuncObj) createFuncObj, destroyFuncObj)
else: else:
nativeScriptRegisterClass(getNativeLibHandle(), classNameLit, godotScriptRegisterClass(getNativeLibHandle(), classNameLit, baseNameLit,
baseNameLit, createFuncObj, destroyFuncObj) createFuncObj, destroyFuncObj)
template registerGodotField(classNameLit, classNameIdent, propNameLit, template registerGodotField(classNameLit, classNameIdent, propNameLit,
propNameIdent, propTypeLit, propTypeIdent, propNameIdent, propTypeLit, propTypeIdent,
@ -400,9 +390,10 @@ template registerGodotField(classNameLit, classNameIdent, propNameLit,
getFunc: getFuncIdent getFunc: getFuncIdent
) )
mixin godotTypeInfo mixin godotTypeInfo
const typeInfo = when compiles(godotTypeInfo(propTypeIdent)): static:
godotTypeInfo(propTypeIdent) var typeInfo: GodotTypeInfo
else: GodotTypeInfo() when compiles(godotTypeInfo(propTypeIdent)):
typeInfo = godotTypeInfo(propTypeIdent)
const hintStr = when hintStrLit != "NIM": const hintStr = when hintStrLit != "NIM":
hintStrLit hintStrLit
else: else:
@ -424,10 +415,13 @@ template registerGodotField(classNameLit, classNameIdent, propNameLit,
{.push warning[ProveInit]: on.} {.push warning[ProveInit]: on.}
when hasDefaultValue: when hasDefaultValue:
attr.defaultValue = (defaultValueNode).toVariant().godotVariant[] attr.defaultValue = (defaultValueNode).toVariant().godotVariant[]
nativeScriptRegisterProperty(getNativeLibHandle(), classNameLit, propNameLit, godotScriptRegisterProperty(getNativeLibHandle(), classNameLit, propNameLit,
unsafeAddr attr, setFunc, getFunc) unsafeAddr attr, setFunc, getFunc)
hintStrGodot.deinit() hintStrGodot.deinit()
static:
import strutils, sets, sequtils
proc toGodotStyle(s: string): string {.compileTime.} = proc toGodotStyle(s: string): string {.compileTime.} =
result = newStringOfCap(s.len + 10) result = newStringOfCap(s.len + 10)
for c in s: for c in s:
@ -448,7 +442,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let objTy = newNimNode(nnkObjectTy) let objTy = newNimNode(nnkObjectTy)
typeDef.add(newNimNode(nnkRefTy).add(objTy)) typeDef.add(newNimNode(nnkRefTy).add(objTy))
objTy.add(newEmptyNode()) objTy.add(newEmptyNode())
if obj.parentName.len == 0: if obj.parentName.isNil:
objTy.add(newEmptyNode()) objTy.add(newEmptyNode())
else: else:
objTy.add(newNimNode(nnkOfInherit).add(ident(obj.parentName))) objTy.add(newNimNode(nnkOfInherit).add(ident(obj.parentName)))
@ -458,8 +452,7 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
let initBody = newStmtList() let initBody = newStmtList()
for decl in obj.fields: for decl in obj.fields:
if not decl.defaultValue.isNil and decl.defaultValue.kind != nnkEmpty: if not decl.defaultValue.isNil and decl.defaultValue.kind != nnkEmpty:
initBody.add(newNimNode(nnkAsgn).add(newDotExpr(ident("self"), decl.name), initBody.add(newNimNode(nnkAsgn).add(decl.name, decl.defaultValue))
decl.defaultValue))
let name = if not decl.isExported: decl.name let name = if not decl.isExported: decl.name
else: postfix(decl.name, "*") else: postfix(decl.name, "*")
recList.add(newIdentDefs(name, decl.typ)) recList.add(newIdentDefs(name, decl.typ))
@ -485,7 +478,6 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
else: else:
initMethod.body.insert(0, initBody) initMethod.body.insert(0, initBody)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
# {.this: self.} for convenience # {.this: self.} for convenience
result.add(newNimNode(nnkPragma).add(newNimNode(nnkExprColonExpr).add( result.add(newNimNode(nnkPragma).add(newNimNode(nnkExprColonExpr).add(
ident("this"), ident("self") ident("this"), ident("self")
@ -509,25 +501,23 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
result.add(meth.nimNode) result.add(meth.nimNode)
# Register Godot object # Register Godot object
let parentName = if obj.parentName.len == 0: newStrLitNode("Object") let parentName = if obj.parentName.isNil: newStrLitNode("Object")
else: newStrLitNode(obj.parentName) else: newStrLitNode(obj.parentName)
let classNameLit = newStrLitNode(obj.name) let classNameLit = newCStringLit(obj.name)
let classNameIdent = ident(obj.name) let classNameIdent = ident(obj.name)
let isRef: bool = if obj.parentName.len == 0: false let isRef: bool = if obj.parentName.isNil: false
else: obj.parentName in refClasses 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( result.add(getAst(
registerGodotClass(classNameIdent, classNameLit, newLit(isRef), parentName, registerGodotClass(classNameIdent, classNameLit, isRef, parentName,
genSym(nskProc, "createFunc"), newLit(obj.isTool)))) genSym(nskProc, "createFunc"), obj.isTool)))
# Register fields (properties) # Register fields (properties)
for field in obj.fields: for field in obj.fields:
if field.isNoGodot: continue if field.isNoGodot: continue
let hintStr = if field.hintStr.isNone: "NIM" let hintStr = if field.hintStr.isNil: "NIM"
else: field.hintStr.get else: field.hintStr
let hint = if field.hint.isNone: "NIM" let hint = if field.hint.isNil: "NIM"
else: field.hint.get else: field.hint
let usage = let usage =
if field.usage.isNil: if field.usage.isNil:
newLit(ord(GodotPropertyUsage.Default) or newLit(ord(GodotPropertyUsage.Default) or
@ -550,23 +540,10 @@ proc genType(obj: ObjectDecl): NimNode {.compileTime.} =
template registerGodotMethod(classNameLit, classNameIdent, methodNameIdent, template registerGodotMethod(classNameLit, classNameIdent, methodNameIdent,
methodNameLit, minArgs, maxArgs, methodNameLit, minArgs, maxArgs,
argTypes, methFuncIdent, hasReturnValue) = 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, proc methFuncIdent(obj: ptr GodotObject, methodData: pointer,
userData: pointer, numArgs: cint, userData: pointer, numArgs: cint,
args: var array[MAX_ARG_COUNT, ptr GodotVariant]): args: var array[MAX_ARG_COUNT, ptr GodotVariant]):
GodotVariant {.noconv.} = GodotVariant {.noconv.} =
var stackBottom {.volatile.}: pointer
stackBottom = addr(stackBottom)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
{.emit: """
setStackBottom((void*)(&`stackBottom`));
""".}
else:
nimGC_setStackBottom(stackBottom)
let self = cast[classNameIdent](userData) let self = cast[classNameIdent](userData)
const isStaticCall = methodNameLit == cstring"_ready" or const isStaticCall = methodNameLit == cstring"_ready" or
methodNameLit == cstring"_process" or methodNameLit == cstring"_process" or
@ -591,8 +568,8 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom);
let meth = GodotInstanceMethod( let meth = GodotInstanceMethod(
meth: methFuncIdent meth: methFuncIdent
) )
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit, godotScriptRegisterMethod(getNativeLibHandle(), classNameLit, methodNameLit,
methodNameLit, GodotMethodAttributes(), meth) GodotMethodAttributes(), meth)
for meth in obj.methods: for meth in obj.methods:
if meth.isNoGodot: continue if meth.isNoGodot: continue
@ -610,7 +587,7 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom);
let hasReturnValueBool = not (meth.returnType.isNil or let hasReturnValueBool = not (meth.returnType.isNil or
meth.returnType.kind == nnkEmpty or meth.returnType.kind == nnkEmpty or
(meth.returnType.kind == nnkIdent and (meth.returnType.kind == nnkIdent and
meth.returnType.strVal == "void")) meth.returnType.ident == !"void"))
let hasReturnValue = if hasReturnValueBool: ident("true") let hasReturnValue = if hasReturnValueBool: ident("true")
else: ident("false") else: ident("false")
result.add(getAst( result.add(getAst(
@ -628,15 +605,19 @@ N_NOINLINE(void, setStackBottom)(void* thestackbottom);
let refDec = GodotInstanceMethod( let refDec = GodotInstanceMethod(
meth: refcountDecremented meth: refcountDecremented
) )
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit, godotScriptRegisterMethod(getNativeLibHandle(), classNameLit,
cstring"_refcount_incremented", cstring"_refcount_incremented",
GodotMethodAttributes(), refInc) GodotMethodAttributes(), refInc)
nativeScriptRegisterMethod(getNativeLibHandle(), classNameLit, godotScriptRegisterMethod(getNativeLibHandle(), classNameLit,
cstring"_refcount_decremented", cstring"_refcount_decremented",
GodotMethodAttributes(), refDec) GodotMethodAttributes(), refDec)
result.add(getAst(registerRefIncDec(classNameLit))) result.add(getAst(registerRefIncDec(classNameLit)))
macro gdobj*(ast: varargs[untyped]): untyped = {.push warning[Deprecated]: off.}
# immediate macros are deprecated, but `untyped` doesn't make it immediate,
# as the warning and the documentation claim.
macro gdobj*(definition: untyped, body: typed): typed {.immediate.} =
## Generates Godot type. Self-documenting example: ## Generates Godot type. Self-documenting example:
## ##
## .. code-block:: nim ## .. code-block:: nim
@ -644,7 +625,7 @@ macro gdobj*(ast: varargs[untyped]): untyped =
## ##
## gdobj MyObj of Node: ## gdobj MyObj of Node:
## var myField: int ## var myField: int
## ## Not exported to Godot (i.e. editor and scripts will not see this field). ## ## Not exported to Godot (i.e. editor will not see this field).
## ##
## var myString* {.gdExport, hint: Length, hintStr: "20".}: string ## var myString* {.gdExport, hint: Length, hintStr: "20".}: string
## ## Exported to Godot as ``my_string``. ## ## Exported to Godot as ``my_string``.
@ -657,12 +638,12 @@ macro gdobj*(ast: varargs[untyped]): untyped =
## ## Exported methods are exported to Godot by default, ## ## Exported methods are exported to Godot by default,
## ## and their Godot names are prefixed with ``_`` ## ## and their Godot names are prefixed with ``_``
## ## (in this case ``_ready``) ## ## (in this case ``_ready``)
## print("I am ready! myString is: " & self.myString) ## print("I am ready! myString is: " & myString)
## ##
## proc myProc*() {.gdExport.} = ## proc myProc*() {.gdExport.} =
## ## Exported to Godot as ``my_proc`` ## ## Exported to Godot as ``my_proc``
## print("myProc is called! Incrementing myField.") ## print("myProc is called! Incrementing myField.")
## inc self.myField ## inc myField
## ##
## If parent type is omitted, the type is inherited from ``Object``. ## If parent type is omitted, the type is inherited from ``Object``.
## ##
@ -680,5 +661,7 @@ macro gdobj*(ast: varargs[untyped]): untyped =
## `gdnew <godotnim.html#gdnew>`_ or by using ## `gdnew <godotnim.html#gdnew>`_ or by using
## `load <godotapi/resource_loader.html#load,string,string,bool>`_ or any other way ## `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>`_. ## that you can find in `Godot API <index.html#modules-godot-api>`_.
let typeDef = parseType(ast) let typeDef = parseType(definition, callsite())
result = genType(typeDef) result = genType(typeDef)
{.push warning[Deprecated]: on.}

View file

@ -1,14 +1,13 @@
# Copyright 2018 Xored Software, Inc. # Copyright 2017 Xored Software, Inc.
import tables, typetraits, macros, unicode, strutils, sets, options import tables, typetraits, macros, asyncdispatch
import gdnativeapi import core.godotbase
import core/godotcoretypes, core/godotbase import core.vector2, core.rect2,
import core/vector2, core/rect2, core.vector3, core.transform2d,
core/vector3, core/transform2d, core.planes, core.quats, core.rect3,
core/planes, core/quats, core/aabb, core.basis, core.transforms, core.colors,
core/basis, core/transforms, core/colors, core.nodepaths, core.rids, core.dictionaries,
core/nodepaths, core/rids, core/dictionaries, core.arrays, core.poolarrays, core.variants
core/arrays, core/poolarrays, core/variants
import godotinternal import godotinternal
## This module defines ``NimGodotObject`` and ``toVariant``/``fromVariant`` ## This module defines ``NimGodotObject`` and ``toVariant``/``fromVariant``
@ -31,7 +30,7 @@ type
## The base type all Godot types inherit from. ## The base type all Godot types inherit from.
## Manages lifecycle of the wrapped ``GodotObject``. ## Manages lifecycle of the wrapped ``GodotObject``.
godotObject: ptr GodotObject godotObject: ptr GodotObject
linkedObjectPtr: pointer linkedObject: NimGodotObject
## Wrapper around native object that is the container of the Nim "script" ## Wrapper around native object that is the container of the Nim "script"
## This is needed for `of` checks and `as` conversions to work as ## This is needed for `of` checks and `as` conversions to work as
## expected. For example, Nim type may inherit from ``Spatial``, but the ## expected. For example, Nim type may inherit from ``Spatial``, but the
@ -39,8 +38,6 @@ type
## ``Particles`` is valid, but Nim type system is not aware of that. ## ``Particles`` is valid, but Nim type system is not aware of that.
## This works in both directions - for linked native object this ## This works in both directions - for linked native object this
## reference points to Nim object. ## reference points to Nim object.
## This is stored as a raw pointer to avoid reference cycles and therefore
## improve GC performance.
isRef*: bool isRef*: bool
isFinalized: bool isFinalized: bool
isNative: bool isNative: bool
@ -59,7 +56,7 @@ type
SomeFloat = float32 or float64 or cfloat SomeFloat = float32 or float64 or cfloat
SomeGodot = bool or Vector2 or Rect2 or Vector3 or SomeGodot = bool or Vector2 or Rect2 or Vector3 or
Transform2D or Plane or Quat or AABB or Transform2D or Plane or Quat or Rect3 or
Basis or Transform or Color or NodePath or Basis or Transform or Color or NodePath or
RID or GodotObject or Dictionary or Array or RID or GodotObject or Dictionary or Array or
PoolByteArray or PoolIntArray or PoolRealArray or PoolByteArray or PoolIntArray or PoolRealArray or
@ -91,71 +88,40 @@ type
## values. ## values.
## See documentation of ``GodotPropertyHint`` for description of formats. ## See documentation of ``GodotPropertyHint`` for description of formats.
FNV1Hash = uint32
include "internal/backwardcompat.inc.nim"
proc isFinalized*(obj: NimGodotObject): bool {.inline.} = proc isFinalized*(obj: NimGodotObject): bool {.inline.} =
obj.isFinalized obj.isFinalized
var classRegistry {.threadvar.}: TableRef[FNV1Hash, ObjectInfo] template printWarning*(warning: typed) =
var classRegistryStatic* {.compileTime.}: TableRef[FNV1Hash, ObjectInfo] ## Prints ``warning`` to Godot log, adding filename and line information.
let (filename, line) = instantiationInfo()
godotPrintWarning(cstring($warning), nil, cstring(filename), line.cint)
template printError*(error: typed) =
## Prints ``error`` to Godot log, adding filename and line information.
let (filename, line) = instantiationInfo()
godotPrintError(cstring($error), nil, cstring(filename), 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()
var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo]
var classRegistryStatic* {.compileTime.}: TableRef[cstring, ObjectInfo]
## Compile-time variable used for implementation of several procedures ## Compile-time variable used for implementation of several procedures
## and macros ## and macros
static: static:
classRegistryStatic = newTable[FNV1Hash, ObjectInfo]() classRegistryStatic = newTable[cstring, ObjectInfo]()
static:
import sets, strutils
var nativeClasses {.compileTime.} = newSeq[string]() var nativeClasses {.compileTime.} = newSeq[string]()
var refClasses* {.compileTime.} = newSeq[string]() var refClasses* {.compileTime.} = newSeq[string]()
template initFNV1Hash(hash: var FNV1Hash) =
hash = 0x811c9dc5'u32
template appendFNV1Hash(hash: var FNV1Hash, val: uint8) =
block:
let u64hash = hash.uint64
hash = ((
u64hash +
(u64hash shl 1'u64) +
(u64hash shl 4'u64) +
(u64hash shl 7'u64) +
(u64hash shl 8'u64) +
(u64hash shl 24'u64)) and 0xFFFFFFFF'u32).uint32 xor val
{.push stackTrace:off.}
proc lsb(c: ptr cwchar_t): char {.noinit, inline.} =
{.emit: [result, " = (char)(", c[]," & 0xFF);"]}
{.pop.}
proc fnv1Hash(godotClassName: GodotString): FNV1Hash =
var charsCount = godotClassName.len
let charsPtr = godotClassName.dataPtr
if charsCount > 2 and
charsPtr.offset(charsCount - 2).lsb == 'S' and
charsPtr.offset(charsCount - 1).lsb == 'W':
charsCount -= 2
initFNV1Hash(result)
for i in 0..<charsCount:
let c = charsPtr.offset(i).lsb
appendFNV1Hash(result, c.uint8)
proc fnv1Hash(godotClassName: string): FNV1Hash {.compileTime.} =
var charsCount = godotClassName.len
if godotClassName.endsWith("SW"):
charsCount -= 2
initFNV1Hash(result)
var i = 0
for rune in runes(godotClassName):
if i >= charsCount:
break
let firstByte = uint8(rune.uint64 and 0xFF'u64)
appendFNV1Hash(result, firstByte)
# We don't really need to calculate hash of other bytes,
# since we only use hashes of ASCII strings
inc i
proc getClassName*(o: NimGodotObject): string = proc getClassName*(o: NimGodotObject): string =
o.godotObject.getClassName() o.godotObject.getClassName()
@ -173,13 +139,6 @@ proc reference(o: ptr GodotObject): bool {.discardable.} =
cstring"reference") cstring"reference")
referenceMethodBind.ptrCall(o, nil, addr result) referenceMethodBind.ptrCall(o, nil, addr result)
var initRefMethodBind {.threadvar.}: ptr GodotMethodBind
proc initRef(o: ptr GodotObject): bool {.discardable.} =
if isNil(initRefMethodBind):
initRefMethodBind = getMethod(cstring"Reference",
cstring"init_ref")
initRefMethodBind.ptrCall(o, nil, addr result)
proc deinit*(obj: NimGodotObject) = proc deinit*(obj: NimGodotObject) =
## Destroy the object. You only need to call this for objects not inherited ## Destroy the object. You only need to call this for objects not inherited
## from Reference, where manual lifecycle control is necessary. ## from Reference, where manual lifecycle control is necessary.
@ -187,15 +146,12 @@ proc deinit*(obj: NimGodotObject) =
obj.godotObject.deinit() obj.godotObject.deinit()
obj.godotObject = nil obj.godotObject = nil
proc linkedObject(obj: NimGodotObject): NimGodotObject {.inline.} =
cast[NimGodotObject](obj.linkedObjectPtr)
proc nimGodotObjectFinalizer*[T: NimGodotObject](obj: T) = proc nimGodotObjectFinalizer*[T: NimGodotObject](obj: T) =
if obj.godotObject.isNil or obj.isNative: return if obj.godotObject.isNil or obj.isNative: return
# important to set it before so that ``unreference`` is aware # important to set it before so that ``unreference`` is aware
obj.isFinalized = true obj.isFinalized = true
if (obj.isRef or not obj.linkedObject.isNil and obj.linkedObject.isRef) and if obj.isRef and obj.godotObject.unreference() or
obj.godotObject.unreference(): not obj.linkedObject.isNil:
obj.deinit() obj.deinit()
macro baseNativeType(T: typedesc): cstring = macro baseNativeType(T: typedesc): cstring =
@ -209,7 +165,7 @@ macro baseNativeType(T: typedesc): cstring =
if typeName == "NimGodotObject": if typeName == "NimGodotObject":
break break
t = getType(t[1][1]) t = getType(t[1][1])
if baseT.len == 0: if baseT.isNil:
result = newNilLit() result = newNilLit()
else: else:
let rStr = newNimNode(nnkRStrLit) let rStr = newNimNode(nnkRStrLit)
@ -234,12 +190,12 @@ macro isResource(T: typedesc): bool =
result = if inherits(getType(T), "Resource"): ident("true") result = if inherits(getType(T), "Resource"): ident("true")
else: ident("false") else: ident("false")
template registerClass*(T: typedesc; godotClassName: string or cstring, template registerClass*(T: typedesc; godotClassName: cstring,
native: bool) = native: bool) =
## Registers the specified Godot type. ## Registers the specified Godot type.
## Used by ``gdobj`` macro and `godotapigen <godotapigen.html>`_. ## Used by ``gdobj`` macro and `godotapigen <godotapigen.html>`_.
if classRegistry.isNil: if classRegistry.isNil:
classRegistry = newTable[FNV1Hash, ObjectInfo]() classRegistry = newTable[cstring, ObjectInfo]()
let constructor = proc(): NimGodotObject = let constructor = proc(): NimGodotObject =
var t: T var t: T
new(t, nimGodotObjectFinalizer[T]) new(t, nimGodotObjectFinalizer[T])
@ -253,22 +209,14 @@ template registerClass*(T: typedesc; godotClassName: string or cstring,
isNative: native, isNative: native,
isRef: isRef isRef: isRef
) )
classRegistry[fnv1Hash($godotClassName)] = objInfo classRegistry[godotClassName] = objInfo
static: static:
let objInfoStatic = ObjectInfo( let objInfoStatic = ObjectInfo(
baseNativeClass: base, baseNativeClass: base,
isNative: native, isNative: native,
isRef: isRef, isRef: isRef,
) )
let nameHash = fnv1Hash($godotClassName) classRegistryStatic[godotClassName] = objInfoStatic
if not classRegistryStatic.contains(nameHash):
classRegistryStatic[nameHash] = objInfoStatic
elif not endsWith($godotClassName, "SW"):
# For simplicity we assume that all class names must have
# different hashes
# If this exception is ever raised, I guess, we should
# implement a proper collision resolving
raise newException(Exception, "Hash collision " & $godotClassName)
when isRef: when isRef:
static: static:
refClasses.add(T.name) refClasses.add(T.name)
@ -277,10 +225,10 @@ template registerClass*(T: typedesc; godotClassName: string or cstring,
nativeClasses.add(T.name) nativeClasses.add(T.name)
proc newNimGodotObject[T: NimGodotObject]( proc newNimGodotObject[T: NimGodotObject](
godotObject: ptr GodotObject, godotClassName: GodotString, noRef: bool): T = godotObject: ptr GodotObject, godotClassName: cstring, noRef: bool): T =
assert(not classRegistry.isNil) assert(not classRegistry.isNil)
assert(not godotObject.isNil) assert(not godotObject.isNil)
let objInfo = classRegistry.getOrDefault(fnv1Hash(godotClassName)) let objInfo = classRegistry.getOrDefault(godotClassName)
if objInfo.constructor.isNil: if objInfo.constructor.isNil:
printError("Nim constructor not found for class " & $godotClassName) printError("Nim constructor not found for class " & $godotClassName)
else: else:
@ -291,7 +239,7 @@ proc newNimGodotObject[T: NimGodotObject](
result.godotObject.reference() result.godotObject.reference()
proc asNimGodotObject*[T: NimGodotObject]( proc asNimGodotObject*[T: NimGodotObject](
godotObject: ptr GodotObject, forceNativeObject, noRef: bool = false): T = godotObject: ptr GodotObject, forceNativeObject: bool = false): T =
## Wraps ``godotObject`` into Nim type ``T``. ## Wraps ``godotObject`` into Nim type ``T``.
## This is used by `godotapigen <godotapigen.html>`_ and should rarely be ## This is used by `godotapigen <godotapigen.html>`_ and should rarely be
## used by anything else. ## used by anything else.
@ -303,11 +251,8 @@ proc asNimGodotObject*[T: NimGodotObject](
# Could be data from other bindings # Could be data from other bindings
result = nil result = nil
if result.isNil: if result.isNil:
var classNameStr = godotObject.getClassNameRaw()
result = newNimGodotObject[T]( result = newNimGodotObject[T](
godotObject, classNameStr, godotObject, cstring(godotObject.getClassName()), forceNativeObject)
forceNativeObject or noRef)
deinit(classNameStr)
proc newVariant*(obj: NimGodotObject): Variant {.inline.} = proc newVariant*(obj: NimGodotObject): Variant {.inline.} =
newVariant(obj.godotObject) newVariant(obj.godotObject)
@ -332,35 +277,47 @@ proc `as`*[T: NimGodotObject](obj: NimGodotObject, t: typedesc[T]): T =
## This can be used either in dot notation (``node.as(Button)``) or ## This can be used either in dot notation (``node.as(Button)``) or
## infix notation (``node as Button``). ## infix notation (``node as Button``).
if obj.isNil: return nil if obj.isNil: return nil
if system.`of`(obj, T): if obj of T:
result = T(obj) result = T(obj)
elif not obj.linkedObject.isNil and system.`of`(obj.linkedObject, T): elif not obj.linkedObject.isNil and obj.linkedObject of T:
result = T(obj.linkedObject) result = T(obj.linkedObject)
else: else:
when not defined(release):
printError("Failed to cast object to " &
T.name & "\n" & getStackTrace())
result = nil result = nil
proc `of`*[T1, T2: NimGodotObject](obj: T1, t: typedesc[T2]): bool {.inline.} = proc `of`*[T: NimGodotObject](obj: NimGodotObject,
t: typedesc[T]): bool {.inline.} =
## Godot-specific inheritance check. ## Godot-specific inheritance check.
not obj.isNil and (system.`of`(obj, T2) or system.`of`(obj.linkedObject, T2)) not obj.isNil and (system.`of`(obj, T) or system.`of`(obj.linkedObject, T))
{.deprecated: [`~`: `of`].}
proc newRStrLit(s: string): NimNode {.compileTime.} = proc newRStrLit(s: string): NimNode {.compileTime.} =
result = newNimNode(nnkRStrLit) result = newNimNode(nnkRStrLit)
result.strVal = s result.strVal = s
macro toGodotName(T: typedesc): untyped = static:
import strutils
macro toGodotName(T: typedesc): string =
var godotName: string
if T is GodotString or T is string: if T is GodotString or T is string:
newStrLitNode"String" godotName = "String"
elif T is SomeFloat: elif T is SomeFloat:
newStrLitNode"float" godotName = "float"
elif T is SomeUnsignedInt or T is SomeSignedInt: elif T is SomeUnsignedInt or T is SomeSignedInt:
newStrLitNode"int" godotName = "int"
else: if godotName.isNil:
let nameStr = ((T.getType()[1][1].strVal).split(':')[0]) let nameStr: string = (($T.getType()[1][1].symbol).split(':')[0])
case nameStr: godotName = case nameStr:
of "File", "Directory", "Thread", "Mutex", "Semaphore": of "File", "Directory", "Thread", "Mutex", "Semaphore":
newStrLitNode("_" & nameStr) "_" & nameStr
else: else:
newStrLitNode(nameStr) nameStr
result = newLit(godotName)
macro asCString(s: static[string]): cstring = macro asCString(s: static[string]): cstring =
result = newNimNode(nnkCallStrLit).add( result = newNimNode(nnkCallStrLit).add(
@ -419,18 +376,11 @@ proc newOwnObj[T: NimGodotObject](name: cstring): T =
proc gdnew*[T: NimGodotObject](): T = proc gdnew*[T: NimGodotObject](): T =
## Instantiates new object of type ``T``. ## Instantiates new object of type ``T``.
const godotName = toGodotName(T) const godotName = asCString(toGodotName(T))
const cGodotName = asCString(godotName) const objInfo = classRegistryStatic[godotName]
const objInfo = classRegistryStatic[fnv1Hash(godotName)] result = when objInfo.isNative:
when objInfo.isNative: asNimGodotObject[T](getClassConstructor(godotName)())
let godotObject = getClassConstructor(cGodotName)() else: newOwnObj[T](godotName)
new(result, nimGodotObjectFinalizer[T])
result.godotObject = godotObject
when objInfo.isRef:
godotObject.initRef()
result.isRef = true
else:
result = newOwnObj[T](cGodotName)
proc newCallError*(err: VariantCallError): ref CallError = proc newCallError*(err: VariantCallError): ref CallError =
## Instantiates ``CallError`` from Godot ``err``. ## Instantiates ``CallError`` from Godot ``err``.
@ -470,17 +420,14 @@ proc setGodotObject*(nimObj: NimGodotObject, obj: ptr GodotObject) {.inline.} =
proc setNativeObject*(nimObj: NimGodotObject, proc setNativeObject*(nimObj: NimGodotObject,
nativeObj: NimGodotObject) {.inline.} = nativeObj: NimGodotObject) {.inline.} =
## Used from Godot constructor produced by ``gdobj`` macro. Do not call. ## Used from Godot constructor produced by ``gdobj`` macro. Do not call.
GC_ref(nativeObj) nimObj.linkedObject = nativeObj
nimObj.linkedObjectPtr = cast[pointer](nativeObj) nativeObj.linkedObject = nimObj
nativeObj.linkedObjectPtr = cast[pointer](nimObj)
nativeObj.isNative = true nativeObj.isNative = true
proc removeGodotObject*(nimObj: NimGodotObject) {.inline.} = proc removeGodotObject*(nimObj: NimGodotObject) {.inline.} =
## Used from Godot destructor produced by ``gdobj`` macro. Do not call. ## Used from Godot destructor produced by ``gdobj`` macro. Do not call.
GC_unref(nimObj.linkedObject)
nimObj.godotObject = nil nimObj.godotObject = nil
nimObj.linkedObject.godotObject = nil nimObj.linkedObject.godotObject = nil
nimObj.linkedObjectPtr = nil
proc `==`*(self, other: NimGodotObject): bool {.inline.} = proc `==`*(self, other: NimGodotObject): bool {.inline.} =
## Compares objects by referential equality. ## Compares objects by referential equality.
@ -523,7 +470,7 @@ proc toVariant*(self: Variant): Variant {.inline.} =
if self.isNil: if self.isNil:
newVariant() newVariant()
else: else:
newVariant(self) self
proc fromVariant*(self: var Variant, proc fromVariant*(self: var Variant,
val: Variant): ConversionResult {.inline.} = val: Variant): ConversionResult {.inline.} =
@ -551,8 +498,8 @@ proc godotTypeInfo*(T: typedesc[SomeGodotOrNum]): GodotTypeInfo {.inline.} =
VariantType.Plane VariantType.Plane
elif T is Quat: elif T is Quat:
VariantType.Quat VariantType.Quat
elif T is AABB: elif T is Rect3:
VariantType.AABB VariantType.Rect3
elif T is Basis: elif T is Basis:
VariantType.Basis VariantType.Basis
elif T is Transform: elif T is Transform:
@ -612,11 +559,7 @@ proc fromVariant*[T: SomeSignedInt or SomeUnsignedInt](
else: uint64) else: uint64)
intVal = when T is SomeSignedInt: val.asInt() intVal = when T is SomeSignedInt: val.asInt()
else: val.asUint() else: val.asUint()
const highT = when T is SomeSignedInt: high(T).int64 if intVal > high(T) or intVal < low(T):
else: high(T).uint64
const lowT = when T is SomeSignedInt: low(T).int64
else: low(T).uint64
if intVal > highT or intVal < lowT:
result = ConversionResult.RangeError result = ConversionResult.RangeError
else: else:
self = T(intVal) self = T(intVal)
@ -672,8 +615,8 @@ proc fromVariant*[T: SomeGodot](self: var T, val: Variant): ConversionResult =
self = val.asPlane() self = val.asPlane()
elif self is Quat: elif self is Quat:
self = val.asQuat() self = val.asQuat()
elif self is AABB: elif self is Rect3:
self = val.asAABB() self = val.asRect3()
elif self is Basis: elif self is Basis:
self = val.asBasis() self = val.asBasis()
elif self is Transform: elif self is Transform:
@ -720,10 +663,7 @@ proc fromVariant*(s: var string, val: Variant): ConversionResult =
if val.getType() == VariantType.String: if val.getType() == VariantType.String:
s = val.asString() s = val.asString()
elif val.getType() == VariantType.Nil: elif val.getType() == VariantType.Nil:
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
s = nil s = nil
else:
s = ""
else: else:
result = ConversionResult.TypeError result = ConversionResult.TypeError
@ -749,20 +689,12 @@ proc godotTypeInfo*(T: typedesc[seq]): GodotTypeInfo =
proc godotTypeInfo*(T: typedesc[array]): GodotTypeInfo = proc godotTypeInfo*(T: typedesc[array]): GodotTypeInfo =
arrTypeInfo(T) arrTypeInfo(T)
template arrayToVariant(s: untyped): Variant = proc toVariant*[T](s: openarray[T]): Variant =
var arr = newArray() var arr = newArray()
mixin toVariant mixin toVariant
for item in s: for item in s:
arr.add(toVariant(item)) arr.add(toVariant(item))
newVariant(arr) result = newVariant(arr)
proc toVariant*[T](s: seq[T]): Variant =
if s.isNil:
return newVariant()
result = arrayToVariant(s)
proc toVariant*[I, T](s: array[I, T]): Variant =
result = arrayToVariant(s)
proc fromVariant*[T](s: var seq[T], val: Variant): ConversionResult = proc fromVariant*[T](s: var seq[T], val: Variant): ConversionResult =
if val.getType() == VariantType.Nil: if val.getType() == VariantType.Nil:
@ -797,31 +729,10 @@ proc fromVariant*[T: array](s: var T, val: Variant): ConversionResult =
else: else:
result = ConversionResult.TypeError result = ConversionResult.TypeError
proc godotTypeInfo*[T](OptT: typedesc[Option[T]]): GodotTypeInfo = proc godotTypeInfo*(T: typedesc[Table|TableRef]): GodotTypeInfo {.inline.} =
when compiles(godotTypeInfo(T)):
result.variantType = godotTypeInfo(T)
else:
result.variantType = VariantType.Nil
proc toVariant*[T](option: Option[T]): Variant =
if option.isSome():
result = toVariant(option.unsafeGet())
else:
result = newVariant()
proc fromVariant*[T](option: var Option[T], val: Variant): ConversionResult =
if val.getType() == VariantType.Nil:
option = none(T)
else:
var v: T
result = fromVariant(v, val)
if result == ConversionResult.OK:
option = some(result)
proc godotTypeInfo*(T: typedesc[Table|TableRef|OrderedTable|OrderedTableRef]): GodotTypeInfo {.inline.} =
result.variantType = VariantType.Dictionary result.variantType = VariantType.Dictionary
proc toVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: T): Variant = proc toVariant*[T: Table or TableRef](t: T): Variant =
when t is ref: when t is ref:
if t.isNil: if t.isNil:
return newVariant() return newVariant()
@ -831,7 +742,7 @@ proc toVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: T):
dict[toVariant(k)] = toVariant(v) dict[toVariant(k)] = toVariant(v)
result = newVariant(dict) result = newVariant(dict)
proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: var T, proc fromVariant*[T: Table or TableRef](t: var T,
val: Variant): ConversionResult = val: Variant): ConversionResult =
if val.getType() == VariantType.Nil: if val.getType() == VariantType.Nil:
when t is ref: when t is ref:
@ -841,12 +752,8 @@ proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: va
mixin fromVariant mixin fromVariant
when t is Table: when t is Table:
t = initTable[type(t.keys()), type(t.values())]() t = initTable[type(t.keys()), type(t.values())]()
elif t is TableRef:
t = newTable[type(t.keys()), type(t.values())]()
elif t is OrderedTable:
t = initOrderedTable[type(t.keys()), type(t.values())]()
else: else:
t = newOrderedTable[type(t.keys()), type(t.values())]() t = newTable[type(t.keys()), type(t.values())]()
for k, v in dict: for k, v in dict:
var nimKey: type(t.keys()) var nimKey: type(t.keys())
var nimVal: type(t.values()) var nimVal: type(t.values())
@ -864,11 +771,10 @@ proc fromVariant*[T: Table or TableRef or OrderedTable or OrderedTableRef](t: va
else: else:
result = ConversionResult.TypeError result = ConversionResult.TypeError
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0): {.emit: """/*TYPESECTION*/
{.emit: """/*TYPESECTION*/ void NimMain(void);
N_LIB_EXPORT N_CDECL(void, NimMain)(void); N_NOINLINE(void, setStackBottom)(void* thestackbottom);
N_NOINLINE(void, setStackBottom)(void* thestackbottom); """.}
""".}
var nativeLibHandle: pointer var nativeLibHandle: pointer
proc getNativeLibHandle*(): pointer = proc getNativeLibHandle*(): pointer =
@ -881,60 +787,29 @@ proc godot_nativescript_init(handle: pointer) {.
nativeLibHandle = handle nativeLibHandle = handle
var stackBottom {.volatile.}: pointer var stackBottom {.volatile.}: pointer
stackBottom = addr(stackBottom)
{.emit: """ {.emit: """
NimMain(); NimMain();
""".}
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
{.emit: """
setStackBottom((void*)(&`stackBottom`)); setStackBottom((void*)(&`stackBottom`));
""".} """.}
else:
nimGC_setStackBottom(stackBottom)
GC_fullCollect() GC_fullCollect()
GC_disable() GC_disable()
proc godot_gdnative_init(options: ptr GDNativeInitOptions) {. proc godot_gdnative_init(options: ptr GodotNativeInitOptions) {.
cdecl, exportc, dynlib.} = cdecl, exportc, dynlib.} =
gdNativeLibraryObj = options.gdNativeLibrary gdNativeLibraryObj = options.gdNativeLibrary
setGDNativeAPI(options.gdNativeAPIStruct, options)
proc godot_gdnative_terminate(options: ptr GDNativeTerminateOptions) {. proc godot_gdnative_terminate(options: ptr GodotNativeTerminateOptions) {.
cdecl, exportc, dynlib.} = cdecl, exportc, dynlib.} =
if not options[].inEditor or not compileOption("threads"):
deallocHeap(runFinalizers = not options[].inEditor, allowGcAfterwards = false) deallocHeap(runFinalizers = not options[].inEditor, allowGcAfterwards = false)
const nimGcStepLengthUs {.intdefine.} = 2000 const nimGcStepLengthUs {.intdefine.} = 2000
var idleCallbacks {.threadvar.}: seq[proc () {.closure.}]
idleCallbacks = newSeq[proc () {.closure.}]()
var isMainThread {.threadvar.}: bool
isMainThread = true
proc registerFrameCallback*(cb: proc () {.closure.}) =
# Registers a callback to be called on the main thread at the end
# of each frame.
if not isMainThread:
const err = cstring"registerFrameIdleCallback is called from non-main thread. Ignoring."
godotPrintError(err, cstring"registerFrameCallback",
cstring"godotnim.nim", 0)
else:
idleCallbacks.add(cb)
{.push stackTrace: off.}
proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} = proc godot_nativescript_frame() {.cdecl, exportc, dynlib.} =
var stackBottom {.volatile.}: pointer var stackBottom {.volatile.}: pointer
stackBottom = addr(stackBottom)
when (NimMajor, NimMinor, NimPatch) < (0, 19, 0):
{.emit: """ {.emit: """
setStackBottom((void*)(&`stackBottom`)); setStackBottom((void*)(&`stackBottom`));
""".} """.}
else: if asyncdispatch.hasPendingOperations():
nimGC_setStackBottom(stackBottom) poll(0)
for cb in idleCallbacks:
cb()
GC_step(nimGcStepLengthUs, true, 0) GC_step(nimGcStepLengthUs, true, 0)
when not defined(release): when not defined(release):
@ -945,13 +820,8 @@ proc godot_nativescript_thread_enter() {.cdecl, exportc, dynlib.} =
when compileOption("threads"): when compileOption("threads"):
setupForeignThreadGc() setupForeignThreadGc()
else: else:
const err = cstring"A foreign thread is created, but app is compiled without --threads:on. Bad things will happen if Nim code is invoked from this thread. If you see this warning when running the editor and you don't actually use threads, ignore it." print(cstring"A foreign thread is created, but app is compiled without --threads:on. Bad things will happen if Nim code is invoked from this thread.")
var s = err.toGodotString()
godotPrint(s)
s.deinit()
proc godot_nativescript_thread_exit() {.cdecl, exportc, dynlib.} = proc godot_nativescript_thread_exit() {.cdecl, exportc, dynlib.} =
when compileOption("threads"): when compileOption("threads"):
teardownForeignThreadGc() teardownForeignThreadGc()
{.pop.} # stackTrace: off

View file

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