Compare commits
40 Commits
3.2-stable
...
2.0.1-stab
| Author | SHA1 | Date | |
|---|---|---|---|
| 53aa9cd51a | |||
| 706d576f7b | |||
| 226e0a7f4f | |||
| c44060bb82 | |||
| 4fee5f3915 | |||
| e69c9021b5 | |||
| edb3716da7 | |||
| 1bdd5d24cb | |||
| a1a1c0b9f6 | |||
| 450a7a9120 | |||
| c850fa7331 | |||
| afd75013f9 | |||
| 848c7378fd | |||
| 4b2fcabb74 | |||
| cb7693c533 | |||
| 7fea990b1b | |||
| 95e46e6eac | |||
| bea8e1654e | |||
| cafcdb015d | |||
| 459b914d9c | |||
| 9ed3d21d5a | |||
| 82d06b0027 | |||
| e0a66b6e56 | |||
| 186b82c350 | |||
| 1af2e1101d | |||
| a55f41e3d9 | |||
| 439e29ea95 | |||
| f5e8e89f50 | |||
| f619b05751 | |||
| aa94ff6dae | |||
| ee5c250b63 | |||
| e4d367e7a1 | |||
| 45a0bbe56e | |||
| d86b12a397 | |||
| f0ba9c7e78 | |||
| 61f17fb1bb | |||
| a43af20f31 | |||
| 7ba92ae9eb | |||
| b05c27a27f | |||
| e30cbc3b36 |
@ -1,32 +0,0 @@
|
||||
image: Visual Studio 2019
|
||||
|
||||
platform: x64
|
||||
|
||||
environment:
|
||||
HOME: "%HOMEDRIVE%%HOMEPATH%"
|
||||
PYTHON: C:\Python38
|
||||
SCONS_CACHE_ROOT: "%HOME%\\scons_cache"
|
||||
SCONS_CACHE_LIMIT: 1024
|
||||
matrix:
|
||||
- GD_PLATFORM: windows
|
||||
TOOLS: yes
|
||||
TARGET: release_debug
|
||||
|
||||
init:
|
||||
- ps: if ($env:APPVEYOR_REPO_BRANCH -ne "master") { $env:APPVEYOR_CACHE_SKIP_SAVE = "true" }
|
||||
|
||||
cache:
|
||||
- "%SCONS_CACHE_ROOT%"
|
||||
|
||||
install:
|
||||
- SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
- pip install scons==3.1.2
|
||||
|
||||
before_build:
|
||||
- echo %GD_PLATFORM%
|
||||
- python --version
|
||||
- scons --version
|
||||
- set "SCONS_CACHE=%SCONS_CACHE_ROOT%\%APPVEYOR_REPO_BRANCH%"
|
||||
|
||||
build_script:
|
||||
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no verbose=yes progress=no gdnative_wrapper=yes
|
||||
127
.clang-format
127
.clang-format
@ -1,127 +0,0 @@
|
||||
# Commented out parameters are those with the same value as base LLVM style
|
||||
# We can uncomment them if we want to change their value, or enforce the
|
||||
# chosen value in case the base style changes (last sync: Clang 6.0.1).
|
||||
---
|
||||
### General config, applies to all languages ###
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
# AlignConsecutiveAssignments: false
|
||||
# AlignConsecutiveDeclarations: false
|
||||
# AlignEscapedNewlines: Right
|
||||
# AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
# AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
# AllowShortLoopsOnASingleLine: false
|
||||
# AlwaysBreakAfterDefinitionReturnType: None
|
||||
# AlwaysBreakAfterReturnType: None
|
||||
# AlwaysBreakBeforeMultilineStrings: false
|
||||
# AlwaysBreakTemplateDeclarations: false
|
||||
# BinPackArguments: true
|
||||
# BinPackParameters: true
|
||||
# BraceWrapping:
|
||||
# AfterClass: false
|
||||
# AfterControlStatement: false
|
||||
# AfterEnum: false
|
||||
# AfterFunction: false
|
||||
# AfterNamespace: false
|
||||
# AfterObjCDeclaration: false
|
||||
# AfterStruct: false
|
||||
# AfterUnion: false
|
||||
# AfterExternBlock: false
|
||||
# BeforeCatch: false
|
||||
# BeforeElse: false
|
||||
# IndentBraces: false
|
||||
# SplitEmptyFunction: true
|
||||
# SplitEmptyRecord: true
|
||||
# SplitEmptyNamespace: true
|
||||
# BreakBeforeBinaryOperators: None
|
||||
# BreakBeforeBraces: Attach
|
||||
# BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: false
|
||||
# BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: AfterColon
|
||||
# BreakStringLiterals: true
|
||||
ColumnLimit: 0
|
||||
# CommentPragmas: '^ IWYU pragma:'
|
||||
# CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
# DerivePointerAlignment: false
|
||||
# DisableFormat: false
|
||||
# ExperimentalAutoDetectBinPacking: false
|
||||
# FixNamespaceComments: true
|
||||
# ForEachMacros:
|
||||
# - foreach
|
||||
# - Q_FOREACH
|
||||
# - BOOST_FOREACH
|
||||
# IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '".*"'
|
||||
Priority: 1
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 2
|
||||
- Regex: '^<.*'
|
||||
Priority: 3
|
||||
# IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: true
|
||||
# IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
# IndentWrappedFunctionNames: false
|
||||
# JavaScriptQuotes: Leave
|
||||
# JavaScriptWrapImports: true
|
||||
# KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
# MacroBlockBegin: ''
|
||||
# MacroBlockEnd: ''
|
||||
# MaxEmptyLinesToKeep: 1
|
||||
# NamespaceIndentation: None
|
||||
# PenaltyBreakAssignment: 2
|
||||
# PenaltyBreakBeforeFirstCallParameter: 19
|
||||
# PenaltyBreakComment: 300
|
||||
# PenaltyBreakFirstLessLess: 120
|
||||
# PenaltyBreakString: 1000
|
||||
# PenaltyExcessCharacter: 1000000
|
||||
# PenaltyReturnTypeOnItsOwnLine: 60
|
||||
# PointerAlignment: Right
|
||||
# RawStringFormats:
|
||||
# - Delimiter: pb
|
||||
# Language: TextProto
|
||||
# BasedOnStyle: google
|
||||
# ReflowComments: true
|
||||
# SortIncludes: true
|
||||
# SortUsingDeclarations: true
|
||||
# SpaceAfterCStyleCast: false
|
||||
# SpaceAfterTemplateKeyword: true
|
||||
# SpaceBeforeAssignmentOperators: true
|
||||
# SpaceBeforeParens: ControlStatements
|
||||
# SpaceInEmptyParentheses: false
|
||||
# SpacesBeforeTrailingComments: 1
|
||||
# SpacesInAngles: false
|
||||
# SpacesInContainerLiterals: true
|
||||
# SpacesInCStyleCastParentheses: false
|
||||
# SpacesInParentheses: false
|
||||
# SpacesInSquareBrackets: false
|
||||
TabWidth: 4
|
||||
UseTab: Always
|
||||
---
|
||||
### C++ specific config ###
|
||||
Language: Cpp
|
||||
Standard: Cpp03
|
||||
---
|
||||
### ObjC specific config ###
|
||||
Language: ObjC
|
||||
Standard: Cpp03
|
||||
ObjCBlockIndentWidth: 4
|
||||
# ObjCSpaceAfterProperty: false
|
||||
# ObjCSpaceBeforeProtocolList: true
|
||||
---
|
||||
### Java specific config ###
|
||||
Language: Java
|
||||
# BreakAfterJavaFieldAnnotations: false
|
||||
...
|
||||
@ -4,14 +4,6 @@ root = true
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{cpp,hpp,c,h,mm}]
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{*.{py,cs},SConstruct,SCsub}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[.travis.yml]
|
||||
indent_style = space
|
||||
|
||||
19
.gitattributes
vendored
19
.gitattributes
vendored
@ -1,15 +1,4 @@
|
||||
# Properly detect languages on Github
|
||||
*.h linguist-language=cpp
|
||||
*.inc linguist-language=cpp
|
||||
thirdparty/* linguist-vendored
|
||||
|
||||
# Normalize EOL for all files that Git considers text files
|
||||
* text=auto eol=lf
|
||||
|
||||
# The above only works properly for Git 2.10+, so for older versions
|
||||
# we need to manually list the binary files we don't want modified.
|
||||
*.icns binary
|
||||
*.ico binary
|
||||
*.jar binary
|
||||
*.png binary
|
||||
*.ttf binary
|
||||
*.cpp eol=lf
|
||||
*.h eol=lf
|
||||
*.py eol=lf
|
||||
*.hpp eol=lf
|
||||
|
||||
49
.github/CODEOWNERS
vendored
49
.github/CODEOWNERS
vendored
@ -1,49 +0,0 @@
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
# Owners can be @users, @org/teams or emails
|
||||
|
||||
/doc/ @godotengine/documentation
|
||||
doc_classes/* @godotengine/documentation
|
||||
|
||||
# Rendering
|
||||
/drivers/gl_context/ @reduz
|
||||
/drivers/gles2/ @reduz
|
||||
/drivers/gles3/ @reduz
|
||||
|
||||
# Audio
|
||||
/drivers/alsa/ @marcelofg55
|
||||
/drivers/alsamidi/ @marcelofg55
|
||||
/drivers/coreaudio/ @marcelofg55
|
||||
/drivers/coremidi/ @marcelofg55
|
||||
/drivers/pulseaudio/ @marcelofg55
|
||||
/drivers/wasapi/ @marcelofg55
|
||||
/drivers/winmidi/ @marcelofg55
|
||||
/drivers/xaudio2/ @marcelofg55
|
||||
|
||||
/drivers/unix/ @hpvb
|
||||
/drivers/windows/ @hpvb
|
||||
|
||||
/editor/icons/ @djrm
|
||||
|
||||
/misc/ @akien-mga
|
||||
|
||||
/modules/bullet/ @AndreaCatania
|
||||
/modules/csg/ @BastiaanOlij
|
||||
/modules/enet/ @godotengine/network
|
||||
/modules/gdnative/*arvr/ @BastiaanOlij
|
||||
/modules/gdscript/ @vnen @bojidar-bg
|
||||
/modules/mbedtls/ @godotengine/network
|
||||
/modules/mobile_vr/ @BastiaanOlij
|
||||
/modules/mono/ @neikeq
|
||||
/modules/opensimplex/ @JFonS
|
||||
/modules/regex/ @LeeZH
|
||||
/modules/upnp/ @godotengine/network
|
||||
/modules/websocket/ @godotengine/network
|
||||
|
||||
/platform/javascript/ @eska014
|
||||
/platform/uwp/ @vnen
|
||||
|
||||
/server/physics*/ @reduz @AndreaCatania
|
||||
/server/visual*/ @reduz
|
||||
|
||||
/thirdparty/ @akien-mga
|
||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1,2 +0,0 @@
|
||||
patreon: godotengine
|
||||
custom: https://godotengine.org/donate
|
||||
18
.github/ISSUE_TEMPLATE/bug_report.md
vendored
18
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug in Godot
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Godot version:**
|
||||
|
||||
**OS/device including version:**
|
||||
|
||||
**Issue description:**
|
||||
|
||||
**Steps to reproduce:**
|
||||
|
||||
**Minimal reproduction project:**
|
||||
@ -1,19 +0,0 @@
|
||||
---
|
||||
name: Feature / Enhancement Request
|
||||
about: Adding new features or improving existing ones.
|
||||
title: 'IMPORTANT: This repository no longer accepts feature / enhancement requests.'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**IMPORTANT, PLEASE READ**
|
||||
|
||||
Feature / Enhancement requests are no longer accepted in the main Godot repository.
|
||||
Please open an item by filling the relevant fields in the *Proposals* repository:
|
||||
|
||||
https://github.com/godotengine/godot-proposals/issues/new/choose
|
||||
|
||||
Do not submit to this repository or your issue will be closed.
|
||||
|
||||
**IMPORTANT, PLEASE READ**
|
||||
137
.gitignore
vendored
137
.gitignore
vendored
@ -1,6 +1,28 @@
|
||||
# Godot auto generated files
|
||||
*.gen.*
|
||||
.import/
|
||||
# GoDot auto generated files
|
||||
platform/server/logo.h
|
||||
platform/android/logo.h
|
||||
platform/bb10/logo.h
|
||||
platform/iphone/logo.h
|
||||
platform/javascript/logo.h
|
||||
platform/nacl/logo.h
|
||||
platform/osx/logo.h
|
||||
platform/windows/logo.h
|
||||
platform/x11/logo.h
|
||||
drivers/gles2/shaders/*.h
|
||||
modules/register_module_types.cpp
|
||||
core/version.h
|
||||
core/method_bind.inc
|
||||
core/method_bind_ext.inc
|
||||
core/script_encryption_key.cpp
|
||||
core/global_defaults.cpp
|
||||
drivers/unix/os_unix_global_settings_path.cpp
|
||||
tools/editor/register_exporters.cpp
|
||||
tools/editor/doc_data_compressed.h
|
||||
tools/editor/editor_icons.cpp
|
||||
-fpic
|
||||
.fscache
|
||||
make.bat
|
||||
log.txt
|
||||
|
||||
# Documentation generated by doxygen or from classes.xml
|
||||
doc/_build/
|
||||
@ -8,18 +30,22 @@ doc/_build/
|
||||
# Javascript specific
|
||||
*.bc
|
||||
|
||||
# CLion
|
||||
cmake-build-debug
|
||||
|
||||
# Android specific
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
.idea
|
||||
.gradletasknamecache
|
||||
project.properties
|
||||
platform/android/java/.gradle
|
||||
platform/android/java/.gradletasknamecache
|
||||
platform/android/java/local.properties
|
||||
platform/android/java/project.properties
|
||||
platform/android/java/AndroidManifest.xml
|
||||
platform/android/java/bin/*
|
||||
platform/android/java/libs/*
|
||||
platform/android/java/gen/*
|
||||
platform/android/java/assets
|
||||
platform/android/libs/apk_expansion/bin/*
|
||||
platform/android/libs/apk_expansion/gen/*
|
||||
platform/android/libs/google_play_services/bin/*
|
||||
platform/android/libs/google_play_services/gen/*
|
||||
platform/android/libs/play_licensing/bin/*
|
||||
platform/android/libs/play_licensing/gen/*
|
||||
|
||||
# General c++ generated files
|
||||
*.lib
|
||||
@ -32,50 +58,27 @@ platform/android/java/assets
|
||||
*.os
|
||||
*.Plo
|
||||
*.lo
|
||||
*.Po
|
||||
|
||||
# Libs generated files
|
||||
.deps/*
|
||||
.dirstamp
|
||||
|
||||
# Gprof output
|
||||
gmon.out
|
||||
|
||||
# Vim temp files
|
||||
*.swo
|
||||
*.swp
|
||||
|
||||
# Qt project files
|
||||
# QT project files
|
||||
*.config
|
||||
*.creator
|
||||
*.creator.*
|
||||
*.files
|
||||
*.includes
|
||||
*.cflags
|
||||
*.cxxflags
|
||||
|
||||
# Eclipse CDT files
|
||||
.cproject
|
||||
.settings/
|
||||
*.pydevproject
|
||||
*.launch
|
||||
|
||||
# Geany/geany-plugins files
|
||||
*.geany
|
||||
.geanyprj
|
||||
|
||||
# Jetbrains IDEs
|
||||
.idea/
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
__MACOSX
|
||||
logs/
|
||||
|
||||
# for projects that use SCons for building: http://http://www.scons.org/
|
||||
.sconf_temp
|
||||
.sconsign*.dblite
|
||||
.sconsign.dblite
|
||||
*.pyc
|
||||
|
||||
|
||||
# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
@ -96,19 +99,11 @@ build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
*.debug
|
||||
*.dSYM
|
||||
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# Hints for improving IntelliSense, created together with VS project
|
||||
cpp.hint
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
@ -132,7 +127,6 @@ TestResult.xml
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.bak
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
@ -140,7 +134,6 @@ TestResult.xml
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
*.nib
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
@ -152,10 +145,6 @@ ipch/
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
*.VC.VC.opendb
|
||||
enc_temp_folder/
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
@ -248,20 +237,10 @@ ClientBin/
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
__pycache__/
|
||||
|
||||
# KDE
|
||||
.directory
|
||||
|
||||
#Kdevelop project files
|
||||
*.kdev4
|
||||
|
||||
# Xcode
|
||||
xcuserdata/
|
||||
*.xcscmblueprint
|
||||
*.xccheckout
|
||||
*.xcodeproj/*
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
@ -289,19 +268,11 @@ FakesAssemblies/
|
||||
# =========================
|
||||
|
||||
# Windows image file caches
|
||||
[Tt]humbs.db
|
||||
[Tt]humbs.db:encryptable
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Windows stackdumps
|
||||
*.stackdump
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
@ -313,7 +284,6 @@ logo.h
|
||||
TAGS
|
||||
!TAGS/
|
||||
tags
|
||||
*.tags
|
||||
!tags/
|
||||
gtags.files
|
||||
GTAGS
|
||||
@ -327,22 +297,3 @@ godot.creator.*
|
||||
|
||||
projects/
|
||||
platform/windows/godot_res.res
|
||||
|
||||
# Visual Studio 2017 and Visual Studio Code workspace folder
|
||||
/.vs
|
||||
/.vscode
|
||||
|
||||
# Visual Studio Code workspace file
|
||||
*.code-workspace
|
||||
|
||||
# Scons progress indicator
|
||||
.scons_node_count
|
||||
|
||||
# ccls cache (https://github.com/MaskRay/ccls)
|
||||
.ccls-cache/
|
||||
|
||||
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||
compile_commands.json
|
||||
|
||||
# Cppcheck
|
||||
*.cppcheck
|
||||
|
||||
118
.mailmap
118
.mailmap
@ -1,118 +0,0 @@
|
||||
Alexander Holland <alexander.holland@live.de>
|
||||
Alexander Holland <alexander.holland@live.de> <alexander.holland@haw-hamburg.de>
|
||||
Alexander Holland <alexander.holland@live.de> <AlexHolly>
|
||||
Andrea Catania <info@andreacatania.com>
|
||||
Andreas Haas <liu.gam3@gmail.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <hinsbart@gmail.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <hinsbart@users.noreply.github.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <entenflugstuhl@gmail.com>
|
||||
Anish Bhobe <anishbhobe@hotmail.com>
|
||||
Anutrix <numaanzaheerahmed@yahoo.com>
|
||||
Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com>
|
||||
Ariel Manzur <ariel@godotengine.org>
|
||||
Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org>
|
||||
Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com>
|
||||
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local>
|
||||
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini-2.local>
|
||||
Bastiaan Olij <mux213@gmail.com>
|
||||
Benjamin <mafortion.benjamin@gmail.com>
|
||||
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.de>
|
||||
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.org>
|
||||
Bruno Lourenço <madequa@users.noreply.github.com> <bmlourenco@gmail.com>
|
||||
Chaosus <chaosus89@gmail.com>
|
||||
Chris Bradfield <chris@kidscancode.org> <cb@scribe.net>
|
||||
Clay John <claynjohn@gmail.com>
|
||||
Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca>
|
||||
Dana Olson <dana@shineuponthee.com> <adolson@gmail.com>
|
||||
Daniel J. Ramirez <djrmuv@gmail.com>
|
||||
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
|
||||
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
|
||||
Fabian <supagu@gmail.com>
|
||||
Ferenc Arn <tagcup@yahoo.com>
|
||||
Ferenc Arn <tagcup@yahoo.com> <tagcup@users.noreply.github.com>
|
||||
Fredia Huya-Kouadio <fhuyakou@gmail.com>
|
||||
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.com>
|
||||
Geequlim <geequlim@gmail.com>
|
||||
Gilles Roudiere <gilles.roudiere@gmail.com>
|
||||
Gilles Roudiere <gilles.roudiere@gmail.com> <gilles.roudiere@laas.fr>
|
||||
Gordon MacPherson <gordon@gordonite.tech>
|
||||
Guilherme Felipe <guilhermefelipecgs@gmail.com>
|
||||
Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
|
||||
Hein-Pieter van Braam-Stewart <hp@tmm.cx>
|
||||
Hubert Jarosz <marqin.pl@gmail.com>
|
||||
Hubert Jarosz <marqin.pl@gmail.com> <marqin.pl+git@gmail.com>
|
||||
Hugo Locurcio <hugo.locurcio@hugo.pro> <hugo.l@openmailbox.org>
|
||||
Hugo Locurcio <hugo.locurcio@hugo.pro> <Calinou@users.noreply.github.com>
|
||||
Hugo Locurcio <hugo.locurcio@hugo.pro> Calinou <calinou@opmbx.org>
|
||||
Ian Bishop <ianb96@gmail.com>
|
||||
Ignacio Etcheverry <ignalfonsore@gmail.com>
|
||||
Ignacio Etcheverry <ignalfonsore@gmail.com> <neikeq@users.noreply.github.com>
|
||||
Ilaria Cislaghi <cislaghi.ilaria@gmail.com>
|
||||
Ilaria Cislaghi <cislaghi.ilaria@gmail.com> <ilaria.cislaghi@simedis.com>
|
||||
Indah Sylvia <ISylvox@yahoo.com>
|
||||
J08nY <johny@neuromancer.sk> <jancar.jj@gmail.com>
|
||||
J08nY <johny@neuromancer.sk> <J08nY@users.noreply.github.com>
|
||||
Jakub Grzesik <kubecz3k@gmail.com>
|
||||
Jérôme Gully <jerome.gully0@gmail.com>
|
||||
JFonS <joan.fonssanchez@gmail.com>
|
||||
Juan Linietsky <reduzio@gmail.com>
|
||||
Juan Linietsky <reduzio@gmail.com> <juan@godotengine.org>
|
||||
Juan Linietsky <reduzio@gmail.com> <juan@okamstudio.com>
|
||||
Juan Linietsky <reduzio@gmail.com> <reduz@Juans-MBP.fibertel.com.ar>
|
||||
Juan Linietsky <reduzio@gmail.com> <red@kyoko>
|
||||
Julian Murgia <the.straton@gmail.com>
|
||||
Kanabenki <lucien.menassol@gmail.com> <18357657+Kanabenki@users.noreply.github.com>
|
||||
Kelly Thomas <kelly.thomas@hotmail.com.au>
|
||||
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
|
||||
Leon Krause <lk@leonkrause.com> <eska@eska.me>
|
||||
Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
|
||||
Manuel Strey <manuel.strey@gmx.de>
|
||||
Marcelo Fernandez <marcelofg55@gmail.com>
|
||||
Marcin Zawiejski <dragmz@gmail.com>
|
||||
Mariano Javier Suligoy <marianognu.easyrpg@gmail.com>
|
||||
Mario Schlack <m4r10.5ch14ck@gmail.com>
|
||||
marxin <mliska@suse.cz>
|
||||
marynate <mary.w.nate@gmail.com> <marynate@github.com>
|
||||
Max Hilbrunner <m.hilbrunner@gmail.com>
|
||||
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
|
||||
Michael Alexsander <michaelalexsander@protonmail.com>
|
||||
Nathan Lovato <nathan@gdquest.com>
|
||||
Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com>
|
||||
Nils ANDRÉ-CHANG <nils@nilsand.re>
|
||||
Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com>
|
||||
Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt>
|
||||
Pedro J. Estébanez <pedrojrulez@gmail.com> <RandomShaper@users.noreply.github.com>
|
||||
Paul Batty <p_batty@hotmail.co.uk>
|
||||
Paul Batty <p_batty@hotmail.co.uk> <Paulb23@users.noreply.github.com>
|
||||
Pawel Kowal <pkowal1982@gmail.com> <pawel.kowal@javart.eu>
|
||||
Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
|
||||
Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com>
|
||||
Poommetee Ketson <poommetee@protonmail.com>
|
||||
Przemysław Gołąb (n-pigeon) <golab.przemyslaw@gmail.com>
|
||||
Rafał Mikrut <mikrutrafal54@gmail.com>
|
||||
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de>
|
||||
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com>
|
||||
Ramesh Ravone <ramesh.maran443@gmail.com>
|
||||
RaphaelHunter <raphael10241024@gmail.com>
|
||||
RaphaelHunter <raphael10241024@gmail.com> <Raphael10241024@gmail.com>
|
||||
RaphaelHunter <raphael10241024@gmail.com> <raphael20141024@gmail.com>
|
||||
Rémi Verschelde <rverschelde@gmail.com> <remi@verschelde.fr>
|
||||
Rhody Lugo <rhodylugo@gmail.com> <rhodylugo@me.com>
|
||||
Robin Hübner <profan@prfn.se> <robinhubner@gmail.com>
|
||||
romulox_x <romulox_x@yahoo.com>
|
||||
Ruslan Mustakov <r.mustakov@gmail.com> <ruslan.mustakov@xored.com>
|
||||
Saracen <SaracenOne@gmail.com>
|
||||
sheepandshepherd <sheepandshepherd@hotmail.com> <sheepandshepherd@users.noreply.github.com>
|
||||
Swarnim Arun <swarnimarun11@gmail.com>
|
||||
Theo Hallenius <redsymbzone@hotmail.com>
|
||||
Thomas Herzog <therzog@mail.de>
|
||||
Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com>
|
||||
Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com>
|
||||
Twarit <wtwarit@gmail.com>
|
||||
V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com>
|
||||
Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr>
|
||||
Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com>
|
||||
Will Nations <willnationsdev@gmail.com>
|
||||
yg2f <yoann@terminajones.com>
|
||||
Zak Stam <zakscomputers@hotmail.com>
|
||||
Zher Huei Lee <lee.zh.92@gmail.com>
|
||||
168
.travis.yml
168
.travis.yml
@ -1,140 +1,52 @@
|
||||
language: cpp
|
||||
|
||||
# OS config, depends on actual 'os' in build matrix
|
||||
dist: xenial
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
stages:
|
||||
- check
|
||||
- build
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
global:
|
||||
- SCONS_CACHE=$HOME/.scons_cache/$TRAVIS_BRANCH
|
||||
- SCONS_CACHE_LIMIT=1024
|
||||
- OPTIONS="debug_symbols=no verbose=yes progress=no builtin_libpng=yes"
|
||||
- secure: "uch9QszCgsl1qVbuzY41P7S2hWL2IiNFV4SbAYRCdi0oJ9MIu+pVyrQdpf3+jG4rH6j4Rffl+sN17Zz4dIDDioFL1JwqyCqyCyswR8uACC0Rr8gr4Mi3+HIRbv+2s2P4cIQq41JM8FJe84k9jLEMGCGh69w+ibCWoWs74CokYVA="
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $SCONS_CACHE
|
||||
- GODOT_TARGET=iphone
|
||||
- GODOT_TARGET=osx
|
||||
- GODOT_TARGET=x11
|
||||
- GODOT_TARGET=android
|
||||
- GODOT_TARGET=windows
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- name: Static checks (clang-format) + Documentation checks
|
||||
stage: check
|
||||
env: STATIC_CHECKS=yes
|
||||
os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-xenial-8
|
||||
packages:
|
||||
- clang-format-8
|
||||
exclude:
|
||||
- os: linux
|
||||
env: GODOT_TARGET=iphone
|
||||
- os: linux
|
||||
env: GODOT_TARGET=osx
|
||||
- os: linux
|
||||
env: GODOT_TARGET=android
|
||||
- os: osx
|
||||
env: GODOT_TARGET=x11
|
||||
- os: osx
|
||||
env: GODOT_TARGET=windows
|
||||
- compiler: gcc
|
||||
env: GODOT_TARGET=iphone
|
||||
- compiler: gcc
|
||||
env: GODOT_TARGET=osx
|
||||
- compiler: clang
|
||||
env: GODOT_TARGET=android
|
||||
- compiler: clang
|
||||
env: GODOT_TARGET=windows
|
||||
- compiler: clang
|
||||
env: GODOT_TARGET=x11
|
||||
|
||||
- name: Linux editor (debug, GCC 9, with Mono)
|
||||
stage: build
|
||||
env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="module_mono_enabled=yes mono_glue=no warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: gcc-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- mono
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- &gcc9_deps [gcc-9, g++-9]
|
||||
- &linux_deps [libasound2-dev, libgl1-mesa-dev, libglu1-mesa-dev, libx11-dev, libxcursor-dev, libxi-dev, libxinerama-dev, libxrandr-dev]
|
||||
- &linux_mono_deps [mono-devel, msbuild, nuget]
|
||||
|
||||
- name: Linux export template (release, Clang)
|
||||
stage: build
|
||||
env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- *linux_deps
|
||||
|
||||
- name: Android export template (release_debug, Clang)
|
||||
stage: build
|
||||
env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- openjdk-8-jdk
|
||||
|
||||
- name: macOS editor (debug, Clang)
|
||||
stage: build
|
||||
env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang EXTRA_ARGS="warnings=extra werror=yes"
|
||||
os: osx
|
||||
compiler: clang
|
||||
|
||||
- name: iOS export template (debug, Clang)
|
||||
stage: build
|
||||
env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang
|
||||
os: osx
|
||||
compiler: clang
|
||||
|
||||
- name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running)
|
||||
stage: build
|
||||
env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes" TEST_PROJECT=yes
|
||||
os: linux
|
||||
compiler: gcc-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- *gcc9_deps
|
||||
- *linux_deps
|
||||
|
||||
- name: Linux export template (release_debug, GCC 5, without 3D support)
|
||||
stage: build
|
||||
env: PLATFORM=x11 TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-5 EXTRA_ARGS="CXXFLAGS=-fno-strict-aliasing disable_3d=yes"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- *linux_deps
|
||||
|
||||
before_install:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- if [ "$STATIC_CHECKS" = "yes" ]; then
|
||||
unset SCONS_CACHE;
|
||||
fi
|
||||
|
||||
install:
|
||||
- pip install --user scons;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$PLATFORM" = "android" ]; then
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64;
|
||||
export PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/bin:${PATH};
|
||||
java -version;
|
||||
misc/travis/android-tools-linux.sh;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
export PATH=${PATH}:/Users/travis/Library/Python/2.7/bin;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- if [ "$PLATFORM" = "android" ]; then
|
||||
export ANDROID_HOME=$TRAVIS_BUILD_DIR/godot-dev/build-tools/android-sdk;
|
||||
export ANDROID_NDK_ROOT=$TRAVIS_BUILD_DIR/godot-dev/build-tools/android-ndk;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; sudo apt-get install -y scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "windows" ]; then sudo apt-get update -qq; sudo apt-get install -y mingw32 mingw-w64; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then brew update; brew install android-sdk android-ndk; export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk; fi
|
||||
|
||||
script:
|
||||
- if [ "$STATIC_CHECKS" = "yes" ]; then
|
||||
sh ./misc/travis/clang-format.sh &&
|
||||
doc/tools/makerst.py --dry-run doc/classes modules;
|
||||
else
|
||||
scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS &&
|
||||
if [ "$TEST_PROJECT" = "yes" ]; then
|
||||
git clone --depth 1 "https://github.com/godotengine/godot-tests.git";
|
||||
sed -i "s:custom_template/release=\"\":custom_template/release=\"$(readlink -e bin/godot_server.x11.opt.tools.64)\":" godot-tests/tests/project_export/export_presets.cfg;
|
||||
godot-tests/tests/project_export/test_project.sh "bin/godot_server.x11.opt.tools.64";
|
||||
fi
|
||||
fi
|
||||
- scons platform=$GODOT_TARGET CXX=$CXX
|
||||
|
||||
176
AUTHORS.md
176
AUTHORS.md
@ -1,176 +0,0 @@
|
||||
# Godot Engine authors
|
||||
|
||||
Godot Engine is developed by a community of voluntary contributors who
|
||||
contribute code, bug reports, documentation, artwork, support, etc.
|
||||
|
||||
It is impossible to list them all; nevertheless, this file aims at listing
|
||||
the developers who contributed significant patches to this MIT licensed
|
||||
source code. "Significant" is arbitrarily decided, but should be fair :)
|
||||
|
||||
GitHub usernames are indicated in parentheses, or as sole entry when no other
|
||||
name is available.
|
||||
|
||||
## Project Founders
|
||||
|
||||
Juan Linietsky (reduz)
|
||||
Ariel Manzur (punto-)
|
||||
|
||||
## Lead Developer
|
||||
|
||||
Juan Linietsky (reduz)
|
||||
|
||||
## Project Manager
|
||||
|
||||
Rémi Verschelde (akien-mga)
|
||||
|
||||
## Developers
|
||||
|
||||
(in alphabetical order, with over 10 commits excluding merges)
|
||||
|
||||
Aaron Franke (aaronfranke)
|
||||
Alexander Holland (AlexHolly)
|
||||
Alexey Khoroshavin (allkhor)
|
||||
Alket Rexhepi (alketii)
|
||||
Andrea Catania (AndreaCatania)
|
||||
Andreas Haas (Hinsbart)
|
||||
Andrii Doroshenko (Xrayez)
|
||||
Andy Moss (MillionOstrich)
|
||||
Anish Bhobe (KidRigger)
|
||||
Anton Yabchinskiy (a12n)
|
||||
Anutrix
|
||||
Aren Villanueva (kurikaesu)
|
||||
Ariel Manzur (punto-)
|
||||
Bastiaan Olij (BastiaanOlij)
|
||||
Ben Brookshire (sheepandshepherd)
|
||||
Benjamin Larsson (Nallebeorn)
|
||||
Bernard Liebl (poke1024)
|
||||
Błażej Szczygieł (zaps166)
|
||||
Bojidar Marinov (bojidar-bg)
|
||||
Bruno Lourenço (MadEqua)
|
||||
bruvzg
|
||||
Cameron Reikes (creikey)
|
||||
Camille Mohr-Daurat (pouleyKetchoupp)
|
||||
Carl Olsson (not-surt)
|
||||
Carter Anderson (cart)
|
||||
Chris Bradfield (cbscribe)
|
||||
Clay John (clayjohn)
|
||||
Dana Olson (adolson)
|
||||
Daniel J. Ramirez (djrm)
|
||||
Daniel Rakos (aqnuep)
|
||||
dankan1890
|
||||
David Sichma (DavidSichma)
|
||||
Dharkael (lupoDharkael)
|
||||
Dmitry Koteroff (Krakean)
|
||||
DualMatrix
|
||||
Emmanuel Barroga (codecustard)
|
||||
Emmanuel Leblond (touilleMan)
|
||||
Eoin O'Neill (Eoin-ONeill-Yokai)
|
||||
Eric Lasota (elasota)
|
||||
Eric Rybicki (ericrybick)
|
||||
Erik Selecký (rxlecky)
|
||||
est31
|
||||
Fabian Mathews (supagu)
|
||||
Fabio Alessandrelli (Faless)
|
||||
Ferenc Arn (tagcup)
|
||||
Franklin Sobrinho (TheHX)
|
||||
Fredia Huya-Kouadio (m4gr3d)
|
||||
Geequlim
|
||||
George Marques (vnen)
|
||||
Gerrit Großkopf (Grosskopf)
|
||||
Gilles Roudiere (groud)
|
||||
Gordon MacPherson (RevoluPowered)
|
||||
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
|
||||
Hanif Bin Ariffin (hbina)
|
||||
Haoyu Qiu (timothyqiu)
|
||||
Hein-Pieter van Braam-Stewart (hpvb)
|
||||
Hiroshi Ogawa (hi-ogawa)
|
||||
homer666
|
||||
Hubert Jarosz (Marqin)
|
||||
Hugo Locurcio (Calinou)
|
||||
Ian Bishop (ianb96)
|
||||
Ibrahn Sahir (ibrahn)
|
||||
Ignacio Etcheverry (neikeq)
|
||||
Ilaria Cislaghi (QbieShay)
|
||||
Indah Sylvia (ISylvox)
|
||||
J08nY
|
||||
Jakub Grzesik (kubecz3k)
|
||||
Jérôme Gully (Nutriz)
|
||||
Joan Fons Sanchez (JFonS)
|
||||
Johan Manuel (29jm)
|
||||
Joshua Grams (JoshuaGrams)
|
||||
Juan Linietsky (reduz)
|
||||
Julian Murgia (StraToN)
|
||||
Justo Delgado (mrcdk)
|
||||
Kelly Thomas (KellyThomas)
|
||||
Kostadin Damyanov (Max-Might)
|
||||
K. S. Ernest (iFire) Lee (fire)
|
||||
Leon Krause (eska014)
|
||||
Lucien Menassol (Kanabenki)
|
||||
m4nu3lf
|
||||
Marcel Admiraal (madmiraal)
|
||||
Marcelo Fernandez (marcelofg55)
|
||||
Marc Gilleron (Zylann)
|
||||
Marcin Zawiejski (dragmz)
|
||||
Mariano Javier Suligoy (MarianoGnu)
|
||||
Mario Schlack (hurikhan)
|
||||
Martin Capitanio (capnm)
|
||||
Martin Liška (marxin)
|
||||
Martin Sjursen (binbitten)
|
||||
marynate
|
||||
Masoud BH (masoudbh3)
|
||||
Matthias Hölzl (hoelzl)
|
||||
Max Hilbrunner (mhilbrunner)
|
||||
merumelu
|
||||
Michael Alexsander (YeldhamDev)
|
||||
MichiRecRoom (LikeLakers2)
|
||||
mrezai
|
||||
Nathan Warden (NathanWarden)
|
||||
Nils André-Chang (NilsIrl)
|
||||
Nuno Donato (nunodonato)
|
||||
Ovnuniarchos
|
||||
Pascal Richter (ShyRed)
|
||||
Patrick (firefly2442)
|
||||
Paul Batty (Paulb23)
|
||||
Paul Joannon (paulloz)
|
||||
Paul Trojahn (ptrojahn)
|
||||
Pawel Kowal (pkowal1982)
|
||||
Pedro J. Estébanez (RandomShaper)
|
||||
Pieter-Jan Briers (PJB3005)
|
||||
Poommetee Ketson (Noshyaar)
|
||||
Przemysław Gołąb (n-pigeon)
|
||||
Rafał Mikrut (qarmin)
|
||||
Ralf Hölzemer (rollenrolm)
|
||||
Ramesh Ravone (RameshRavone)
|
||||
raphael10241024
|
||||
Ray Koopa (RayKoopa)
|
||||
Rémi Verschelde (akien-mga)
|
||||
Rhody Lugo (rraallvv)
|
||||
Roberto F. Arroyo (robfram)
|
||||
Robin Hübner (profan)
|
||||
romulox-x
|
||||
Ruslan Mustakov (endragor)
|
||||
Saniko (sanikoyes)
|
||||
santouits
|
||||
SaracenOne
|
||||
sersoong
|
||||
Shiqing (kawa-yoiko)
|
||||
Simon Wenner (swenner)
|
||||
Swarnim Arun (minraws)
|
||||
Theo Hallenius (TheoXD)
|
||||
Thomas Herzog (karroffel)
|
||||
Timo Schwarzer (timoschwarzer)
|
||||
Timo (toger5)
|
||||
Tomasz Chabora (KoBeWi)
|
||||
Twarit Waikar (IronicallySerious)
|
||||
Vinzenz Feenstra (vinzenz)
|
||||
박한얼 (volzhs)
|
||||
V. Vamsi Krishna (vkbsb)
|
||||
Wilhem Barbier (nounoursheureux)
|
||||
Will Nations (willnationsdev)
|
||||
Wilson E. Alvarez (Rubonnek)
|
||||
Xavier Cho (mysticfall)
|
||||
yg2f (SuperUserNameMan)
|
||||
Yuri Roubinsky (Chaosus)
|
||||
Zak Stam (zaksnet)
|
||||
Zher Huei Lee (leezh)
|
||||
ZuBsPaCe
|
||||
1123
CHANGELOG.md
1123
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
||||
# Code of Conduct
|
||||
|
||||
By participating in this repository, you agree to abide by the
|
||||
[Godot Engine Code of Conduct](https://godotengine.org/code-of-conduct).
|
||||
166
CONTRIBUTING.md
166
CONTRIBUTING.md
@ -1,186 +1,58 @@
|
||||
# How to contribute efficiently
|
||||
|
||||
Sections covered in this file:
|
||||
|
||||
* [Reporting bugs or proposing features](#reporting-bugs-or-proposing-features)
|
||||
* [Contributing pull requests](#contributing-pull-requests)
|
||||
* [Contributing to Godot's translation](#contributing-to-godots-translation)
|
||||
* [Communicating with developers](#communicating-with-developers)
|
||||
|
||||
**Please read the first section before reporting a bug!**
|
||||
|
||||
## Reporting bugs or proposing features
|
||||
|
||||
The golden rule is to **always open *one* issue for *one* bug**. If you notice
|
||||
several bugs and want to report them, make sure to create one new issue for
|
||||
each of them.
|
||||
The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
|
||||
|
||||
Everything referred to hereafter as "bug" also applies for feature requests.
|
||||
Everything refered to hereafter as "bug" also applies for feature requests.
|
||||
|
||||
If you are reporting a new issue, you will make our life much simpler (and the
|
||||
fix come much sooner) by following these guidelines:
|
||||
If you are reporting a new issue, you will make our life much simpler (and the fix come much sooner) by following those guidelines:
|
||||
|
||||
#### Search first in the existing database
|
||||
|
||||
Issues are often reported several times by various users. It's a good practice
|
||||
to **search first** in the issues database before reporting your issue. If you
|
||||
don't find a relevant match or if you are unsure, don't hesitate to **open a
|
||||
new issue**. The bugsquad will handle it from there if it's a duplicate.
|
||||
Issues are often reported several times by various users. It's a good practice to **search first** in the issues database before reporting your issue. If you don't find a relevant match or if you are unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
|
||||
|
||||
#### Specify the platform
|
||||
|
||||
Godot runs on a large variety of platforms and operating systems and devices.
|
||||
If you believe your issue is device/platform dependent (for example if it is
|
||||
related to the rendering, crashes or compilation errors), please specify:
|
||||
Godot runs on a large variety of platforms and operating systems and devices. If you believe your issue is device/platform dependent (for example if it is related to the rendering, crashes or compilation errors), please specify:
|
||||
* Operating system
|
||||
* Device (including architecture, e.g. x86, x86_64, arm, etc.)
|
||||
* GPU model (and driver in use if you know it)
|
||||
|
||||
#### Specify steps to reproduce
|
||||
|
||||
Many bugs can't be reproduced unless specific steps are taken. Please **specify
|
||||
the exact steps** that must be taken to reproduce the condition, and try to
|
||||
keep them as minimal as possible.
|
||||
Many bugs can't be reproduced unless specific steps are taken. Please **specify the exact steps** that must be taken to reproduce the condition, and try to keep them as minimal as possible.
|
||||
|
||||
#### Provide a simple, example project
|
||||
|
||||
Sometimes an unexpected behavior happens in your project. In such case,
|
||||
understand that:
|
||||
* What happens to you may not happen to other users.
|
||||
* We can't take the time to look at your project, understand how it is set up
|
||||
and then figure out why it's failing.
|
||||
Sometimes an unexpected behavior happens in your project. In such case, understand that:
|
||||
|
||||
To speed up our work, please prepare for us **a simple project** that isolates
|
||||
and reproduces the issue. This is always the **best way for us to fix it**.
|
||||
You can attach a zip file with the minimal project directly to the bug report,
|
||||
by drag and dropping the file in the GitHub edition field.
|
||||
* What happens to you may not happen to other users.
|
||||
* We can't take the time to look at your project, understand how it is set up and then figure out why it's failing.
|
||||
|
||||
To speed up our work, please prepare for us **a simple project** that isolates and reproduces the issue. This is always the **the best way for us to fix it**. You can attach a zip file with the minimal project directly to the bug report, by drag and dropping the file in the GitHub edition field.
|
||||
|
||||
## Contributing pull requests
|
||||
|
||||
If you want to add new engine functionalities, please make sure that:
|
||||
|
||||
* This functionality is desired, which means that it solves a common use case
|
||||
that several users will need in their real-life projects.
|
||||
* You talked to other developers on how to implement it best (on either
|
||||
communication channel, and maybe in a GitHub issue first before making your
|
||||
PR).
|
||||
* Even if it does not get merged, your PR is useful for future work by another
|
||||
developer.
|
||||
* This functionality is desired.
|
||||
* You talked to other developers on how to implement it best (on either communication channel, and maybe in a GitHub issue first before making your PR).
|
||||
* Even if it does not get merged, your PR is useful for future work by another developer.
|
||||
|
||||
Similar rules can be applied when contributing bug fixes - it's always best to
|
||||
discuss the implementation in the bug report first if you are not 100% about
|
||||
what would be the best fix.
|
||||
|
||||
[This blog post](https://godotengine.org/article/will-your-contribution-be-merged-heres-how-tell)
|
||||
outlines the process used by core developers when assessing PRs. We strongly
|
||||
recommend that you have a look at it to know what's important to take into
|
||||
account for a PR to be considered for merging.
|
||||
|
||||
In addition to the following tips, also take a look at the
|
||||
[Engine development guide](https://docs.godotengine.org/en/latest/development/cpp/)
|
||||
for an introduction to developing on Godot.
|
||||
|
||||
The [Contributing docs](https://docs.godotengine.org/en/latest/community/contributing/index.html)
|
||||
also have important information on the PR workflow and the code style we use.
|
||||
Similar rules can be applied when contributing bug fixes - it's always best to discuss the implementation in the bug report first if you are not 100% about what would be the best fix.
|
||||
|
||||
#### Be nice to the git history
|
||||
|
||||
Try to make simple PRs that handle one specific topic. Just like for reporting
|
||||
issues, it's better to open 3 different PRs that each address a different issue
|
||||
than one big PR with three commits.
|
||||
Try to make simple PRs with that handle one specific topic. Just like for reporting issues, it's better to open 3 different PRs that each address a different issue than one big PR with three commits.
|
||||
|
||||
When updating your fork with upstream changes, please use ``git pull --rebase``
|
||||
to avoid creating "merge commits". Those commits unnecessarily pollute the git
|
||||
history when coming from PRs.
|
||||
When updating your fork with upstream changes, please use ``git pull --rebase`` to avoid creating "merge commits". Those commits unnecessarily pollute the git history when coming from PRs.
|
||||
|
||||
Also try to make commits that bring the engine from one stable state to another
|
||||
stable state, i.e. if your first commit has a bug that you fixed in the second
|
||||
commit, try to merge them together before making your pull request (see ``git
|
||||
rebase -i`` and relevant help about rebasing or amending commits on the
|
||||
Internet).
|
||||
Also try to make commits that bring the engine from one stable state to another stable state, i.e. if your first commit has a bug that you fixed in the second commit, try to merge them together before making your pull request (see ``git rebase -i`` and relevant help about rebasing or ammending commits on the Internet).
|
||||
|
||||
This git style guide has some good practices to have in mind:
|
||||
[Git Style Guide](https://github.com/agis-/git-style-guide)
|
||||
|
||||
See our [PR workflow](https://docs.godotengine.org/en/latest/community/contributing/pr_workflow.html)
|
||||
documentation for tips on using Git, amending commits and rebasing branches.
|
||||
|
||||
#### Format your commit logs with readability in mind
|
||||
|
||||
The way you format your commit logs is quite important to ensure that the
|
||||
commit history and changelog will be easy to read and understand. A git commit
|
||||
log is formatted as a short title (first line) and an extended description
|
||||
(everything after the first line and an empty separation line).
|
||||
|
||||
The short title is the most important part, as it is what will appear in the
|
||||
`shortlog` changelog (one line per commit, so no description shown) or in the
|
||||
GitHub interface unless you click the "expand" button. As the name tells it,
|
||||
try to keep that first line relatively short (ideally <= 50 chars, though it's
|
||||
rare to be able to tell enough in so few characters, so you can go a bit
|
||||
higher) - it should describe what the commit does globally, while details would
|
||||
go in the description. Typically, if you can't keep the title short because you
|
||||
have too much stuff to mention, it means that you should probably split your
|
||||
changes in several commits :)
|
||||
|
||||
Here's an example of a well-formatted commit log (note how the extended
|
||||
description is also manually wrapped at 80 chars for readability):
|
||||
|
||||
```
|
||||
Prevent French fries carbonization by fixing heat regulation
|
||||
|
||||
When using the French fries frying module, Godot would not regulate the heat
|
||||
and thus bring the oil bath to supercritical liquid conditions, thus causing
|
||||
unwanted side effects in the physics engine.
|
||||
|
||||
By fixing the regulation system via an added binding to the internal feature,
|
||||
this commit now ensures that Godot will not go past the ebullition temperature
|
||||
of cooking oil under normal atmospheric conditions.
|
||||
|
||||
Fixes #1789, long live the Realm!
|
||||
```
|
||||
|
||||
*Note:* When using the GitHub online editor (or worse, the drag and drop
|
||||
feature), *please* edit the commit title to something meaningful. Commits named
|
||||
"Update my_file.cpp" will not be accepted.
|
||||
|
||||
## Contributing to Godot's translation
|
||||
|
||||
You can contribute to Godot's translation from the [Hosted
|
||||
Weblate](https://hosted.weblate.org/projects/godot-engine/godot), an open
|
||||
source and web-based translation platform. Please refer to the [translation
|
||||
readme](editor/translations/README.md) for more information.
|
||||
|
||||
You can also help translate [Godot's
|
||||
documentation](https://hosted.weblate.org/projects/godot-engine/godot-docs/)
|
||||
on Weblate.
|
||||
|
||||
## Communicating with developers
|
||||
|
||||
The Godot Engine community has [many communication
|
||||
channels](https://godotengine.org/community), some used more for user-level
|
||||
discussions and support, others more for development discussions.
|
||||
|
||||
To communicate with developers (e.g. to discuss a feature you want to implement
|
||||
or a bug you want to fix), the following channels can be used:
|
||||
- [GitHub issues](https://github.com/godotengine/godot/issues): If there is an
|
||||
existing issue about a topic you want to discuss, just add a comment to it -
|
||||
all developers watch the repository and will get an email notification. You
|
||||
can also create a new issue - please keep in mind to create issues only to
|
||||
discuss quite specific points about the development, and not general user
|
||||
feedback or support requests.
|
||||
- [#godotengine-devel IRC channel on
|
||||
Freenode](https://webchat.freenode.net/?channels=godotengine-devel): You will
|
||||
find most core developers there, so it's the go-to channel for direct chat
|
||||
about Godot Engine development. Feel free to start discussing something there
|
||||
to get some early feedback before writing up a detailed proposal in a GitHub
|
||||
issue.
|
||||
- [devel@godotengine.org mailing
|
||||
list](https://listengine.tuxfamily.org/godotengine.org/devel/): Mailing list
|
||||
for Godot developers, used primarily to announce developer meetings on IRC
|
||||
and other important discussions that need to reach people directly in their
|
||||
mailbox. See the [index
|
||||
page](https://listengine.tuxfamily.org/godotengine.org/devel/) for
|
||||
subscription instructions.
|
||||
This git style guide has some good practices to have in mind: https://github.com/agis-/git-style-guide
|
||||
|
||||
Thanks!
|
||||
|
||||
|
||||
1516
COPYRIGHT.txt
1516
COPYRIGHT.txt
File diff suppressed because it is too large
Load Diff
498
DONORS.md
498
DONORS.md
@ -1,498 +0,0 @@
|
||||
# Donors to the Godot Engine project
|
||||
|
||||
Godot Engine is a non-profit project developed by a community of voluntary
|
||||
contributors, as well as occasional paid contributors thanks to the financial
|
||||
support of generous donors.
|
||||
|
||||
The ways to donate to the project, as well as details on how the funds are
|
||||
used, are described on [Godot's website](https://godotengine.org/donate).
|
||||
|
||||
The following is a list of the current monthly donors, to be have their
|
||||
generous deed immortalized in the next stable release of Godot Engine.
|
||||
|
||||
## Platinum sponsors
|
||||
|
||||
Heroic Labs <https://heroiclabs.com>
|
||||
Interblock <http://interblockgaming.com>
|
||||
|
||||
## Gold sponsors
|
||||
|
||||
Gamblify <https://www.gamblify.com>
|
||||
Moonwards <https://www.moonwards.com>
|
||||
|
||||
## Mini sponsors
|
||||
|
||||
AD Ford
|
||||
Alan Beauchamp
|
||||
Anand Mallik
|
||||
Andres Hernandez
|
||||
Andrew Dunai
|
||||
Brandon Lamb
|
||||
Christopher Montesano
|
||||
Darkhan Baimyrza
|
||||
Edward Flick
|
||||
Gamechuck
|
||||
GameDev.net
|
||||
GameDev.tv
|
||||
Grady
|
||||
Hein-Pieter van Braam
|
||||
Jacob McKenney
|
||||
Javary Co.
|
||||
Jeffery Chiu
|
||||
Justin Arnold
|
||||
Justo Delgado Baudí
|
||||
Kyle Szklenski
|
||||
Leonard Meagher
|
||||
Mariano Suligoy
|
||||
Matthieu Huvé
|
||||
Maxim Karsten
|
||||
Mike King
|
||||
Nathan Warden
|
||||
Neal Gompa (Conan Kudo)
|
||||
Slobodan Milnovic
|
||||
Stephan Lanfermann
|
||||
Steve
|
||||
Tristan Pemble
|
||||
VilliHaukka
|
||||
|
||||
## Gold donors
|
||||
|
||||
Andrei
|
||||
Dave
|
||||
David Gehrig
|
||||
David Snopek
|
||||
Ed Morley
|
||||
Florian Krick
|
||||
Florian Rämisch
|
||||
Jakub Grzesik
|
||||
Manuele Finocchiaro
|
||||
Officine Pixel S.n.c.
|
||||
Retro Village
|
||||
Ronan Zeegers
|
||||
Sofox
|
||||
Taylor Ritenour
|
||||
Zaven Muradyan
|
||||
|
||||
Asher Glick
|
||||
Austen McRae
|
||||
Bernhard Werner
|
||||
beVR
|
||||
Brian van der Stel
|
||||
Carlo Cabanilla
|
||||
Daniel James
|
||||
David Giardi
|
||||
Default Name
|
||||
Florian Breisch
|
||||
Gamejunkey
|
||||
Javier Roman
|
||||
Jay Horton
|
||||
Joel Höglund
|
||||
Jon Woodward
|
||||
Jose Fernando Alexandre
|
||||
Karl Werf
|
||||
Klavdij Voncina
|
||||
Lex Steers
|
||||
Luke
|
||||
Maciej Pendolski
|
||||
Matthew Hillier
|
||||
Mohamed Ikbel Boulabiar
|
||||
Mored1984
|
||||
Péter Magyar
|
||||
Rob Messick
|
||||
Ryan Badour
|
||||
Scott Wadden
|
||||
Sergey
|
||||
Shawn Yu
|
||||
thechris
|
||||
Tom Langwaldt
|
||||
tukon
|
||||
William Wold
|
||||
|
||||
Alex Khayrullin
|
||||
Chris Goddard
|
||||
Chris Serino
|
||||
Christian Padilla
|
||||
Conrad Curry
|
||||
Craig Smith
|
||||
Darrian Little
|
||||
Ivan Trombley
|
||||
Jakub Dering
|
||||
Joan Fons
|
||||
Joshua Flores
|
||||
Krzysztof Jankowski
|
||||
Lord Bloodhound
|
||||
Pascal Grüter
|
||||
Petr Malac
|
||||
Rami
|
||||
Reneator
|
||||
Rob
|
||||
Robert Willes
|
||||
Ronnie Ashlock
|
||||
Thomas Bjarnelöf
|
||||
Unseen Domains
|
||||
Valryia
|
||||
Vincent Henderson
|
||||
Wojciech Chojnacki
|
||||
Xavier PATRICELLI
|
||||
|
||||
Adam Neumann
|
||||
Alexander J Maynard
|
||||
Alexey Dyadchenko
|
||||
Andreas Funke
|
||||
André Frélicot
|
||||
Andrew Bowen
|
||||
aoshiwik
|
||||
Carlos de Sousa Marques
|
||||
Chase Taranto
|
||||
Chris Petrich
|
||||
Christian Leth Jeppesen
|
||||
Christoph Schröder
|
||||
Cody Parker
|
||||
Craig Ostrin
|
||||
D
|
||||
Daniel Eichler
|
||||
David White
|
||||
Eric Monson
|
||||
Eugenio Hugo Salgüero Jáñez
|
||||
Fain
|
||||
flesk
|
||||
gavlig
|
||||
GGGames.org
|
||||
Guilherme Felipe de C. G. da Silva
|
||||
Heath Hayes
|
||||
Hysteria
|
||||
Idzard Kwadijk
|
||||
Jared White
|
||||
Jeff Nyte
|
||||
Jeremy Sims
|
||||
Jerry Ling
|
||||
Joe Flood
|
||||
Jose Malheiro
|
||||
Joshua Lesperance
|
||||
Juan Velandia
|
||||
Juraj Móza
|
||||
Kasper Jeppesen
|
||||
kinfox
|
||||
Marcelo Dornbusch Lopes
|
||||
Markus Fehr
|
||||
Markus Wiesner
|
||||
Martin Eigel
|
||||
Marvin
|
||||
Matt Eunson
|
||||
Max Bulai
|
||||
MuffinManKen
|
||||
Nick Nikitin
|
||||
Oliver Dick
|
||||
Patrick Ting
|
||||
Paul Hocker
|
||||
Paul Von Zimmerman
|
||||
Pete Goodwin
|
||||
pl
|
||||
Ranoller
|
||||
Robert Larnach
|
||||
Robin Arys
|
||||
Rocknight Studios
|
||||
Romildo Franco
|
||||
Ryan
|
||||
Samuel Judd
|
||||
Scott Pilet
|
||||
spilldata
|
||||
Stoned Xander
|
||||
TheLevelOfDetail .
|
||||
Thomas Krampl
|
||||
Thomas Kurz
|
||||
Tobias Bocanegra
|
||||
Urho
|
||||
Zie Weaver
|
||||
蕭惟允
|
||||
|
||||
## Silver donors
|
||||
|
||||
1D_Inc
|
||||
Abraham Haskins
|
||||
Adam
|
||||
Adam Brunnmeier
|
||||
Adam Carr
|
||||
Adam Long
|
||||
Adam Nakonieczny
|
||||
Adam N Webber
|
||||
Adam Smeltzer
|
||||
Adam Szymański
|
||||
Adisibio
|
||||
Adrian Demetrescu
|
||||
Agustinus Arya
|
||||
Aidan O'Flannagain
|
||||
Aki Mimoto
|
||||
Albin Jonasson Svärdsby
|
||||
Alder Stefano
|
||||
Alessandro Senese
|
||||
alex clavelle
|
||||
Alex Davies-Moore
|
||||
Allen Schade
|
||||
Andreas Evers
|
||||
Andreas Krampitz
|
||||
André Simões
|
||||
Andrew Thomas
|
||||
Andrzej Skalski
|
||||
Angelos Arnaoutis
|
||||
Anthony Staunton
|
||||
AP Condomines
|
||||
Arda Erol
|
||||
Arseniy M
|
||||
Arthur S. Muszynski
|
||||
Asger
|
||||
Aubrey Falconer
|
||||
Avencherus
|
||||
B A
|
||||
Balázs Batári
|
||||
Benedikt
|
||||
Ben G
|
||||
Ben Phelan
|
||||
Ben Vercammen
|
||||
Bernd Jänichen
|
||||
Black Block
|
||||
Blair Allen
|
||||
Bobby CC Wong
|
||||
Bryan Stevenson
|
||||
Carl van der Geest
|
||||
Carwyn Edwards
|
||||
Casey M.
|
||||
Chris Brown
|
||||
Chris Chapin
|
||||
Christian Baune
|
||||
Christian Winter
|
||||
Christoffer Sundbom
|
||||
Christopher Schmitt
|
||||
Christoph Woinke
|
||||
Clay Heaton
|
||||
Collin Shooltz
|
||||
Daniel Johnson
|
||||
Daniel Kimblad
|
||||
DanielMaximiano
|
||||
Daniel Pontillo
|
||||
Daniel Reed
|
||||
David May
|
||||
David Rapisarda
|
||||
David Woodard
|
||||
Dennis Idzikowsky
|
||||
Dominic Cooney
|
||||
Dominik Wetzel
|
||||
Donn Eddy
|
||||
Donovan Hutcheon
|
||||
Dragontrapper
|
||||
Dr Ewan Murray
|
||||
Duobix
|
||||
Duodecimal
|
||||
Dylan Todd
|
||||
Eduardo Teixeira
|
||||
Edward Herbert
|
||||
Egon Elbre
|
||||
Elmeri '- Duy Kevin Nguyen
|
||||
Eric Ellingson
|
||||
Eric Williams
|
||||
Erkki Seppälä
|
||||
Evan Rose
|
||||
Fancy Ants Studios
|
||||
Fekinox
|
||||
Felix Kollmann
|
||||
fengjiongmax
|
||||
Flaredown
|
||||
Forty Doubleu
|
||||
FuDiggity
|
||||
G3Dev sàrl
|
||||
Gadzhi Kharkharov
|
||||
gamedev by Celio
|
||||
Gary Hulst
|
||||
George Marques
|
||||
GiulianoB
|
||||
Greg Olson
|
||||
GREGORY C FEIN
|
||||
Greg P
|
||||
Greyson Richey
|
||||
Guldoman
|
||||
Hal A
|
||||
Heribert Hirth
|
||||
Hunter Jones
|
||||
Hylpher
|
||||
Iiari
|
||||
IndustrialRobot
|
||||
Isaac Morton
|
||||
Jaiden Gerig
|
||||
Jaime Ruiz-Borau Vizárraga
|
||||
Jako Danar
|
||||
James A F Manley
|
||||
Jannik Gröger
|
||||
Jax
|
||||
Jeff Hungerford
|
||||
Jennifer Graves
|
||||
Jeremy Kahn
|
||||
Jesse Dubay
|
||||
Joe Alden
|
||||
Joel Fivat
|
||||
Joel Setterberg
|
||||
Johannes Wuensch
|
||||
Jomei Jackson
|
||||
Jonas Rudlang
|
||||
Jonas Yamazaki
|
||||
Jonathan G
|
||||
Jonathon
|
||||
Jon Bonazza
|
||||
Jon Sully
|
||||
Jose Aleman
|
||||
Jose C. Rubio
|
||||
Joseph Catrambone
|
||||
Juanfran
|
||||
Judd
|
||||
Julian Murgia
|
||||
JungleRobba
|
||||
Justin Spedding
|
||||
Kaiser Bald0
|
||||
Kauzig
|
||||
KC Chan
|
||||
Keedong Park
|
||||
Keith Bradner
|
||||
Kevin McPhillips
|
||||
kickmaniac
|
||||
Kiyohiro Kawamura (kyorohiro)
|
||||
Kjetil Haugland
|
||||
Klagsam
|
||||
Klassix
|
||||
KR McGinley
|
||||
KsyTek Games
|
||||
Kuan Cheang
|
||||
kycho
|
||||
Leonardo Dimano
|
||||
Levi Lindsey
|
||||
Linus Lind Lundgren
|
||||
Lionel Gaillard
|
||||
LunaticInAHat
|
||||
Lurkars
|
||||
Major Haul
|
||||
Malcolm
|
||||
Malik Ahmed
|
||||
Malik Nejer
|
||||
Marcus Richter
|
||||
Markus Michael Egger
|
||||
Martin Holas
|
||||
Martin Liška
|
||||
Matthew Little
|
||||
Matti Pohjanvirta
|
||||
Maxime Blade
|
||||
Maxwell
|
||||
medecau
|
||||
Melissa Mears
|
||||
M H
|
||||
mhilbrunner
|
||||
Michael Dürwald
|
||||
Michael Gringauz
|
||||
Michael Haney
|
||||
Michael Labbe
|
||||
Mikael Olsson
|
||||
Mikayla
|
||||
Mike Birkhead
|
||||
Mitchell J. Wagner
|
||||
MoM
|
||||
Nathan Fish
|
||||
Natrim
|
||||
nee
|
||||
Neil Blakey-Milner
|
||||
Neil Wang
|
||||
Nerdforge
|
||||
Nicholas
|
||||
Nick Macholl
|
||||
Niclas Eriksen
|
||||
Nicolás Montaña
|
||||
Nicolas SAN AGUSTIN
|
||||
Nima Farid
|
||||
NZ
|
||||
Oleg Reva
|
||||
Olivier
|
||||
Omar Delarosa
|
||||
Oscar Norlander
|
||||
Pan Ip
|
||||
Patrick Nafarrete
|
||||
Paul Gieske
|
||||
Paul Mason
|
||||
Paweł Kowal
|
||||
Pedro Assuncao
|
||||
Penguin
|
||||
Petrus Prinsloo
|
||||
Philip Cohoe
|
||||
Pierre-Igor Berthet
|
||||
Pitsanu Tongprasin
|
||||
Point08
|
||||
Poryg
|
||||
Rad Cat
|
||||
Rafa Laguna
|
||||
rainerLinux
|
||||
Raphael Leroux
|
||||
Remi Rampin
|
||||
Rémi Verschelde
|
||||
Ricardo Alcantara
|
||||
Richard Diss
|
||||
Richard Ivánek
|
||||
Richard Patching
|
||||
Robert Farr (Larington)
|
||||
Robert Hernandez
|
||||
Rodrigo Loli
|
||||
Roger Smith
|
||||
Roland Rząsa
|
||||
Roman Tinkov
|
||||
Ronan
|
||||
Ryan Groom
|
||||
Ryan Hentz
|
||||
Sam.C
|
||||
Sam Edson
|
||||
Samuele Zolfanelli
|
||||
Sasori Olkof
|
||||
Scott D. Yelich
|
||||
Sebastian Michailidis
|
||||
sgnsajgon
|
||||
Shane
|
||||
Shane Sicienski
|
||||
Shane Spoor
|
||||
Simon Wenner
|
||||
SK
|
||||
smbe19
|
||||
Stonepyre
|
||||
Svenne Krap
|
||||
tezuvholovdr
|
||||
thomas
|
||||
Thomas Bechtold
|
||||
Thomas Kelly
|
||||
tiansheng li
|
||||
Tim Drumheller
|
||||
Timothy B. MacDonald
|
||||
tinyBigGames LLC
|
||||
Tobbun
|
||||
Tom Fulp
|
||||
Tom Glenn
|
||||
Torsten Crass
|
||||
Travis O'Brien
|
||||
Trent Skinner
|
||||
Troy Bonneau
|
||||
Tryggve Sollid
|
||||
Turgut Temucin
|
||||
Tyler Compton
|
||||
Tyler Stafos
|
||||
UltyX
|
||||
Vaiktorg
|
||||
Vaughan Ling
|
||||
Victor
|
||||
Vigilant Watch
|
||||
Vincent Cloutier
|
||||
waka nya
|
||||
Wayne Haak
|
||||
werner mendizabal
|
||||
Wiley Thompson
|
||||
Will
|
||||
William Hogben
|
||||
Wout Standaert
|
||||
Wyatt Goodin
|
||||
Yegor
|
||||
Yuri Sizov
|
||||
|
||||
## Bronze donors
|
||||
|
||||
There are even more donors that support the project with a small monthly donation.
|
||||
Every bit counts and we thank every one of them for their amazing support!
|
||||
10
ISSUE_TEMPLATE
Normal file
10
ISSUE_TEMPLATE
Normal file
@ -0,0 +1,10 @@
|
||||
**Operating system or device:**
|
||||
|
||||
|
||||
**Issue description** (what happened, and what was expected):
|
||||
|
||||
|
||||
**Steps to reproduce:**
|
||||
|
||||
|
||||
**Link to minimal example project** (optional but very welcome):
|
||||
27
LICENSE.md
Normal file
27
LICENSE.md
Normal file
@ -0,0 +1,27 @@
|
||||
GODOT ENGINE
|
||||
http://www.godotengine.org
|
||||
|
||||
************************************************************************
|
||||
|
||||
Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
|
||||
|
||||
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, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
************************************************************************
|
||||
20
LICENSE.txt
20
LICENSE.txt
@ -1,20 +0,0 @@
|
||||
Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
|
||||
Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
|
||||
|
||||
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, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,3 +1,2 @@
|
||||
Godot Logo (C) Andrea Calabró
|
||||
Distributed under the terms of the Creative Commons Attribution License
|
||||
version 3.0 (CC-BY 3.0) <https://creativecommons.org/licenses/by/3.0/legalcode>.
|
||||
Godot Logo (c) Andrea Calabró, distributed under the terms of the CC By License:
|
||||
https://creativecommons.org/licenses/by/3.0/legalcode
|
||||
75
README.md
75
README.md
@ -1,72 +1,29 @@
|
||||
[](https://godotengine.org)
|
||||

|
||||
|
||||
## Godot Engine
|
||||
http://www.godotengine.org
|
||||
|
||||
Homepage: https://godotengine.org
|
||||
### The Engine
|
||||
|
||||
#### 2D and 3D cross-platform game engine
|
||||
Godot is a fully featured, open source, MIT licensed, game engine. It focuses on having great tools, and a visual oriented workflow that can export to PC, Mobile and Web platforms with no hassle.
|
||||
The editor, language and APIs are feature rich, yet simple to learn, allowing you to become productive in a matter of hours.
|
||||
|
||||
Godot Engine is a feature-packed, cross-platform game engine to create 2D and
|
||||
3D games from a unified interface. It provides a comprehensive set of common
|
||||
tools, so that users can focus on making games without having to reinvent the
|
||||
wheel. Games can be exported in one click to a number of platforms, including
|
||||
the major desktop platforms (Linux, Mac OSX, Windows) as well as mobile
|
||||
(Android, iOS) and web-based (HTML5) platforms.
|
||||
### About
|
||||
|
||||
#### Free, open source and community-driven
|
||||
Godot has been developed by Juan Linietsky and Ariel Manzur for several years, and was born as an in-house engine, used to publish several work-for-hire titles. Godot is a member project of the [Software Freedom Conservancy](https://sfconservancy.org)
|
||||
|
||||
Godot is completely free and open source under the very permissive MIT license.
|
||||
No strings attached, no royalties, nothing. The users' games are theirs, down
|
||||
to the last line of engine code. Godot's development is fully independent and
|
||||
community-driven, empowering users to help shape their engine to match their
|
||||
expectations. It is supported by the Software Freedom Conservancy
|
||||
not-for-profit.
|
||||
### Documentation
|
||||
|
||||
Before being open sourced in February 2014, Godot had been developed by Juan
|
||||
Linietsky and Ariel Manzur (both still maintaining the project) for several
|
||||
years as an in-house engine, used to publish several work-for-hire titles.
|
||||
Documentation has been moved to [ReadTheDocs](http://docs.godotengine.org).
|
||||
|
||||

|
||||
### Binary Downloads, Community, etc.
|
||||
|
||||
### Getting the engine
|
||||
Binary downloads, community, etc. can be found in Godot homepage:
|
||||
|
||||
#### Binary downloads
|
||||
http://www.godotengine.org
|
||||
|
||||
Official binaries for the Godot editor and the export templates can be found
|
||||
[on the homepage](https://godotengine.org/download).
|
||||
### Compiling from Source
|
||||
|
||||
#### Compiling from source
|
||||
Compilation instructions for every platform can be found in the Wiki:
|
||||
http://docs.godotengine.org/en/latest/reference/_compiling.html
|
||||
|
||||
[See the official docs](https://docs.godotengine.org/en/latest/development/compiling/)
|
||||
for compilation instructions for every supported platform.
|
||||
|
||||
### Community and contributing
|
||||
|
||||
Godot is not only an engine but an ever-growing community of users and engine
|
||||
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).
|
||||
|
||||
To get in touch with the developers, the best way is to join the
|
||||
[#godotengine IRC channel](https://webchat.freenode.net/?channels=godotengine)
|
||||
on Freenode.
|
||||
|
||||
To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).
|
||||
|
||||
### Documentation and demos
|
||||
|
||||
The official documentation is hosted on [ReadTheDocs](https://docs.godotengine.org).
|
||||
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).
|
||||
|
||||
The [class reference](https://docs.godotengine.org/en/latest/classes/)
|
||||
is also accessible from within the engine.
|
||||
|
||||
The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
|
||||
as well.
|
||||
|
||||
There are also a number of other learning resources provided by the community,
|
||||
such as text and video tutorials, demos, etc. Consult the [community channels](https://godotengine.org/community)
|
||||
for more info.
|
||||
|
||||
[](https://travis-ci.org/godotengine/godot)
|
||||
[](https://ci.appveyor.com/project/akien-mga/godot)
|
||||
[](https://www.codetriage.com/godotengine/godot)
|
||||
[](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
|
||||
[](https://travis-ci.org/godotengine/godot)
|
||||
|
||||
784
SConstruct
784
SConstruct
@ -1,17 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
EnsureSConsVersion(0,14);
|
||||
|
||||
EnsureSConsVersion(0, 98, 1)
|
||||
|
||||
# System
|
||||
import glob
|
||||
import string
|
||||
import os
|
||||
import pickle
|
||||
import os.path
|
||||
import glob
|
||||
import sys
|
||||
|
||||
# Local
|
||||
import methods
|
||||
import gles_builders
|
||||
from platform_methods import run_in_subprocess
|
||||
|
||||
methods.update_version()
|
||||
|
||||
# scan possible build platforms
|
||||
|
||||
@ -19,653 +16,404 @@ platform_list = [] # list of platforms
|
||||
platform_opts = {} # options for each platform
|
||||
platform_flags = {} # flags for each platform
|
||||
|
||||
active_platforms = []
|
||||
active_platform_ids = []
|
||||
platform_exporters = []
|
||||
platform_apis = []
|
||||
|
||||
for x in sorted(glob.glob("platform/*")):
|
||||
if (not os.path.isdir(x) or not os.path.exists(x + "/detect.py")):
|
||||
active_platforms=[]
|
||||
active_platform_ids=[]
|
||||
platform_exporters=[]
|
||||
global_defaults=[]
|
||||
|
||||
for x in glob.glob("platform/*"):
|
||||
if (not os.path.isdir(x)):
|
||||
continue
|
||||
tmppath = "./" + x
|
||||
tmppath="./"+x
|
||||
|
||||
sys.path.insert(0, tmppath)
|
||||
sys.path.append(tmppath)
|
||||
import detect
|
||||
|
||||
if (os.path.exists(x + "/export/export.cpp")):
|
||||
if (os.path.exists(x+"/export/export.cpp")):
|
||||
platform_exporters.append(x[9:])
|
||||
if (os.path.exists(x + "/api/api.cpp")):
|
||||
platform_apis.append(x[9:])
|
||||
if (os.path.exists(x+"/globals/global_defaults.cpp")):
|
||||
global_defaults.append(x[9:])
|
||||
if (detect.is_active()):
|
||||
active_platforms.append(detect.get_name())
|
||||
active_platform_ids.append(x)
|
||||
active_platforms.append( detect.get_name() )
|
||||
active_platform_ids.append(x);
|
||||
if (detect.can_build()):
|
||||
x = x.replace("platform/", "") # rest of world
|
||||
x = x.replace("platform\\", "") # win32
|
||||
platform_list += [x]
|
||||
platform_opts[x] = detect.get_opts()
|
||||
platform_flags[x] = detect.get_flags()
|
||||
x=x.replace("platform/","") # rest of world
|
||||
x=x.replace("platform\\","") # win32
|
||||
platform_list+=[x]
|
||||
platform_opts[x]=detect.get_opts()
|
||||
platform_flags[x]=detect.get_flags()
|
||||
sys.path.remove(tmppath)
|
||||
sys.modules.pop('detect')
|
||||
|
||||
module_list = methods.detect_modules()
|
||||
module_list=methods.detect_modules()
|
||||
|
||||
methods.save_active_platforms(active_platforms, active_platform_ids)
|
||||
|
||||
custom_tools = ['default']
|
||||
#print "Detected Platforms: "+str(platform_list)
|
||||
|
||||
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
|
||||
methods.save_active_platforms(active_platforms,active_platform_ids)
|
||||
|
||||
if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)):
|
||||
custom_tools = ['mingw']
|
||||
elif platform_arg == 'javascript':
|
||||
# Use generic POSIX build toolchain for Emscripten.
|
||||
custom_tools = ['cc', 'c++', 'ar', 'link', 'textfile', 'zip']
|
||||
custom_tools=['default']
|
||||
|
||||
env_base = Environment(tools=custom_tools)
|
||||
if 'TERM' in os.environ:
|
||||
env_base['ENV']['TERM'] = os.environ['TERM']
|
||||
env_base.AppendENVPath('PATH', os.getenv('PATH'))
|
||||
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
||||
env_base.disabled_modules = []
|
||||
env_base.use_ptrcall = False
|
||||
env_base.module_version_string = ""
|
||||
env_base.msvc = False
|
||||
platform_arg = ARGUMENTS.get("platform", False)
|
||||
|
||||
if (os.name=="posix"):
|
||||
pass
|
||||
elif (os.name=="nt"):
|
||||
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
|
||||
custom_tools=['mingw']
|
||||
|
||||
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
|
||||
|
||||
#env_base=Environment(tools=custom_tools);
|
||||
env_base.global_defaults=global_defaults
|
||||
env_base.android_maven_repos=[]
|
||||
env_base.android_dependencies=[]
|
||||
env_base.android_java_dirs=[]
|
||||
env_base.android_res_dirs=[]
|
||||
env_base.android_aidl_dirs=[]
|
||||
env_base.android_jni_dirs=[]
|
||||
env_base.android_manifest_chunk=""
|
||||
env_base.android_permission_chunk=""
|
||||
env_base.android_appattributes_chunk=""
|
||||
env_base.disabled_modules=[]
|
||||
|
||||
env_base.split_drivers=False
|
||||
|
||||
|
||||
|
||||
env_base.__class__.android_add_maven_repository=methods.android_add_maven_repository
|
||||
env_base.__class__.android_add_dependency=methods.android_add_dependency
|
||||
env_base.__class__.android_add_java_dir=methods.android_add_java_dir
|
||||
env_base.__class__.android_add_res_dir=methods.android_add_res_dir
|
||||
env_base.__class__.android_add_aidl_dir=methods.android_add_aidl_dir
|
||||
env_base.__class__.android_add_jni_dir=methods.android_add_jni_dir
|
||||
env_base.__class__.android_add_to_manifest = methods.android_add_to_manifest
|
||||
env_base.__class__.android_add_to_permissions = methods.android_add_to_permissions
|
||||
env_base.__class__.android_add_to_attributes = methods.android_add_to_attributes
|
||||
env_base.__class__.disable_module = methods.disable_module
|
||||
|
||||
env_base.__class__.add_module_version_string = methods.add_module_version_string
|
||||
|
||||
env_base.__class__.add_source_files = methods.add_source_files
|
||||
env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix
|
||||
env_base.__class__.split_lib = methods.split_lib
|
||||
|
||||
env_base.__class__.add_shared_library = methods.add_shared_library
|
||||
env_base.__class__.add_library = methods.add_library
|
||||
env_base.__class__.add_program = methods.add_program
|
||||
env_base.__class__.CommandNoCache = methods.CommandNoCache
|
||||
env_base.__class__.disable_warnings = methods.disable_warnings
|
||||
|
||||
env_base["x86_libtheora_opt_gcc"] = False
|
||||
env_base["x86_libtheora_opt_vc"] = False
|
||||
|
||||
# avoid issues when building with different versions of python out of the same directory
|
||||
env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))
|
||||
|
||||
# Build options
|
||||
env_base["x86_opt_gcc"]=False
|
||||
env_base["x86_opt_vc"]=False
|
||||
env_base["armv7_opt_gcc"]=False
|
||||
|
||||
customs = ['custom.py']
|
||||
|
||||
profile = ARGUMENTS.get("profile", False)
|
||||
if profile:
|
||||
import os.path
|
||||
if os.path.isfile(profile):
|
||||
customs.append(profile)
|
||||
elif os.path.isfile(profile + ".py"):
|
||||
customs.append(profile + ".py")
|
||||
elif os.path.isfile(profile+".py"):
|
||||
customs.append(profile+".py")
|
||||
|
||||
opts = Variables(customs, ARGUMENTS)
|
||||
|
||||
# Target build options
|
||||
opts.Add('arch', "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", '')
|
||||
opts.Add(EnumVariable('bits', "Target platform bits", 'default', ('default', '32', '64')))
|
||||
opts.Add('p', "Platform (alias for 'platform')", '')
|
||||
opts.Add('platform', "Target platform (%s)" % ('|'.join(platform_list), ), '')
|
||||
opts.Add(EnumVariable('target', "Compilation target", 'debug', ('debug', 'release_debug', 'release')))
|
||||
opts.Add(EnumVariable('optimize', "Optimization type", 'speed', ('speed', 'size')))
|
||||
opts.Add(BoolVariable('tools', "Build the tools (a.k.a. the Godot editor)", True))
|
||||
opts.Add(BoolVariable('use_lto', 'Use link-time optimization', False))
|
||||
opts.Add(BoolVariable('use_precise_math_checks', 'Math checks use very precise epsilon (useful to debug the engine)', False))
|
||||
|
||||
# Components
|
||||
opts.Add(BoolVariable('deprecated', "Enable deprecated features", True))
|
||||
opts.Add(BoolVariable('gdscript', "Enable GDScript support", True))
|
||||
opts.Add(BoolVariable('minizip', "Enable ZIP archive support using minizip", True))
|
||||
opts.Add(BoolVariable('xaudio2', "Enable the XAudio2 audio driver", False))
|
||||
|
||||
# Advanced options
|
||||
opts.Add(BoolVariable('verbose', "Enable verbose output for the compilation", False))
|
||||
opts.Add(BoolVariable('progress', "Show a progress indicator during compilation", True))
|
||||
opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during compilation", 'all', ('extra', 'all', 'moderate', 'no')))
|
||||
opts.Add(BoolVariable('werror', "Treat compiler warnings as errors. Depends on the level of warnings set with 'warnings'", False))
|
||||
opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=extra werror=yes", False))
|
||||
opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all generated binary files", '')
|
||||
opts.Add(BoolVariable('vsproj', "Generate a Visual Studio solution", False))
|
||||
opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
|
||||
opts.Add(BoolVariable('split_libmodules', "Split intermediate libmodules.a in smaller chunks to prevent exceeding linker command line size (forced to True when using MinGW)", False))
|
||||
opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for a smaller executable", False))
|
||||
opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced GUI nodes and behaviors", False))
|
||||
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
|
||||
opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
|
||||
|
||||
# Thirdparty libraries
|
||||
opts.Add(BoolVariable('builtin_bullet', "Use the built-in Bullet library", True))
|
||||
opts.Add(BoolVariable('builtin_certs', "Bundle default SSL certificates to be used if you don't specify an override in the project settings", True))
|
||||
opts.Add(BoolVariable('builtin_enet', "Use the built-in ENet library", True))
|
||||
opts.Add(BoolVariable('builtin_freetype', "Use the built-in FreeType library", True))
|
||||
opts.Add(BoolVariable('builtin_libogg', "Use the built-in libogg library", True))
|
||||
opts.Add(BoolVariable('builtin_libpng', "Use the built-in libpng library", True))
|
||||
opts.Add(BoolVariable('builtin_libtheora', "Use the built-in libtheora library", True))
|
||||
opts.Add(BoolVariable('builtin_libvorbis', "Use the built-in libvorbis library", True))
|
||||
opts.Add(BoolVariable('builtin_libvpx', "Use the built-in libvpx library", True))
|
||||
opts.Add(BoolVariable('builtin_libwebp', "Use the built-in libwebp library", True))
|
||||
opts.Add(BoolVariable('builtin_wslay', "Use the built-in wslay library", True))
|
||||
opts.Add(BoolVariable('builtin_mbedtls', "Use the built-in mbedTLS library", True))
|
||||
opts.Add(BoolVariable('builtin_miniupnpc', "Use the built-in miniupnpc library", True))
|
||||
opts.Add(BoolVariable('builtin_opus', "Use the built-in Opus library", True))
|
||||
opts.Add(BoolVariable('builtin_pcre2', "Use the built-in PCRE2 library", True))
|
||||
opts.Add(BoolVariable('builtin_pcre2_with_jit', "Use JIT compiler for the built-in PCRE2 library", True))
|
||||
opts.Add(BoolVariable('builtin_recast', "Use the built-in Recast library", True))
|
||||
opts.Add(BoolVariable('builtin_squish', "Use the built-in squish library", True))
|
||||
opts.Add(BoolVariable('builtin_xatlas', "Use the built-in xatlas library", True))
|
||||
opts.Add(BoolVariable('builtin_zlib', "Use the built-in zlib library", True))
|
||||
opts.Add(BoolVariable('builtin_zstd', "Use the built-in Zstd library", True))
|
||||
|
||||
# Compilation environment setup
|
||||
opts.Add("CXX", "C++ compiler")
|
||||
opts.Add("CC", "C compiler")
|
||||
opts.Add("LINK", "Linker")
|
||||
opts.Add("CCFLAGS", "Custom flags for both the C and C++ compilers")
|
||||
opts.Add("CFLAGS", "Custom flags for the C compiler")
|
||||
opts.Add("CXXFLAGS", "Custom flags for the C++ compiler")
|
||||
opts.Add("LINKFLAGS", "Custom flags for the linker")
|
||||
opts=Variables(customs, ARGUMENTS)
|
||||
opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug")
|
||||
opts.Add('bits', 'Compile Target Bits (default/32/64).', "default")
|
||||
opts.Add('platform','Platform: '+str(platform_list)+'.',"")
|
||||
opts.Add('p','Platform (same as platform=).',"")
|
||||
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
|
||||
opts.Add('gdscript','Build GDSCript support: (yes/no)','yes')
|
||||
opts.Add('vorbis','Build Ogg Vorbis Support: (yes/no)','yes')
|
||||
opts.Add('opus','Build Opus Audio Format Support: (yes/no)','yes')
|
||||
opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes')
|
||||
opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
|
||||
opts.Add('theora','Theora Video (yes/no)','yes')
|
||||
opts.Add('theoralib','Theora Video (yes/no)','no')
|
||||
opts.Add('freetype','Freetype support in editor','yes')
|
||||
opts.Add('speex','Speex Audio (yes/no)','yes')
|
||||
opts.Add('xml','XML Save/Load support (yes/no)','yes')
|
||||
opts.Add('png','PNG Image loader support (yes/no)','yes')
|
||||
opts.Add('jpg','JPG Image loader support (yes/no)','yes')
|
||||
opts.Add('webp','WEBP Image loader support (yes/no)','yes')
|
||||
opts.Add('dds','DDS Texture loader support (yes/no)','yes')
|
||||
opts.Add('pvr','PVR (PowerVR) Texture loader support (yes/no)','yes')
|
||||
opts.Add('etc1','etc1 Texture compression support (yes/no)','yes')
|
||||
opts.Add('builtin_zlib','Use built-in zlib (yes/no)','yes')
|
||||
opts.Add('openssl','Use OpenSSL (yes/no/builtin)','no')
|
||||
opts.Add('musepack','Musepack Audio (yes/no)','yes')
|
||||
opts.Add("CXX", "Compiler");
|
||||
opts.Add("CCFLAGS", "Custom flags for the C++ compiler");
|
||||
opts.Add("CFLAGS", "Custom flags for the C compiler");
|
||||
opts.Add("LINKFLAGS", "Custom flags for the linker");
|
||||
opts.Add('unix_global_settings_path', 'unix-specific path to system-wide settings. Currently only used by templates.','')
|
||||
opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no")
|
||||
opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no")
|
||||
opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no')
|
||||
opts.Add('extra_suffix', 'Custom extra suffix added to the base filename of all generated binary files.', '')
|
||||
opts.Add('vsproj', 'Generate Visual Studio Project. (yes/no)', 'no')
|
||||
|
||||
# add platform specific options
|
||||
|
||||
for k in platform_opts.keys():
|
||||
opt_list = platform_opts[k]
|
||||
for o in opt_list:
|
||||
opts.Add(o)
|
||||
opts.Add(o[0],o[1],o[2])
|
||||
|
||||
for x in module_list:
|
||||
module_enabled = True
|
||||
tmppath = "./modules/" + x
|
||||
sys.path.insert(0, tmppath)
|
||||
import config
|
||||
enabled_attr = getattr(config, "is_enabled", None)
|
||||
if (callable(enabled_attr) and not config.is_enabled()):
|
||||
module_enabled = False
|
||||
sys.path.remove(tmppath)
|
||||
sys.modules.pop('config')
|
||||
opts.Add(BoolVariable('module_' + x + '_enabled', "Enable module '%s'" % (x, ), module_enabled))
|
||||
opts.Add('module_'+x+'_enabled', "Enable module '"+x+"'.", "yes")
|
||||
|
||||
opts.Update(env_base) # update environment
|
||||
Help(opts.GenerateHelpText(env_base)) # generate help
|
||||
|
||||
# add default include paths
|
||||
|
||||
env_base.Prepend(CPPPATH=['#'])
|
||||
env_base.Append(CPPPATH=['#core','#core/math','#tools','#drivers','#'])
|
||||
|
||||
# configure ENV for platform
|
||||
env_base.platform_exporters = platform_exporters
|
||||
env_base.platform_apis = platform_apis
|
||||
env_base.platform_exporters=platform_exporters
|
||||
|
||||
if (env_base["use_precise_math_checks"]):
|
||||
env_base.Append(CPPDEFINES=['PRECISE_MATH_CHECKS'])
|
||||
"""
|
||||
sys.path.append("./platform/"+env_base["platform"])
|
||||
import detect
|
||||
detect.configure(env_base)
|
||||
sys.path.remove("./platform/"+env_base["platform"])
|
||||
sys.modules.pop('detect')
|
||||
"""
|
||||
|
||||
if (env_base['target'] == 'debug'):
|
||||
env_base.Append(CPPDEFINES=['DEBUG_MEMORY_ALLOC','DISABLE_FORCED_INLINE'])
|
||||
|
||||
# The two options below speed up incremental builds, but reduce the certainty that all files
|
||||
# will properly be rebuilt. As such, we only enable them for debug (dev) builds, not release.
|
||||
|
||||
# To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
|
||||
env_base.Decider('MD5-timestamp')
|
||||
# Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06s04.html
|
||||
env_base.SetOption('implicit_cache', 1)
|
||||
|
||||
if (env_base['no_editor_splash']):
|
||||
env_base.Append(CPPDEFINES=['NO_EDITOR_SPLASH'])
|
||||
|
||||
if not env_base['deprecated']:
|
||||
env_base.Append(CPPDEFINES=['DISABLE_DEPRECATED'])
|
||||
if (env_base['target']=='debug'):
|
||||
env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']);
|
||||
env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE'])
|
||||
|
||||
env_base.platforms = {}
|
||||
|
||||
selected_platform = ""
|
||||
|
||||
selected_platform =""
|
||||
|
||||
if env_base['platform'] != "":
|
||||
selected_platform = env_base['platform']
|
||||
selected_platform=env_base['platform']
|
||||
elif env_base['p'] != "":
|
||||
selected_platform = env_base['p']
|
||||
env_base["platform"] = selected_platform
|
||||
else:
|
||||
# Missing `platform` argument, try to detect platform automatically
|
||||
if sys.platform.startswith('linux'):
|
||||
selected_platform = 'x11'
|
||||
elif sys.platform == 'darwin':
|
||||
selected_platform = 'osx'
|
||||
elif sys.platform == 'win32':
|
||||
selected_platform = 'windows'
|
||||
else:
|
||||
print("Could not detect platform automatically. Supported platforms:")
|
||||
for x in platform_list:
|
||||
print("\t" + x)
|
||||
print("\nPlease run SCons again and select a valid platform: platform=<string>")
|
||||
selected_platform=env_base['p']
|
||||
env_base["platform"]=selected_platform
|
||||
|
||||
if selected_platform != "":
|
||||
print("Automatically detected platform: " + selected_platform)
|
||||
env_base["platform"] = selected_platform
|
||||
|
||||
if selected_platform in platform_list:
|
||||
tmppath = "./platform/" + selected_platform
|
||||
sys.path.insert(0, tmppath)
|
||||
|
||||
sys.path.append("./platform/"+selected_platform)
|
||||
import detect
|
||||
if "create" in dir(detect):
|
||||
env = detect.create(env_base)
|
||||
else:
|
||||
env = env_base.Clone()
|
||||
|
||||
if env['dev']:
|
||||
env['verbose'] = True
|
||||
env['warnings'] = "extra"
|
||||
env['werror'] = True
|
||||
|
||||
if env['vsproj']:
|
||||
if env['vsproj']=="yes":
|
||||
env.vs_incs = []
|
||||
env.vs_srcs = []
|
||||
|
||||
def AddToVSProject(sources):
|
||||
def AddToVSProject( sources ):
|
||||
for x in sources:
|
||||
if type(x) == type(""):
|
||||
fname = env.File(x).path
|
||||
else:
|
||||
fname = env.File(x)[0].path
|
||||
pieces = fname.split(".")
|
||||
if len(pieces) > 0:
|
||||
if len(pieces)>0:
|
||||
basename = pieces[0]
|
||||
basename = basename.replace('\\\\', '/')
|
||||
if os.path.isfile(basename + ".h"):
|
||||
env.vs_incs = env.vs_incs + [basename + ".h"]
|
||||
elif os.path.isfile(basename + ".hpp"):
|
||||
env.vs_incs = env.vs_incs + [basename + ".hpp"]
|
||||
if os.path.isfile(basename + ".c"):
|
||||
env.vs_srcs = env.vs_srcs + [basename + ".c"]
|
||||
elif os.path.isfile(basename + ".cpp"):
|
||||
basename = basename.replace('\\\\','/')
|
||||
env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
|
||||
env.vs_incs = env.vs_incs + [basename + ".h"]
|
||||
#print basename
|
||||
env.AddToVSProject = AddToVSProject
|
||||
|
||||
env.extra_suffix = ""
|
||||
env.extra_suffix=""
|
||||
|
||||
if env["extra_suffix"] != '':
|
||||
env.extra_suffix += '.' + env["extra_suffix"]
|
||||
if env["extra_suffix"] != '' :
|
||||
env.extra_suffix += '.'+env["extra_suffix"]
|
||||
|
||||
CCFLAGS = env.get('CCFLAGS', '')
|
||||
env['CCFLAGS'] = ''
|
||||
env.Append(CCFLAGS=str(CCFLAGS).split())
|
||||
|
||||
env.Append(CCFLAGS=string.split(str(CCFLAGS)))
|
||||
|
||||
CFLAGS = env.get('CFLAGS', '')
|
||||
env['CFLAGS'] = ''
|
||||
env.Append(CFLAGS=str(CFLAGS).split())
|
||||
|
||||
CXXFLAGS = env.get('CXXFLAGS', '')
|
||||
env['CXXFLAGS'] = ''
|
||||
env.Append(CXXFLAGS=str(CXXFLAGS).split())
|
||||
env.Append(CFLAGS=string.split(str(CFLAGS)))
|
||||
|
||||
LINKFLAGS = env.get('LINKFLAGS', '')
|
||||
env['LINKFLAGS'] = ''
|
||||
env.Append(LINKFLAGS=str(LINKFLAGS).split())
|
||||
|
||||
env.Append(LINKFLAGS=string.split(str(LINKFLAGS)))
|
||||
|
||||
flag_list = platform_flags[selected_platform]
|
||||
for f in flag_list:
|
||||
if not (f[0] in ARGUMENTS): # allow command line to override platform flags
|
||||
env[f[0]] = f[1]
|
||||
|
||||
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
|
||||
#must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
|
||||
detect.configure(env)
|
||||
|
||||
# Enable C++11 support
|
||||
if not env.msvc:
|
||||
env.Append(CXXFLAGS=['-std=c++11'])
|
||||
#env['platform_libsuffix'] = env['LIBSUFFIX']
|
||||
|
||||
# Configure compiler warnings
|
||||
if env.msvc:
|
||||
# Truncations, narrowing conversions, signed/unsigned comparisons...
|
||||
disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4018', '/wd4800']
|
||||
if (env["warnings"] == 'extra'):
|
||||
env.Append(CCFLAGS=['/Wall']) # Implies /W4
|
||||
elif (env["warnings"] == 'all'):
|
||||
env.Append(CCFLAGS=['/W3'] + disable_nonessential_warnings)
|
||||
elif (env["warnings"] == 'moderate'):
|
||||
env.Append(CCFLAGS=['/W2'] + disable_nonessential_warnings)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=['/w'])
|
||||
# Set exception handling model to avoid warnings caused by Windows system headers.
|
||||
env.Append(CCFLAGS=['/EHsc'])
|
||||
if (env["werror"]):
|
||||
env.Append(CCFLAGS=['/WX'])
|
||||
# Force to use Unicode encoding
|
||||
env.Append(MSVC_FLAGS=['/utf8'])
|
||||
else: # Rest of the world
|
||||
shadow_local_warning = []
|
||||
all_plus_warnings = ['-Wwrite-strings']
|
||||
suffix="."+selected_platform
|
||||
|
||||
if methods.using_gcc(env):
|
||||
version = methods.get_compiler_version(env)
|
||||
if version != None and version[0] >= '7':
|
||||
shadow_local_warning = ['-Wshadow-local']
|
||||
|
||||
if (env["warnings"] == 'extra'):
|
||||
# Note: enable -Wimplicit-fallthrough for Clang (already part of -Wextra for GCC)
|
||||
# once we switch to C++11 or later (necessary for our FALLTHROUGH macro).
|
||||
env.Append(CCFLAGS=['-Wall', '-Wextra', '-Wno-unused-parameter']
|
||||
+ all_plus_warnings + shadow_local_warning)
|
||||
env.Append(CXXFLAGS=['-Wctor-dtor-privacy', '-Wnon-virtual-dtor'])
|
||||
if methods.using_gcc(env):
|
||||
env.Append(CCFLAGS=['-Walloc-zero',
|
||||
'-Wduplicated-branches', '-Wduplicated-cond',
|
||||
'-Wstringop-overflow=4', '-Wlogical-op'])
|
||||
env.Append(CXXFLAGS=['-Wnoexcept', '-Wplacement-new=1'])
|
||||
version = methods.get_compiler_version(env)
|
||||
if version != None and version[0] >= '9':
|
||||
env.Append(CCFLAGS=['-Wattribute-alias=2'])
|
||||
elif (env["warnings"] == 'all'):
|
||||
env.Append(CCFLAGS=['-Wall'] + shadow_local_warning)
|
||||
elif (env["warnings"] == 'moderate'):
|
||||
env.Append(CCFLAGS=['-Wall', '-Wno-unused'] + shadow_local_warning)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=['-w'])
|
||||
if (env["werror"]):
|
||||
env.Append(CCFLAGS=['-Werror'])
|
||||
else: # always enable those errors
|
||||
env.Append(CCFLAGS=['-Werror=return-type'])
|
||||
|
||||
if (hasattr(detect, 'get_program_suffix')):
|
||||
suffix = "." + detect.get_program_suffix()
|
||||
else:
|
||||
suffix = "." + selected_platform
|
||||
|
||||
if (env["target"] == "release"):
|
||||
if env["tools"]:
|
||||
if (env["target"]=="release"):
|
||||
if (env["tools"]=="yes"):
|
||||
print("Tools can only be built with targets 'debug' and 'release_debug'.")
|
||||
sys.exit(255)
|
||||
suffix += ".opt"
|
||||
env.Append(CPPDEFINES=['NDEBUG'])
|
||||
suffix+=".opt"
|
||||
|
||||
elif (env["target"] == "release_debug"):
|
||||
if env["tools"]:
|
||||
suffix += ".opt.tools"
|
||||
elif (env["target"]=="release_debug"):
|
||||
if (env["tools"]=="yes"):
|
||||
suffix+=".opt.tools"
|
||||
else:
|
||||
suffix += ".opt.debug"
|
||||
suffix+=".opt.debug"
|
||||
else:
|
||||
if env["tools"]:
|
||||
suffix += ".tools"
|
||||
if (env["tools"]=="yes"):
|
||||
suffix+=".tools"
|
||||
else:
|
||||
suffix += ".debug"
|
||||
suffix+=".debug"
|
||||
|
||||
if env["arch"] != "":
|
||||
suffix += "." + env["arch"]
|
||||
elif (env["bits"] == "32"):
|
||||
suffix += ".32"
|
||||
elif (env["bits"] == "64"):
|
||||
suffix += ".64"
|
||||
if (env["bits"]=="32"):
|
||||
suffix+=".32"
|
||||
elif (env["bits"]=="64"):
|
||||
suffix+=".64"
|
||||
|
||||
suffix += env.extra_suffix
|
||||
suffix+=env.extra_suffix
|
||||
|
||||
sys.path.remove(tmppath)
|
||||
env["PROGSUFFIX"]=suffix+env["PROGSUFFIX"]
|
||||
env["OBJSUFFIX"]=suffix+env["OBJSUFFIX"]
|
||||
env["LIBSUFFIX"]=suffix+env["LIBSUFFIX"]
|
||||
env["SHLIBSUFFIX"]=suffix+env["SHLIBSUFFIX"]
|
||||
|
||||
sys.path.remove("./platform/"+selected_platform)
|
||||
sys.modules.pop('detect')
|
||||
|
||||
env.module_list = []
|
||||
env.module_icons_paths = []
|
||||
env.doc_class_path = {}
|
||||
|
||||
env.module_list=[]
|
||||
|
||||
for x in module_list:
|
||||
if not env['module_' + x + '_enabled']:
|
||||
if env['module_'+x+'_enabled'] != "yes":
|
||||
continue
|
||||
tmppath = "./modules/" + x
|
||||
sys.path.insert(0, tmppath)
|
||||
env.current_module = x
|
||||
tmppath="./modules/"+x
|
||||
sys.path.append(tmppath)
|
||||
env.current_module=x
|
||||
import config
|
||||
# can_build changed number of arguments between 3.0 (1) and 3.1 (2),
|
||||
# so try both to preserve compatibility for 3.0 modules
|
||||
can_build = False
|
||||
try:
|
||||
can_build = config.can_build(env, selected_platform)
|
||||
except TypeError:
|
||||
print("Warning: module '%s' uses a deprecated `can_build` "
|
||||
"signature in its config.py file, it should be "
|
||||
"`can_build(env, platform)`." % x)
|
||||
can_build = config.can_build(selected_platform)
|
||||
if (can_build):
|
||||
if (config.can_build(selected_platform)):
|
||||
config.configure(env)
|
||||
env.module_list.append(x)
|
||||
|
||||
# Get doc classes paths (if present)
|
||||
try:
|
||||
doc_classes = config.get_doc_classes()
|
||||
doc_path = config.get_doc_path()
|
||||
for c in doc_classes:
|
||||
env.doc_class_path[c] = "modules/" + x + "/" + doc_path
|
||||
except:
|
||||
pass
|
||||
# Get icon paths (if present)
|
||||
try:
|
||||
icons_path = config.get_icons_path()
|
||||
env.module_icons_paths.append("modules/" + x + "/" + icons_path)
|
||||
except:
|
||||
# Default path for module icons
|
||||
env.module_icons_paths.append("modules/" + x + "/" + "icons")
|
||||
|
||||
sys.path.remove(tmppath)
|
||||
sys.modules.pop('config')
|
||||
|
||||
methods.update_version(env.module_version_string)
|
||||
|
||||
env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"]
|
||||
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
|
||||
# (SH)LIBSUFFIX will be used for our own built libraries
|
||||
# LIBSUFFIXES contains LIBSUFFIX and SHLIBSUFFIX by default,
|
||||
# so we need to append the default suffixes to keep the ability
|
||||
# to link against thirdparty libraries (.a, .so, .lib, etc.).
|
||||
if os.name == "nt":
|
||||
# On Windows, only static libraries and import libraries can be
|
||||
# statically linked - both using .lib extension
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"]]
|
||||
else:
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"], env["SHLIBSUFFIX"]]
|
||||
env["LIBSUFFIX"] = suffix + env["LIBSUFFIX"]
|
||||
env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"]
|
||||
if (env['musepack']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
|
||||
|
||||
if (env.use_ptrcall):
|
||||
env.Append(CPPDEFINES=['PTRCALL_ENABLED'])
|
||||
if env['tools']:
|
||||
env.Append(CPPDEFINES=['TOOLS_ENABLED'])
|
||||
if env['disable_3d']:
|
||||
if env['tools']:
|
||||
print("Build option 'disable_3d=yes' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
|
||||
sys.exit(255)
|
||||
else:
|
||||
env.Append(CPPDEFINES=['_3D_DISABLED'])
|
||||
if env['gdscript']:
|
||||
env.Append(CPPDEFINES=['GDSCRIPT_ENABLED'])
|
||||
if env['disable_advanced_gui']:
|
||||
if env['tools']:
|
||||
print("Build option 'disable_advanced_gui=yes' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
|
||||
sys.exit(255)
|
||||
else:
|
||||
env.Append(CPPDEFINES=['ADVANCED_GUI_DISABLED'])
|
||||
if env['minizip']:
|
||||
env.Append(CPPDEFINES=['MINIZIP_ENABLED'])
|
||||
if (env['openssl']!='no'):
|
||||
env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
if (env['openssl']=="builtin"):
|
||||
env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||
|
||||
editor_module_list = ['regex']
|
||||
for x in editor_module_list:
|
||||
if not env['module_' + x + '_enabled']:
|
||||
if env['tools']:
|
||||
print("Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
|
||||
sys.exit(255)
|
||||
if (env["builtin_zlib"]=='yes'):
|
||||
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
|
||||
|
||||
if not env['verbose']:
|
||||
methods.no_verbose(sys, env)
|
||||
# to test 64 bits compiltion
|
||||
# env.Append(CPPFLAGS=['-m64'])
|
||||
|
||||
if (not env["platform"] == "server"): # FIXME: detect GLES3
|
||||
env.Append(BUILDERS = { 'GLES3_GLSL' : env.Builder(action=run_in_subprocess(gles_builders.build_gles3_headers), suffix='glsl.gen.h', src_suffix='.glsl')})
|
||||
env.Append(BUILDERS = { 'GLES2_GLSL' : env.Builder(action=run_in_subprocess(gles_builders.build_gles2_headers), suffix='glsl.gen.h', src_suffix='.glsl')})
|
||||
if (env_base['squish']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DSQUISH_ENABLED']);
|
||||
|
||||
scons_cache_path = os.environ.get("SCONS_CACHE")
|
||||
if scons_cache_path != None:
|
||||
CacheDir(scons_cache_path)
|
||||
print("Scons cache enabled... (path: '" + scons_cache_path + "')")
|
||||
if (env['vorbis']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DVORBIS_ENABLED']);
|
||||
if (env['opus']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DOPUS_ENABLED']);
|
||||
|
||||
|
||||
if (env['theora']=='yes'):
|
||||
env['theoralib']='yes'
|
||||
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
||||
if (env['theoralib']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
|
||||
|
||||
if (env['png']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DPNG_ENABLED']);
|
||||
if (env['dds']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DDDS_ENABLED']);
|
||||
if (env['pvr']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DPVR_ENABLED']);
|
||||
if (env['jpg']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DJPG_ENABLED']);
|
||||
if (env['webp']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DWEBP_ENABLED']);
|
||||
|
||||
if (env['speex']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DSPEEX_ENABLED']);
|
||||
|
||||
if (env['tools']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
|
||||
if (env['disable_3d']=='yes'):
|
||||
env.Append(CPPFLAGS=['-D_3D_DISABLED'])
|
||||
if (env['gdscript']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DGDSCRIPT_ENABLED'])
|
||||
if (env['disable_advanced_gui']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DADVANCED_GUI_DISABLED'])
|
||||
|
||||
if (env['minizip'] == 'yes'):
|
||||
env.Append(CPPFLAGS=['-DMINIZIP_ENABLED'])
|
||||
|
||||
if (env['xml']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DXML_ENABLED'])
|
||||
|
||||
if (env['colored']=='yes'):
|
||||
methods.colored(sys,env)
|
||||
|
||||
if (env['etc1']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DETC1_ENABLED'])
|
||||
|
||||
Export('env')
|
||||
|
||||
# build subdirs, the build order is dependent on link order.
|
||||
#build subdirs, the build order is dependent on link order.
|
||||
|
||||
SConscript("core/SCsub")
|
||||
SConscript("servers/SCsub")
|
||||
SConscript("scene/SCsub")
|
||||
SConscript("editor/SCsub")
|
||||
SConscript("tools/SCsub")
|
||||
SConscript("drivers/SCsub")
|
||||
SConscript("bin/SCsub")
|
||||
|
||||
SConscript("platform/SCsub")
|
||||
SConscript("modules/SCsub")
|
||||
SConscript("main/SCsub")
|
||||
|
||||
SConscript("platform/" + selected_platform + "/SCsub") # build selected platform
|
||||
SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform
|
||||
|
||||
# Microsoft Visual Studio Project Generation
|
||||
if env['vsproj']:
|
||||
env['CPPPATH'] = [Dir(path) for path in env['CPPPATH']]
|
||||
methods.generate_vs_project(env, GetOption("num_jobs"))
|
||||
methods.generate_cpp_hint_file("cpp.hint")
|
||||
if (env['vsproj'])=="yes":
|
||||
|
||||
# Check for the existence of headers
|
||||
conf = Configure(env)
|
||||
if ("check_c_headers" in env):
|
||||
for header in env["check_c_headers"]:
|
||||
if (conf.CheckCHeader(header[0])):
|
||||
env.AppendUnique(CPPDEFINES=[header[1]])
|
||||
AddToVSProject(env.core_sources)
|
||||
AddToVSProject(env.main_sources)
|
||||
AddToVSProject(env.modules_sources)
|
||||
AddToVSProject(env.scene_sources)
|
||||
AddToVSProject(env.servers_sources)
|
||||
AddToVSProject(env.tool_sources)
|
||||
|
||||
elif selected_platform != "":
|
||||
if selected_platform == "list":
|
||||
print("The following platforms are available:\n")
|
||||
else:
|
||||
print('Invalid target platform "' + selected_platform + '".')
|
||||
print("The following platforms were detected:\n")
|
||||
#env['MSVS_VERSION']='9.0'
|
||||
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
|
||||
env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
|
||||
debug_variants = ['Debug|Win32']+['Debug|x64']
|
||||
release_variants = ['Release|Win32']+['Release|x64']
|
||||
release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64']
|
||||
variants = debug_variants + release_variants + release_debug_variants
|
||||
debug_targets = ['Debug']+['Debug']
|
||||
release_targets = ['Release']+['Release']
|
||||
release_debug_targets = ['ReleaseDebug']+['ReleaseDebug']
|
||||
targets = debug_targets + release_targets + release_debug_targets
|
||||
msvproj = env.MSVSProject(target = ['#godot' + env['MSVSPROJECTSUFFIX'] ],
|
||||
incs = env.vs_incs,
|
||||
srcs = env.vs_srcs,
|
||||
runfile = targets,
|
||||
buildtarget = targets,
|
||||
auto_build_solution=1,
|
||||
variant = variants)
|
||||
|
||||
else:
|
||||
|
||||
print("No valid target platform selected.")
|
||||
print("The following were detected:")
|
||||
for x in platform_list:
|
||||
print("\t" + x)
|
||||
|
||||
print("\nPlease run SCons again and select a valid platform: platform=<string>")
|
||||
|
||||
if selected_platform == "list":
|
||||
# Exit early to suppress the rest of the built-in SCons messages
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(255)
|
||||
|
||||
# The following only makes sense when the env is defined, and assumes it is
|
||||
if 'env' in locals():
|
||||
screen = sys.stdout
|
||||
# Progress reporting is not available in non-TTY environments since it
|
||||
# messes with the output (for example, when writing to a file)
|
||||
show_progress = (env['progress'] and sys.stdout.isatty())
|
||||
node_count = 0
|
||||
node_count_max = 0
|
||||
node_count_interval = 1
|
||||
node_count_fname = str(env.Dir('#')) + '/.scons_node_count'
|
||||
|
||||
import time, math
|
||||
|
||||
class cache_progress:
|
||||
# The default is 1 GB cache and 12 hours half life
|
||||
def __init__(self, path = None, limit = 1073741824, half_life = 43200):
|
||||
self.path = path
|
||||
self.limit = limit
|
||||
self.exponent_scale = math.log(2) / half_life
|
||||
if env['verbose'] and path != None:
|
||||
screen.write('Current cache limit is ' + self.convert_size(limit) + ' (used: ' + self.convert_size(self.get_size(path)) + ')\n')
|
||||
self.delete(self.file_list())
|
||||
|
||||
def __call__(self, node, *args, **kw):
|
||||
global node_count, node_count_max, node_count_interval, node_count_fname, show_progress
|
||||
if show_progress:
|
||||
# Print the progress percentage
|
||||
node_count += node_count_interval
|
||||
if (node_count_max > 0 and node_count <= node_count_max):
|
||||
screen.write('\r[%3d%%] ' % (node_count * 100 / node_count_max))
|
||||
screen.flush()
|
||||
elif (node_count_max > 0 and node_count > node_count_max):
|
||||
screen.write('\r[100%] ')
|
||||
screen.flush()
|
||||
else:
|
||||
screen.write('\r[Initial build] ')
|
||||
screen.flush()
|
||||
|
||||
def delete(self, files):
|
||||
if len(files) == 0:
|
||||
return
|
||||
if env['verbose']:
|
||||
# Utter something
|
||||
screen.write('\rPurging %d %s from cache...\n' % (len(files), len(files) > 1 and 'files' or 'file'))
|
||||
[os.remove(f) for f in files]
|
||||
|
||||
def file_list(self):
|
||||
if self.path is None:
|
||||
# Nothing to do
|
||||
return []
|
||||
# Gather a list of (filename, (size, atime)) within the
|
||||
# cache directory
|
||||
file_stat = [(x, os.stat(x)[6:8]) for x in glob.glob(os.path.join(self.path, '*', '*'))]
|
||||
if file_stat == []:
|
||||
# Nothing to do
|
||||
return []
|
||||
# Weight the cache files by size (assumed to be roughly
|
||||
# proportional to the recompilation time) times an exponential
|
||||
# decay since the ctime, and return a list with the entries
|
||||
# (filename, size, weight).
|
||||
current_time = time.time()
|
||||
file_stat = [(x[0], x[1][0], (current_time - x[1][1])) for x in file_stat]
|
||||
# Sort by the most recently accessed files (most sensible to keep) first
|
||||
file_stat.sort(key=lambda x: x[2])
|
||||
# Search for the first entry where the storage limit is
|
||||
# reached
|
||||
sum, mark = 0, None
|
||||
for i,x in enumerate(file_stat):
|
||||
sum += x[1]
|
||||
if sum > self.limit:
|
||||
mark = i
|
||||
break
|
||||
if mark is None:
|
||||
return []
|
||||
else:
|
||||
return [x[0] for x in file_stat[mark:]]
|
||||
|
||||
def convert_size(self, size_bytes):
|
||||
if size_bytes == 0:
|
||||
return "0 bytes"
|
||||
size_name = ("bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
|
||||
i = int(math.floor(math.log(size_bytes, 1024)))
|
||||
p = math.pow(1024, i)
|
||||
s = round(size_bytes / p, 2)
|
||||
return "%s %s" % (int(s) if i == 0 else s, size_name[i])
|
||||
|
||||
def get_size(self, start_path = '.'):
|
||||
total_size = 0
|
||||
for dirpath, dirnames, filenames in os.walk(start_path):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
total_size += os.path.getsize(fp)
|
||||
return total_size
|
||||
|
||||
def progress_finish(target, source, env):
|
||||
global node_count, progressor
|
||||
with open(node_count_fname, 'w') as f:
|
||||
f.write('%d\n' % node_count)
|
||||
progressor.delete(progressor.file_list())
|
||||
|
||||
try:
|
||||
with open(node_count_fname) as f:
|
||||
node_count_max = int(f.readline())
|
||||
except:
|
||||
pass
|
||||
|
||||
cache_directory = os.environ.get("SCONS_CACHE")
|
||||
# Simple cache pruning, attached to SCons' progress callback. Trim the
|
||||
# cache directory to a size not larger than cache_limit.
|
||||
cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", 1024)) * 1024 * 1024
|
||||
progressor = cache_progress(cache_directory, cache_limit)
|
||||
Progress(progressor, interval = node_count_interval)
|
||||
|
||||
progress_finish_command = Command('progress_finish', [], progress_finish)
|
||||
AlwaysBuild(progress_finish_command)
|
||||
print("\t"+x)
|
||||
print("\nPlease run scons again with argument: platform=<string>")
|
||||
|
||||
4
bin/SCsub
Normal file
4
bin/SCsub
Normal file
@ -0,0 +1,4 @@
|
||||
Import('env')
|
||||
Export('env')
|
||||
|
||||
SConscript('tests/SCsub');
|
||||
12
bin/tests/SCsub
Normal file
12
bin/tests/SCsub
Normal file
@ -0,0 +1,12 @@
|
||||
Import('env')
|
||||
|
||||
env.tests_sources=[]
|
||||
env.add_source_files(env.tests_sources,"*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
||||
#SConscript('math/SCsub');
|
||||
|
||||
lib = env.Library("tests",env.tests_sources)
|
||||
|
||||
env.Prepend(LIBS=[lib])
|
||||
107
bin/tests/test_containers.cpp
Normal file
107
bin/tests/test_containers.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*************************************************************************/
|
||||
/* test_containers.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_containers.h"
|
||||
#include "dvector.h"
|
||||
#include "set.h"
|
||||
#include "print_string.h"
|
||||
#include "math_funcs.h"
|
||||
#include "servers/visual/default_mouse_cursor.xpm"
|
||||
|
||||
#include "variant.h"
|
||||
#include "list.h"
|
||||
#include "image.h"
|
||||
|
||||
namespace TestContainers {
|
||||
|
||||
MainLoop * test() {
|
||||
|
||||
|
||||
/*
|
||||
HashMap<int,int> int_map;
|
||||
|
||||
for (int i=0;i<68000;i++) {
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
int_map[i]=num;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
{
|
||||
|
||||
// static const int size = 16;
|
||||
Image img;
|
||||
img.create(default_mouse_cursor_xpm);
|
||||
|
||||
{
|
||||
for (int i=0; i<8; i++) {
|
||||
|
||||
Image mipmap;
|
||||
//img.make_mipmap(mipmap);
|
||||
img = mipmap;
|
||||
if (img.get_width() <= 4) break;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#if 0
|
||||
Set<int> set;
|
||||
|
||||
print_line("Begin Insert");
|
||||
for (int i=0;i<1100;i++) {
|
||||
|
||||
int num=i;//(int)Math::random(0,1024);
|
||||
// print_line("inserting "+itos(num));
|
||||
set.insert( num );
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i=0;i<400;i++) {
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
set.erase(num);
|
||||
}
|
||||
*/
|
||||
//set.print_tree();
|
||||
|
||||
for(Set<int>::Element *I=set.front();I;I=I->next()) {
|
||||
|
||||
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
|
||||
|
||||
}
|
||||
|
||||
print_line("depth is "+itos(set.calculate_depth()));
|
||||
print_line("Insert Success");
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
43
bin/tests/test_containers.h
Normal file
43
bin/tests/test_containers.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*************************************************************************/
|
||||
/* test_containers.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_CONTAINERS_H
|
||||
#define TEST_CONTAINERS_H
|
||||
|
||||
#include "os/main_loop.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
namespace TestContainers {
|
||||
|
||||
MainLoop * test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
217
bin/tests/test_detailer.cpp
Normal file
217
bin/tests/test_detailer.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*************************************************************************/
|
||||
/* test_detailer.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_detailer.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
#include "geometry.h"
|
||||
#include "quick_hull.h"
|
||||
namespace TestMultiMesh {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
RID instance;
|
||||
RID camera;
|
||||
RID viewport;
|
||||
RID light;
|
||||
RID mesh;
|
||||
RID scenario;
|
||||
|
||||
#define MULTIMESH_COUNT 1500
|
||||
|
||||
float ofs_x,ofs_y;
|
||||
bool quit;
|
||||
public:
|
||||
|
||||
|
||||
virtual void _update_qh() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
Vector<Vector3> vts;
|
||||
/*
|
||||
|
||||
static const int s = 20;
|
||||
for(int i=0;i<s;i++) {
|
||||
Matrix3 rot(Vector3(0,1,0),i*Math_PI/s);
|
||||
|
||||
for(int j=0;j<s;j++) {
|
||||
Vector3 v;
|
||||
v.x=Math::sin(j*Math_PI*2/s);
|
||||
v.y=Math::cos(j*Math_PI*2/s);
|
||||
|
||||
vts.push_back( rot.xform(v*2 ) );
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
Math::seed(0);
|
||||
for(int i=0;i<50;i++) {
|
||||
|
||||
vts.push_back( Vector3(Math::randf()*2-1.0,Math::randf()*2-1.0,Math::randf()*2-1.0).normalized()*2);
|
||||
}*/
|
||||
/*
|
||||
vts.push_back(Vector3(0,0,1));
|
||||
vts.push_back(Vector3(0,0,-1));
|
||||
vts.push_back(Vector3(0,1,0));
|
||||
vts.push_back(Vector3(0,-1,0));
|
||||
vts.push_back(Vector3(1,0,0));
|
||||
vts.push_back(Vector3(-1,0,0));*/
|
||||
/*
|
||||
vts.push_back(Vector3(1,1,1));
|
||||
vts.push_back(Vector3(1,-1,1));
|
||||
vts.push_back(Vector3(-1,1,1));
|
||||
vts.push_back(Vector3(-1,-1,1));
|
||||
vts.push_back(Vector3(1,1,-1));
|
||||
vts.push_back(Vector3(1,-1,-1));
|
||||
vts.push_back(Vector3(-1,1,-1));
|
||||
vts.push_back(Vector3(-1,-1,-1));
|
||||
*/
|
||||
|
||||
|
||||
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,4,Vector3::AXIS_Z);
|
||||
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
|
||||
vts=convex_data.vertices;
|
||||
|
||||
Geometry::MeshData md;
|
||||
Error err = QuickHull::build(vts,md);
|
||||
print_line("ERR: "+itos(err));
|
||||
|
||||
vs->mesh_remove_surface(mesh,0);
|
||||
vs->mesh_add_surface_from_mesh_data(mesh,md);
|
||||
|
||||
|
||||
|
||||
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
|
||||
|
||||
/*
|
||||
RID sm = vs->shader_create();
|
||||
//vs->shader_set_fragment_code(sm,"OUT_ALPHA=mod(TIME,1);");
|
||||
//vs->shader_set_vertex_code(sm,"OUT_VERTEX=IN_VERTEX*mod(TIME,1);");
|
||||
vs->shader_set_fragment_code(sm,"OUT_DIFFUSE=vec3(1,0,1);OUT_GLOW=abs(sin(TIME));");
|
||||
RID tcmat = vs->mesh_surface_get_material(test_cube,0);
|
||||
vs->material_set_shader(tcmat,sm);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||
|
||||
ofs_x+=p_event.mouse_motion.relative_y/200.0;
|
||||
ofs_y+=p_event.mouse_motion.relative_x/200.0;
|
||||
}
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
|
||||
|
||||
QuickHull::debug_stop_after++;
|
||||
_update_qh();
|
||||
}
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==2) {
|
||||
|
||||
if (QuickHull::debug_stop_after>0)
|
||||
QuickHull::debug_stop_after--;
|
||||
_update_qh();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void init() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
mesh = vs->mesh_create();
|
||||
|
||||
scenario = vs->scenario_create();
|
||||
|
||||
QuickHull::debug_stop_after=0;
|
||||
_update_qh();
|
||||
|
||||
instance = vs->instance_create2(mesh,scenario);
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
vs->viewport_set_scenario( viewport, scenario );
|
||||
|
||||
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,2 ) ) );
|
||||
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
|
||||
light = vs->instance_create2( lightaux,scenario );
|
||||
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
|
||||
|
||||
ofs_x=0;
|
||||
ofs_y=0;
|
||||
quit=false;
|
||||
}
|
||||
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
Transform tr_camera;
|
||||
tr_camera.rotate( Vector3(0,1,0), ofs_y );
|
||||
tr_camera.rotate( Vector3(1,0,0),ofs_x );
|
||||
tr_camera.translate(0,0,10);
|
||||
|
||||
vs->camera_set_transform( camera, tr_camera );
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew(TestMainLoop);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
bin/tests/test_detailer.h
Normal file
44
bin/tests/test_detailer.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*************************************************************************/
|
||||
/* test_detailer.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_MULTIMESH_H
|
||||
#define TEST_MULTIMESH_H
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestMultiMesh {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1042
bin/tests/test_gdscript.cpp
Normal file
1042
bin/tests/test_gdscript.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,11 +26,10 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_GDSCRIPT_H
|
||||
#define TEST_GDSCRIPT_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestGDScript {
|
||||
|
||||
@ -42,7 +40,8 @@ enum TestType {
|
||||
TEST_BYTECODE,
|
||||
};
|
||||
|
||||
MainLoop *test(TestType p_type);
|
||||
} // namespace TestGDScript
|
||||
MainLoop* test(TestType p_type);
|
||||
|
||||
}
|
||||
|
||||
#endif // TEST_GDSCRIPT_H
|
||||
402
bin/tests/test_gui.cpp
Normal file
402
bin/tests/test_gui.cpp
Normal file
@ -0,0 +1,402 @@
|
||||
/*************************************************************************/
|
||||
/* test_gui.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
#include "test_gui.h"
|
||||
|
||||
#include "scene/main/scene_main_loop.h"
|
||||
#include "os/os.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/scroll_bar.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/option_button.h"
|
||||
#include "scene/gui/spin_box.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/progress_bar.h"
|
||||
#include "scene/gui/panel.h"
|
||||
#include "scene/gui/tab_container.h"
|
||||
#include "scene/gui/tree.h"
|
||||
#include "scene/gui/rich_text_label.h"
|
||||
#include "scene/gui/texture_frame.h"
|
||||
#include "io/image_loader.h"
|
||||
#include "print_string.h"
|
||||
#include "scene/2d/sprite.h"
|
||||
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/3d/camera.h"
|
||||
#include "scene/3d/test_cube.h"
|
||||
|
||||
namespace TestGUI {
|
||||
|
||||
|
||||
class TestMainLoop : public SceneTree {
|
||||
|
||||
|
||||
Control *control;
|
||||
|
||||
public:
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
quit();
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
SceneTree::init();
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
Viewport *vp = memnew( Viewport );
|
||||
vp->set_world( Ref<World>( memnew( World )));
|
||||
get_root()->add_child(vp);
|
||||
|
||||
vp->set_rect(Rect2(0,0,256,256));
|
||||
vp->set_as_render_target(true);
|
||||
vp->set_render_target_update_mode(Viewport::RENDER_TARGET_UPDATE_ALWAYS);
|
||||
|
||||
|
||||
Camera *camera = memnew( Camera );
|
||||
vp->add_child(camera);
|
||||
camera->make_current();
|
||||
|
||||
TestCube *testcube = memnew( TestCube );
|
||||
vp->add_child(testcube);
|
||||
testcube->set_transform(Transform( Matrix3().rotated(Vector3(0,1,0),Math_PI*0.25), Vector3(0,0,-8)));
|
||||
|
||||
Sprite *sp = memnew( Sprite );
|
||||
sp->set_texture( vp->get_render_target_texture() );
|
||||
// sp->set_texture( ResourceLoader::load("res://ball.png") );
|
||||
sp->set_pos(Point2(300,300));
|
||||
get_root()->add_child(sp);
|
||||
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
||||
Panel * frame = memnew( Panel );
|
||||
frame->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
|
||||
frame->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
|
||||
frame->set_end( Point2(0,0) );
|
||||
|
||||
Ref<Theme> t = memnew( Theme );
|
||||
frame->set_theme(t);
|
||||
|
||||
get_root()->add_child( frame );
|
||||
|
||||
Label *label = memnew( Label );
|
||||
|
||||
label->set_pos( Point2( 80,90 ) );
|
||||
label->set_size( Point2( 170,80 ) );
|
||||
label->set_align( Label::ALIGN_FILL );
|
||||
//label->set_text("There");
|
||||
label->set_text("There was once upon a time a beautiful unicorn that loved to play with little girls...");
|
||||
|
||||
frame->add_child(label);
|
||||
|
||||
Button *button = memnew( Button );
|
||||
|
||||
button->set_pos( Point2( 20,20 ) );
|
||||
button->set_size( Point2( 1,1 ) );
|
||||
button->set_text("This is a biggie button");
|
||||
|
||||
|
||||
frame->add_child( button );
|
||||
|
||||
|
||||
#if 0
|
||||
Sprite *tf = memnew( Sprite );
|
||||
frame->add_child(tf);
|
||||
Image img;
|
||||
ImageLoader::load_image("LarvoClub.png",&img);
|
||||
|
||||
img.resize(512,512);
|
||||
img.generate_mipmaps();
|
||||
img.compress(Image::COMPRESS_PVRTC4);
|
||||
Ref<ImageTexture> tt = memnew( ImageTexture );
|
||||
tt->create_from_image(img);
|
||||
tf->set_texture(tt);
|
||||
tf->set_pos(Point2(50,50));
|
||||
//tf->set_scale(Point2(0.3,0.3));
|
||||
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
||||
Tree * tree = memnew( Tree );
|
||||
tree->set_columns(2);
|
||||
|
||||
tree->set_pos( Point2( 230,210 ) );
|
||||
tree->set_size( Point2( 150,250 ) );
|
||||
|
||||
|
||||
TreeItem *item = tree->create_item();
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"root");
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"check");
|
||||
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
|
||||
item->set_editable(1,true);
|
||||
item->set_text(1,"check2");
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_editable(0,true);
|
||||
item->set_range_config(0,0,20,0.1);
|
||||
item->set_range(0,2);
|
||||
item->add_button(0,Theme::get_default()->get_icon("folder","FileDialog"));
|
||||
item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_editable(1,true);
|
||||
item->set_range_config(1,0,20,0.1);
|
||||
item->set_range(1,3);
|
||||
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"Have,Many,Several,Options!");
|
||||
item->set_range(0,2);
|
||||
|
||||
item = tree->create_item( item );
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"Gershwin!");
|
||||
|
||||
frame->add_child(tree);
|
||||
|
||||
//control = memnew( Control );
|
||||
//root->add_child( control );
|
||||
|
||||
|
||||
|
||||
LineEdit *line_edit = memnew( LineEdit );
|
||||
|
||||
line_edit->set_pos( Point2( 30,190 ) );
|
||||
line_edit->set_size( Point2( 180,1 ) );
|
||||
|
||||
frame->add_child(line_edit);
|
||||
|
||||
HScrollBar *hscroll = memnew( HScrollBar );
|
||||
|
||||
hscroll->set_pos( Point2( 30,290 ) );
|
||||
hscroll->set_size( Point2( 180,1 ) );
|
||||
hscroll->set_max(10);
|
||||
hscroll->set_page(4);
|
||||
|
||||
frame->add_child(hscroll);
|
||||
|
||||
|
||||
|
||||
SpinBox *spin = memnew( SpinBox );
|
||||
|
||||
spin->set_pos( Point2( 30,260 ) );
|
||||
spin->set_size( Point2( 120,1 ) );
|
||||
|
||||
frame->add_child(spin);
|
||||
hscroll->share(spin);
|
||||
|
||||
ProgressBar *progress = memnew( ProgressBar );
|
||||
|
||||
progress->set_pos( Point2( 30,330 ) );
|
||||
progress->set_size( Point2( 120,1 ) );
|
||||
|
||||
frame->add_child(progress);
|
||||
hscroll->share(progress);
|
||||
|
||||
MenuButton *menu_button = memnew( MenuButton );
|
||||
|
||||
menu_button->set_text("I'm a menu!");
|
||||
menu_button->set_pos( Point2( 30,380 ) );
|
||||
menu_button->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(menu_button);
|
||||
|
||||
PopupMenu *popup = menu_button->get_popup();
|
||||
|
||||
popup->add_item("Hello, testing");
|
||||
popup->add_item("My Dearest");
|
||||
popup->add_separator();
|
||||
popup->add_item("Popup");
|
||||
popup->add_check_item("Check Popup");
|
||||
popup->set_item_checked(4,true);
|
||||
|
||||
OptionButton *options = memnew( OptionButton );
|
||||
|
||||
options->add_item("Hello, testing");
|
||||
options->add_item("My Dearest");
|
||||
|
||||
options->set_pos( Point2( 230,180 ) );
|
||||
options->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(options);
|
||||
|
||||
/*
|
||||
Tree * tree = memnew( Tree );
|
||||
tree->set_columns(2);
|
||||
|
||||
tree->set_pos( Point2( 230,210 ) );
|
||||
tree->set_size( Point2( 150,250 ) );
|
||||
|
||||
|
||||
TreeItem *item = tree->create_item();
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"root");
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"check");
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_editable(0,true);
|
||||
item->set_range_config(0,0,20,0.1);
|
||||
item->set_range(0,2);
|
||||
item->add_button(0,Theme::get_default()->get_icon("folder","FileDialog"));
|
||||
item = tree->create_item( tree->get_root() );
|
||||
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"Have,Many,Several,Options!");
|
||||
item->set_range(0,2);
|
||||
|
||||
frame->add_child(tree);
|
||||
*/
|
||||
|
||||
|
||||
RichTextLabel *richtext = memnew( RichTextLabel );
|
||||
|
||||
richtext->set_pos( Point2( 600,210 ) );
|
||||
richtext->set_size( Point2( 180,250 ) );
|
||||
richtext->set_anchor_and_margin(MARGIN_RIGHT,Control::ANCHOR_END,20);
|
||||
|
||||
frame->add_child(richtext);
|
||||
|
||||
|
||||
richtext->add_text("Hello, My Friends!\n\nWelcome to the amazing world of ");
|
||||
|
||||
richtext->add_newline();
|
||||
richtext->add_newline();
|
||||
|
||||
richtext->push_color(Color(1,0.5,0.5));
|
||||
richtext->add_text("leprechauns");
|
||||
richtext->pop();
|
||||
|
||||
richtext->add_text(" and ");
|
||||
richtext->push_color(Color(0,1.0,0.5));
|
||||
richtext->add_text("faeries.\n");
|
||||
richtext->pop();
|
||||
richtext->add_text("In this new episode, we will attemp to ");
|
||||
richtext->push_font(richtext->get_font("mono_font","Fonts"));
|
||||
richtext->push_color(Color(0.7,0.5,1.0));
|
||||
richtext->add_text("deliver something nice");
|
||||
richtext->pop();
|
||||
richtext->pop();
|
||||
richtext->add_text(" to all the viewers! Unfortunately, I need to ");
|
||||
richtext->push_underline();
|
||||
richtext->add_text("keep writing a lot of text");
|
||||
richtext->pop();
|
||||
richtext->add_text(" so the label control overflows and the scrollbar appears.\n");
|
||||
//richtext->push_indent(1);
|
||||
//richtext->add_text("By the way, testing indent levels! Yohohoho! Everything should appear to the right sightly here!\n");
|
||||
//richtext->pop();
|
||||
richtext->push_meta("http://www.scrollingcapabilities.xz");
|
||||
richtext->add_text("This allows to test for the scrolling capabilities ");
|
||||
richtext->pop();
|
||||
richtext->add_text("of the rich text label for huge text (not like this text will really be huge but, you know).\nAs long as it is so long that it will work nicely for a test/demo, then it's welcomed in my book...\nChanging subject, the day is cloudy today and I'm wondering if I'll get che chance to travel somewhere nice. Sometimes, watching the clouds from satellite images may give a nice insight about how pressure zones in our planet work, althogh it also makes it pretty obvious to see why most weather forecasts get it wrong so often.\nClouds are so difficult to predict!\nBut it's pretty cool how our civilization has adapted to having water falling from the sky each time it rains...");
|
||||
//richtext->add_text("Hello!\nGorgeous..");
|
||||
|
||||
|
||||
//richtext->push_meta("http://www.scrollingcapabilities.xz");
|
||||
///richtext->add_text("Hello!\n");
|
||||
//richtext->pop();
|
||||
|
||||
richtext->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
|
||||
|
||||
|
||||
TabContainer * tabc = memnew( TabContainer );
|
||||
|
||||
Control *ctl= memnew( Control );
|
||||
ctl->set_name("tab 1");
|
||||
tabc->add_child(ctl);
|
||||
|
||||
ctl= memnew( Control );
|
||||
ctl->set_name("tab 2");
|
||||
tabc->add_child(ctl);
|
||||
label = memnew( Label );
|
||||
label->set_text("Some Label");
|
||||
label->set_pos( Point2(20,20) );
|
||||
ctl->add_child(label);;
|
||||
|
||||
ctl= memnew( Control );
|
||||
ctl->set_name("tab 3");
|
||||
button = memnew( Button );
|
||||
button->set_text("Some Button");
|
||||
button->set_pos( Point2(30,50) );
|
||||
ctl->add_child(button);;
|
||||
|
||||
tabc->add_child(ctl);
|
||||
|
||||
frame->add_child(tabc);
|
||||
|
||||
tabc->set_pos( Point2( 400,210 ) );
|
||||
tabc->set_size( Point2( 180,250 ) );
|
||||
|
||||
|
||||
Ref<ImageTexture> text = memnew( ImageTexture );
|
||||
text->load("test_data/concave.png");
|
||||
|
||||
Sprite* sprite = memnew(Sprite);
|
||||
sprite->set_texture(text);
|
||||
sprite->set_pos(Point2(300, 300));
|
||||
frame->add_child(sprite);
|
||||
sprite->show();
|
||||
|
||||
Sprite* sprite2 = memnew(Sprite);
|
||||
sprite->set_texture(text);
|
||||
sprite->add_child(sprite2);
|
||||
sprite2->set_pos(Point2(50, 50));
|
||||
sprite2->show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,19 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_GUI_H
|
||||
#define TEST_GUI_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
namespace TestGUI {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
77
bin/tests/test_image.cpp
Normal file
77
bin/tests/test_image.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*************************************************************************/
|
||||
/* test_image.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_image.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
#include "io/image_loader.h"
|
||||
namespace TestImage {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
bool quit;
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual void init() {
|
||||
|
||||
quit=false;
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
||||
virtual bool idle(float p_time) {
|
||||
return quit;
|
||||
}
|
||||
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
Image img;
|
||||
ImageLoader::load_image("as1.png",&img);
|
||||
|
||||
img.resize(512,512);
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
bin/tests/test_image.h
Normal file
44
bin/tests/test_image.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*************************************************************************/
|
||||
/* test_image.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_IMAGE_H
|
||||
#define TEST_IMAGE_H
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestImage {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
208
bin/tests/test_io.cpp
Normal file
208
bin/tests/test_io.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
/*************************************************************************/
|
||||
/* test_io.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_io.h"
|
||||
|
||||
#ifdef MINIZIP_ENABLED
|
||||
|
||||
|
||||
|
||||
#include "os/main_loop.h"
|
||||
#include "os/os.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "print_string.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/dir_access.h"
|
||||
#include "core/globals.h"
|
||||
|
||||
#include "io/file_access_memory.h"
|
||||
|
||||
namespace TestIO {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
|
||||
bool quit;
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
}
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
print_line("this is test io");
|
||||
DirAccess* da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
da->change_dir(".");
|
||||
print_line("Opening current dir "+ da->get_current_dir());
|
||||
String entry;
|
||||
da->list_dir_begin();
|
||||
while ( (entry = da->get_next()) != "") {
|
||||
|
||||
print_line("entry "+entry+" is dir: " + Variant(da->current_is_dir()));
|
||||
};
|
||||
da->list_dir_end();
|
||||
|
||||
RES texture = ResourceLoader::load("test_data/rock.png");
|
||||
ERR_FAIL_COND_V(texture.is_null(), NULL);
|
||||
|
||||
ResourceSaver::save("test_data/rock.xml",texture);
|
||||
|
||||
print_line("localize paths");
|
||||
print_line(Globals::get_singleton()->localize_path("algo.xml"));
|
||||
print_line(Globals::get_singleton()->localize_path("c:\\windows\\algo.xml"));
|
||||
print_line(Globals::get_singleton()->localize_path(Globals::get_singleton()->get_resource_path()+"/something/something.xml"));
|
||||
print_line(Globals::get_singleton()->localize_path("somedir/algo.xml"));
|
||||
|
||||
{
|
||||
|
||||
FileAccess* z = FileAccess::open("test_data/archive.zip", FileAccess::READ);
|
||||
int len = z->get_len();
|
||||
Vector<uint8_t> zip;
|
||||
zip.resize(len);
|
||||
z->get_buffer(&zip[0], len);
|
||||
z->close();
|
||||
memdelete(z);
|
||||
|
||||
FileAccessMemory::register_file("a_package", zip);
|
||||
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES);
|
||||
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM);
|
||||
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA);
|
||||
|
||||
print_line("archive test");
|
||||
#if 0
|
||||
Archive arch;
|
||||
|
||||
Archive::get_singleton()->add_package("a_package");
|
||||
FileAccessArchive f;
|
||||
|
||||
print_line("opening for read");
|
||||
f._open("file.txt", FileAccess::READ);
|
||||
int pos = f.get_pos();
|
||||
printf("file has %i bytes, initial pos %i\n", (int)f.get_len(), pos);
|
||||
|
||||
do {
|
||||
printf("%c", f.get_8());
|
||||
|
||||
} while (!f.eof_reached());
|
||||
|
||||
print_line("opening for stored seek");
|
||||
f.open("seek.bin", FileAccess::READ);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
f.seek(128);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
|
||||
print_line("opening for deflated seek");
|
||||
f.open("seek_deflated.bin", FileAccess::READ);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
f.seek(128);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
f.seek(256);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
f.seek(4);
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
pos = f.get_pos();
|
||||
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
|
||||
|
||||
f.close();
|
||||
|
||||
DirAccessArchive d;
|
||||
String dir = "../blah1/blah2/blahask/../blah3/.//blah4/";
|
||||
printf("changing dir to %s\n", dir.utf8().get_data());
|
||||
d.change_dir(dir);
|
||||
printf("current dir is %s\n", d.get_current_dir().utf8().get_data());
|
||||
|
||||
FileAccessMemory::cleanup();
|
||||
#endif
|
||||
};
|
||||
|
||||
print_line("test done");
|
||||
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace TestIO {
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
44
bin/tests/test_io.h
Normal file
44
bin/tests/test_io.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*************************************************************************/
|
||||
/* test_io.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_IO_H
|
||||
#define TEST_IO_H
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestIO {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
198
bin/tests/test_main.cpp
Normal file
198
bin/tests/test_main.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/*************************************************************************/
|
||||
/* test_main.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "list.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
#include "test_string.h"
|
||||
#include "test_containers.h"
|
||||
#include "test_math.h"
|
||||
#include "test_gui.h"
|
||||
#include "test_render.h"
|
||||
#include "test_sound.h"
|
||||
#include "test_misc.h"
|
||||
#include "test_physics.h"
|
||||
#include "test_physics_2d.h"
|
||||
#include "test_python.h"
|
||||
#include "test_io.h"
|
||||
#include "test_particles.h"
|
||||
#include "test_detailer.h"
|
||||
#include "test_shader_lang.h"
|
||||
#include "test_gdscript.h"
|
||||
#include "test_image.h"
|
||||
|
||||
|
||||
const char ** tests_get_names() {
|
||||
|
||||
static const char* test_names[]={
|
||||
"string",
|
||||
"containers",
|
||||
"math",
|
||||
"render",
|
||||
"particles",
|
||||
"multimesh",
|
||||
"gui",
|
||||
"io",
|
||||
"shaderlang",
|
||||
"physics",
|
||||
NULL
|
||||
};
|
||||
|
||||
return test_names;
|
||||
}
|
||||
|
||||
MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
|
||||
|
||||
if (p_test=="string") {
|
||||
|
||||
return TestString::test();
|
||||
}
|
||||
|
||||
if (p_test=="containers") {
|
||||
|
||||
return TestContainers::test();
|
||||
}
|
||||
|
||||
if (p_test=="math") {
|
||||
|
||||
return TestMath::test();
|
||||
}
|
||||
|
||||
if (p_test=="physics") {
|
||||
|
||||
return TestPhysics::test();
|
||||
}
|
||||
|
||||
if (p_test=="physics_2d") {
|
||||
|
||||
return TestPhysics2D::test();
|
||||
}
|
||||
|
||||
if (p_test=="misc") {
|
||||
|
||||
return TestMisc::test();
|
||||
}
|
||||
|
||||
if (p_test=="render") {
|
||||
|
||||
return TestRender::test();
|
||||
}
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (p_test=="gui") {
|
||||
|
||||
return TestGUI::test();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_test=="sound") {
|
||||
|
||||
return TestSound::test();
|
||||
}
|
||||
|
||||
if (p_test=="io") {
|
||||
|
||||
return TestIO::test();
|
||||
}
|
||||
|
||||
if (p_test=="particles") {
|
||||
|
||||
return TestParticles::test();
|
||||
}
|
||||
|
||||
if (p_test=="multimesh") {
|
||||
|
||||
return TestMultiMesh::test();
|
||||
}
|
||||
|
||||
if (p_test=="shaderlang") {
|
||||
|
||||
return TestShaderLang::test();
|
||||
}
|
||||
|
||||
if (p_test=="gd_tokenizer") {
|
||||
|
||||
return TestGDScript::test(TestGDScript::TEST_TOKENIZER);
|
||||
}
|
||||
|
||||
if (p_test=="gd_parser") {
|
||||
|
||||
return TestGDScript::test(TestGDScript::TEST_PARSER);
|
||||
}
|
||||
|
||||
if (p_test=="gd_compiler") {
|
||||
|
||||
return TestGDScript::test(TestGDScript::TEST_COMPILER);
|
||||
}
|
||||
|
||||
if (p_test=="gd_bytecode") {
|
||||
|
||||
return TestGDScript::test(TestGDScript::TEST_BYTECODE);
|
||||
}
|
||||
|
||||
if (p_test=="image") {
|
||||
|
||||
return TestImage::test();
|
||||
}
|
||||
|
||||
if (p_test=="detailer") {
|
||||
|
||||
return TestMultiMesh::test();
|
||||
}
|
||||
|
||||
#ifdef PYTHON_ENABLED
|
||||
|
||||
if (p_test=="python") {
|
||||
|
||||
return TestPython::test();
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const char ** tests_get_names() {
|
||||
|
||||
static const char* test_names[]={
|
||||
NULL
|
||||
};
|
||||
|
||||
return test_names;
|
||||
}
|
||||
|
||||
MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,14 +26,16 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_MAIN_H
|
||||
#define TEST_MAIN_H
|
||||
|
||||
#include "core/list.h"
|
||||
#include "core/ustring.h"
|
||||
#include "ustring.h"
|
||||
#include "list.h"
|
||||
|
||||
const char ** tests_get_names();
|
||||
MainLoop* test_main(String p_test,const List<String>& p_args);
|
||||
|
||||
const char **tests_get_names();
|
||||
MainLoop *test_main(String p_test, const List<String> &p_args);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
382
bin/tests/test_math.cpp
Normal file
382
bin/tests/test_math.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
/*************************************************************************/
|
||||
/* test_math.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_math.h"
|
||||
#include "ustring.h"
|
||||
#include "print_string.h"
|
||||
#include "transform.h"
|
||||
#include "matrix3.h"
|
||||
#include "math_funcs.h"
|
||||
#include "camera_matrix.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "variant.h"
|
||||
#include "servers/visual/shader_language.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "vmap.h"
|
||||
#include "os/os.h"
|
||||
namespace TestMath {
|
||||
|
||||
|
||||
void test_vec(Plane p_vec) {
|
||||
|
||||
|
||||
CameraMatrix cm;
|
||||
cm.set_perspective(45,1,0,100);
|
||||
Plane v0=cm.xform4(p_vec);
|
||||
|
||||
print_line("out: "+v0);
|
||||
v0.normal.z = (v0.d/100.0 *2.0-1.0) * v0.d;
|
||||
print_line("out_F: "+v0);
|
||||
|
||||
|
||||
/*v0: 0, 0, -0.1, 0.1
|
||||
v1: 0, 0, 0, 0.1
|
||||
fix: 0, 0, 0, 0.1
|
||||
v0: 0, 0, 1.302803, 1.5
|
||||
v1: 0, 0, 1.401401, 1.5
|
||||
fix: 0, 0, 1.401401, 1.5
|
||||
v0: 0, 0, 25.851850, 26
|
||||
v1: 0, 0, 25.925926, 26
|
||||
fix: 0, 0, 25.925924, 26
|
||||
v0: 0, 0, 49.899902, 50
|
||||
v1: 0, 0, 49.949947, 50
|
||||
fix: 0, 0, 49.949951, 50
|
||||
v0: 0, 0, 100, 100
|
||||
v1: 0, 0, 100, 100
|
||||
fix: 0, 0, 100, 100
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint32_t ihash( uint32_t a)
|
||||
{
|
||||
a = (a+0x7ed55d16) + (a<<12);
|
||||
a = (a^0xc761c23c) ^ (a>>19);
|
||||
a = (a+0x165667b1) + (a<<5);
|
||||
a = (a+0xd3a2646c) ^ (a<<9);
|
||||
a = (a+0xfd7046c5) + (a<<3);
|
||||
a = (a^0xb55a4f09) ^ (a>>16);
|
||||
return a;
|
||||
}
|
||||
|
||||
uint32_t ihash2( uint32_t a) {
|
||||
a = (a ^ 61) ^ (a >> 16);
|
||||
a = a + (a << 3);
|
||||
a = a ^ (a >> 4);
|
||||
a = a * 0x27d4eb2d;
|
||||
a = a ^ (a >> 15);
|
||||
return a;
|
||||
}
|
||||
|
||||
uint32_t ihash3( uint32_t a)
|
||||
{
|
||||
a = (a+0x479ab41d) + (a<<8);
|
||||
a = (a^0xe4aa10ce) ^ (a>>5);
|
||||
a = (a+0x9942f0a6) - (a<<14);
|
||||
a = (a^0x5aedd67d) ^ (a>>3);
|
||||
a = (a+0x17bea992) + (a<<7);
|
||||
return a;
|
||||
}
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
{
|
||||
|
||||
Vector<int32_t> hashes;
|
||||
List<StringName> tl;
|
||||
ObjectTypeDB::get_type_list(&tl);
|
||||
|
||||
|
||||
for (List<StringName>::Element *E=tl.front();E;E=E->next()) {
|
||||
|
||||
Vector<uint8_t> m5b = E->get().operator String().md5_buffer();
|
||||
uint32_t *ub = (uint32_t*)m5b.ptr();
|
||||
//hashes.push_back(ihash(ihash2(ihash3(*ub))));
|
||||
hashes.push_back(hashes.size());
|
||||
//hashes.push_back(E->get().hash());
|
||||
|
||||
}
|
||||
|
||||
//hashes.resize(50);
|
||||
|
||||
for(int i=nearest_shift(hashes.size());i<20;i++) {
|
||||
|
||||
bool success=true;
|
||||
for(int s=0;s<10000;s++) {
|
||||
Set<uint32_t> existing;
|
||||
success=true;
|
||||
|
||||
for(int j=0;j<hashes.size();j++) {
|
||||
|
||||
uint32_t eh = ihash2(ihash3(hashes[j]+ihash(s)+s))&((1<<i)-1);
|
||||
if (existing.has(eh)) {
|
||||
success=false;
|
||||
break;
|
||||
}
|
||||
existing.insert(eh);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
print_line("success at "+itos(i)+"/"+itos(nearest_shift(hashes.size()))+" shift "+itos(s));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
break;
|
||||
}
|
||||
|
||||
print_line("DONE");
|
||||
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
|
||||
|
||||
// print_line("NUM: "+itos(237641278346127));
|
||||
print_line("NUM: "+itos(-128));
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
Vector3 v(1,2,3);
|
||||
v.normalize();
|
||||
float a=0.3;
|
||||
|
||||
//Quat q(v,a);
|
||||
Matrix3 m(v,a);
|
||||
|
||||
Vector3 v2(7,3,1);
|
||||
v2.normalize();
|
||||
float a2=0.8;
|
||||
|
||||
//Quat q(v,a);
|
||||
Matrix3 m2(v2,a2);
|
||||
|
||||
Quat q=m;
|
||||
Quat q2=m2;
|
||||
|
||||
Matrix3 m3 = m.inverse() * m2;
|
||||
Quat q3 = (q.inverse() * q2);//.normalized();
|
||||
|
||||
print_line(Quat(m3));
|
||||
print_line(q3);
|
||||
|
||||
print_line("before v: "+v+" a: "+rtos(a));
|
||||
q.get_axis_and_angle(v,a);
|
||||
print_line("after v: "+v+" a: "+rtos(a));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
String ret;
|
||||
|
||||
List<String> args;
|
||||
args.push_back("-l");
|
||||
Error err = OS::get_singleton()->execute("/bin/ls",args,true,NULL,&ret);
|
||||
print_line("error: "+itos(err));
|
||||
print_line(ret);
|
||||
|
||||
return NULL;
|
||||
Matrix3 m3;
|
||||
m3.rotate(Vector3(1,0,0),0.2);
|
||||
m3.rotate(Vector3(0,1,0),1.77);
|
||||
m3.rotate(Vector3(0,0,1),212);
|
||||
Matrix3 m32;
|
||||
m32.set_euler(m3.get_euler());
|
||||
print_line("ELEULEEEEEEEEEEEEEEEEEER: "+m3.get_euler()+" vs "+m32.get_euler());
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
{
|
||||
|
||||
Dictionary d;
|
||||
d["momo"]=1;
|
||||
Dictionary b=d;
|
||||
b["44"]=4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return NULL;
|
||||
print_line("inters: "+rtos(Geometry::segment_intersects_circle(Vector2(-5,0),Vector2(-2,0),Vector2(),1.0)));
|
||||
|
||||
|
||||
|
||||
print_line("cross: "+Vector3(1,2,3).cross(Vector3(4,5,7)));
|
||||
print_line("dot: "+rtos(Vector3(1,2,3).dot(Vector3(4,5,7))));
|
||||
print_line("abs: "+Vector3(-1,2,-3).abs());
|
||||
print_line("distance_to: "+rtos(Vector3(1,2,3).distance_to(Vector3(4,5,7))));
|
||||
print_line("distance_squared_to: "+rtos(Vector3(1,2,3).distance_squared_to(Vector3(4,5,7))));
|
||||
print_line("plus: "+(Vector3(1,2,3)+Vector3(Vector3(4,5,7))));
|
||||
print_line("minus: "+(Vector3(1,2,3)-Vector3(Vector3(4,5,7))));
|
||||
print_line("mul: "+(Vector3(1,2,3)*Vector3(Vector3(4,5,7))));
|
||||
print_line("div: "+(Vector3(1,2,3)/Vector3(Vector3(4,5,7))));
|
||||
print_line("mul scalar: "+(Vector3(1,2,3)*2));
|
||||
print_line("premul scalar: "+(2*Vector3(1,2,3)));
|
||||
print_line("div scalar: "+(Vector3(1,2,3)/3.0));
|
||||
print_line("length: "+rtos(Vector3(1,2,3).length()));
|
||||
print_line("length squared: "+rtos(Vector3(1,2,3).length_squared()));
|
||||
print_line("normalized: "+Vector3(1,2,3).normalized());
|
||||
print_line("inverse: "+Vector3(1,2,3).inverse());
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v.normalize();
|
||||
print_line("normalize: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v+=Vector3(1,2,3);
|
||||
print_line("+=: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v-=Vector3(1,2,3);
|
||||
print_line("-=: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v*=Vector3(1,2,3);
|
||||
print_line("*=: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v/=Vector3(1,2,3);
|
||||
print_line("/=: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v*=2.0;
|
||||
print_line("scalar *=: "+v);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 v(4,5,7);
|
||||
v/=2.0;
|
||||
print_line("scalar /=: "+v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
print_line(String("C:\\momo\\.\\popo\\..\\gongo").simplify_path());
|
||||
print_line(String("res://../popo/..//gongo").simplify_path());
|
||||
print_line(String("res://..").simplify_path());
|
||||
|
||||
|
||||
DVector<uint8_t> a;
|
||||
DVector<uint8_t> b;
|
||||
|
||||
a.resize(20);
|
||||
b=a;
|
||||
b.resize(30);
|
||||
a=b;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
String za = String::utf8("á");
|
||||
printf("unicode: %x\n",za[0]);
|
||||
CharString cs=za.utf8();
|
||||
for(int i=0;i<cs.size();i++) {
|
||||
uint32_t v = uint8_t(cs[i]);
|
||||
printf("%i - %x\n",i,v);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
print_line(String("C:\\window\\system\\momo").path_to("C:\\window\\momonga"));
|
||||
print_line(String("res://momo/sampler").path_to("res://pindonga"));
|
||||
print_line(String("/margarito/terere").path_to("/margarito/pilates"));
|
||||
print_line(String("/algo").path_to("/algo"));
|
||||
print_line(String("c:").path_to("c:\\"));
|
||||
print_line(String("/").path_to("/"));
|
||||
|
||||
|
||||
print_line(itos(sizeof(Variant)));
|
||||
return NULL;
|
||||
|
||||
Vector<StringName> path;
|
||||
path.push_back("three");
|
||||
path.push_back("two");
|
||||
path.push_back("one");
|
||||
path.push_back("comeon");
|
||||
path.revert();
|
||||
|
||||
NodePath np(path,true);
|
||||
|
||||
print_line(np);
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
bool a=2;
|
||||
|
||||
print_line(Variant(a));
|
||||
|
||||
|
||||
Matrix32 mat2_1;
|
||||
mat2_1.rotate(0.5);
|
||||
Matrix32 mat2_2;
|
||||
mat2_2.translate(Vector2(1,2));
|
||||
Matrix32 mat2_3 = mat2_1 * mat2_2;
|
||||
mat2_3.affine_invert();
|
||||
|
||||
print_line(mat2_3.elements[0]);
|
||||
print_line(mat2_3.elements[1]);
|
||||
print_line(mat2_3.elements[2]);
|
||||
|
||||
|
||||
|
||||
Transform mat3_1;
|
||||
mat3_1.basis.rotate(Vector3(0,0,1),0.5);
|
||||
Transform mat3_2;
|
||||
mat3_2.translate(Vector3(1,2,0));
|
||||
Transform mat3_3 = mat3_1 * mat3_2;
|
||||
mat3_3.affine_invert();
|
||||
|
||||
print_line(mat3_3.basis.get_axis(0));
|
||||
print_line(mat3_3.basis.get_axis(1));
|
||||
print_line(mat3_3.origin);
|
||||
|
||||
#endif
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,15 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_MATH_H
|
||||
#define TEST_MATH_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestMath {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
499
bin/tests/test_misc.cpp
Normal file
499
bin/tests/test_misc.cpp
Normal file
@ -0,0 +1,499 @@
|
||||
/*************************************************************************/
|
||||
/* test_misc.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_misc.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
|
||||
|
||||
namespace TestMisc {
|
||||
|
||||
struct ConvexTestResult
|
||||
{
|
||||
|
||||
Vector3 edgeA[2];
|
||||
Vector3 edgeB[2];
|
||||
bool valid;
|
||||
Vector3 contactA;
|
||||
Vector3 contactB;
|
||||
Vector3 contactNormal;
|
||||
float depth;
|
||||
|
||||
/*
|
||||
Vector3 contactA;
|
||||
Vector3 contactB;
|
||||
Vector3 contactNormal;
|
||||
Vector3 contactX;
|
||||
Vector3 contactY;
|
||||
Vector3 edgeA[2];
|
||||
Vector3 edgeB[2];
|
||||
float depth;
|
||||
bool valid;
|
||||
bool isEdgeEdge;
|
||||
bool needTransform;
|
||||
neBool ComputerEdgeContactPoint(ConvexTestResult & res);
|
||||
neBool ComputerEdgeContactPoint2(float & au, float & bu);
|
||||
void Reverse()
|
||||
{
|
||||
neSwap(contactA, contactB);
|
||||
contactNormal *= -1.0f;
|
||||
}*/
|
||||
bool ComputerEdgeContactPoint2(float & au, float & bu);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool ConvexTestResult::ComputerEdgeContactPoint2(float & au, float & bu)
|
||||
{
|
||||
float d1343, d4321, d1321, d4343, d2121;
|
||||
float numer, denom;
|
||||
|
||||
Vector3 p13;
|
||||
Vector3 p43;
|
||||
Vector3 p21;
|
||||
Vector3 diff;
|
||||
|
||||
p13 = (edgeA[0]) - (edgeB[0]);
|
||||
p43 = (edgeB[1]) - (edgeB[0]);
|
||||
|
||||
if ( p43.length_squared() < CMP_EPSILON2 )
|
||||
{
|
||||
valid = false;
|
||||
goto ComputerEdgeContactPoint2_Exit;
|
||||
}
|
||||
|
||||
p21 = (edgeA[1]) - (edgeA[0]);
|
||||
|
||||
if ( p21.length_squared()<CMP_EPSILON2 )
|
||||
{
|
||||
valid = false;
|
||||
goto ComputerEdgeContactPoint2_Exit;
|
||||
}
|
||||
|
||||
d1343 = p13.dot(p43);
|
||||
d4321 = p43.dot(p21);
|
||||
d1321 = p13.dot(p21);
|
||||
d4343 = p43.dot(p43);
|
||||
d2121 = p21.dot(p21);
|
||||
|
||||
denom = d2121 * d4343 - d4321 * d4321;
|
||||
|
||||
if (ABS(denom) < CMP_EPSILON)
|
||||
{
|
||||
valid = false;
|
||||
|
||||
goto ComputerEdgeContactPoint2_Exit;
|
||||
}
|
||||
|
||||
numer = d1343 * d4321 - d1321 * d4343;
|
||||
au = numer / denom;
|
||||
bu = (d1343 + d4321 * (au)) / d4343;
|
||||
|
||||
if (au < 0.0f || au >= 1.0f)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
else if (bu < 0.0f || bu >= 1.0f)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = true;
|
||||
}
|
||||
{
|
||||
Vector3 tmpv;
|
||||
|
||||
tmpv = p21 * au;
|
||||
contactA = (edgeA[0]) + tmpv;
|
||||
|
||||
tmpv = p43 * bu;
|
||||
contactB = (edgeB[0]) + tmpv;
|
||||
}
|
||||
|
||||
diff = contactA - contactB;
|
||||
|
||||
depth = Math::sqrt(diff.dot(diff));
|
||||
|
||||
return true;
|
||||
|
||||
ComputerEdgeContactPoint2_Exit:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct neCollisionResult {
|
||||
|
||||
float depth;
|
||||
bool penetrate;
|
||||
Matrix3 collisionFrame;
|
||||
Vector3 contactA;
|
||||
Vector3 contactB;
|
||||
};
|
||||
|
||||
|
||||
struct TConvex {
|
||||
|
||||
float radius;
|
||||
float half_height;
|
||||
float CylinderRadius() const { return radius; }
|
||||
float CylinderHalfHeight() const { return half_height; }
|
||||
};
|
||||
|
||||
float GetDistanceFromLine2(Vector3 v, Vector3 & project, const Vector3 & pointA, const Vector3 & pointB)
|
||||
{
|
||||
Vector3 ba = pointB - pointA;
|
||||
|
||||
float len = ba.length();
|
||||
|
||||
if (len<CMP_EPSILON)
|
||||
ba=Vector3();
|
||||
else
|
||||
ba *= 1.0f / len;
|
||||
|
||||
Vector3 pa = v - pointA;
|
||||
|
||||
float k = pa.dot(ba);
|
||||
|
||||
project = pointA + ba * k;
|
||||
|
||||
Vector3 diff = v - project;
|
||||
|
||||
return diff.length();
|
||||
}
|
||||
|
||||
void TestCylinderVertEdge(neCollisionResult & result, Vector3 & edgeA1, Vector3 & edgeA2, Vector3 & vertB,
|
||||
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB, bool flip)
|
||||
{
|
||||
Vector3 project;
|
||||
|
||||
float dist = GetDistanceFromLine2(vertB,project, edgeA1, edgeA2);
|
||||
|
||||
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
|
||||
|
||||
if (depth <= 0.0f)
|
||||
return;
|
||||
|
||||
if (depth <= result.depth)
|
||||
return;
|
||||
|
||||
result.penetrate = true;
|
||||
|
||||
result.depth = depth;
|
||||
|
||||
if (!flip)
|
||||
{
|
||||
result.collisionFrame.set_axis(2,(project - vertB).normalized());
|
||||
|
||||
result.contactA = project - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
|
||||
|
||||
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
result.collisionFrame.set_axis(2,(vertB - project).normalized());
|
||||
|
||||
result.contactA = vertB - result.collisionFrame.get_axis(2) * cB.CylinderRadius();
|
||||
|
||||
result.contactB = project + result.collisionFrame.get_axis(2) * cA.CylinderRadius();
|
||||
}
|
||||
}
|
||||
|
||||
void TestCylinderVertVert(neCollisionResult & result, Vector3 & vertA, Vector3 & vertB,
|
||||
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB)
|
||||
{
|
||||
Vector3 diff = vertA - vertB;
|
||||
|
||||
float dist = diff.length();
|
||||
|
||||
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
|
||||
|
||||
if (depth <= 0.0f)
|
||||
return;
|
||||
|
||||
if (depth <= result.depth)
|
||||
return;
|
||||
|
||||
result.penetrate = true;
|
||||
|
||||
result.depth = depth;
|
||||
|
||||
result.collisionFrame.set_axis(2, diff * (1.0f / dist));
|
||||
|
||||
result.contactA = vertA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
|
||||
|
||||
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
|
||||
}
|
||||
|
||||
void Cylinder2CylinderTest(neCollisionResult & result, TConvex & cA, Transform & transA, TConvex & cB, Transform & transB)
|
||||
{
|
||||
result.penetrate = false;
|
||||
|
||||
Vector3 dir = transA.basis.get_axis(1).cross(transB.basis.get_axis(1));
|
||||
|
||||
float len = dir.length();
|
||||
|
||||
// bool isParallel = len<CMP_EPSILON;
|
||||
|
||||
// int doVertCheck = 0;
|
||||
|
||||
ConvexTestResult cr;
|
||||
|
||||
cr.edgeA[0] = transA.origin + transA.basis.get_axis(1) * cA.CylinderHalfHeight();
|
||||
cr.edgeA[1] = transA.origin - transA.basis.get_axis(1) * cA.CylinderHalfHeight();
|
||||
cr.edgeB[0] = transB.origin + transB.basis.get_axis(1) * cB.CylinderHalfHeight();
|
||||
cr.edgeB[1] = transB.origin - transB.basis.get_axis(1) * cB.CylinderHalfHeight();
|
||||
|
||||
// float dot = transA.basis.get_axis(1).dot(transB.basis.get_axis(1));
|
||||
|
||||
if (len>CMP_EPSILON)
|
||||
{
|
||||
float au, bu;
|
||||
|
||||
cr.ComputerEdgeContactPoint2(au, bu);
|
||||
|
||||
if (cr.valid)
|
||||
{
|
||||
float depth = cA.CylinderRadius() + cB.CylinderRadius() - cr.depth;
|
||||
|
||||
if (depth <= 0.0f)
|
||||
return;
|
||||
|
||||
result.depth = depth;
|
||||
|
||||
result.penetrate = true;
|
||||
|
||||
result.collisionFrame.set_axis(2, (cr.contactA - cr.contactB)*(1.0f / cr.depth));
|
||||
|
||||
result.contactA = cr.contactA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
|
||||
|
||||
result.contactB = cr.contactB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
result.depth = -1.0e6f;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
//project onto edge b
|
||||
|
||||
Vector3 diff = cr.edgeA[i] - cr.edgeB[1];
|
||||
|
||||
float dot = diff.dot(transB.basis.get_axis(1));
|
||||
|
||||
if (dot < 0.0f)
|
||||
{
|
||||
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[1], cA, cB, transA, transB);
|
||||
}
|
||||
else if (dot > (2.0f * cB.CylinderHalfHeight()))
|
||||
{
|
||||
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[0], cA, cB, transA, transB);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestCylinderVertEdge(result, cr.edgeB[0], cr.edgeB[1], cr.edgeA[i], cB, cA, transB, transA, true);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
//project onto edge b
|
||||
|
||||
Vector3 diff = cr.edgeB[i] - cr.edgeA[1];
|
||||
|
||||
float dot = diff.dot(transA.basis.get_axis(1));
|
||||
|
||||
if (dot < 0.0f)
|
||||
{
|
||||
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[1], cA, cB, transA, transB);
|
||||
}
|
||||
else if (dot > (2.0f * cB.CylinderHalfHeight()))
|
||||
{
|
||||
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[0], cA, cB, transA, transB);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestCylinderVertEdge(result, cr.edgeA[0], cr.edgeA[1], cr.edgeB[i], cA, cB, transA, transB, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
RID meshA;
|
||||
RID meshB;
|
||||
RID poly;
|
||||
RID instance;
|
||||
RID camera;
|
||||
RID viewport;
|
||||
RID boxA;
|
||||
RID boxB;
|
||||
RID scenario;
|
||||
|
||||
Transform rot_a;
|
||||
Transform rot_b;
|
||||
|
||||
bool quit;
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
|
||||
|
||||
rot_b.origin.y+=-p_event.mouse_motion.relative_y/100.0;
|
||||
rot_b.origin.x+=p_event.mouse_motion.relative_x/100.0;
|
||||
}
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_MIDDLE) {
|
||||
|
||||
//rot_b.origin.x+=-p_event.mouse_motion.relative_y/100.0;
|
||||
rot_b.origin.z+=p_event.mouse_motion.relative_x/100.0;
|
||||
}
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_RIGHT) {
|
||||
|
||||
float rot_x=-p_event.mouse_motion.relative_y/100.0;
|
||||
float rot_y=p_event.mouse_motion.relative_x/100.0;
|
||||
rot_b.basis = rot_b.basis * Matrix3(Vector3(1,0,0),rot_x) * Matrix3(Vector3(0,1,0),rot_y);
|
||||
}
|
||||
|
||||
}
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,3 ) ) );
|
||||
|
||||
/* CONVEX SHAPE */
|
||||
|
||||
DVector<Plane> cylinder_planes = Geometry::build_cylinder_planes(0.5,2,9,Vector3::AXIS_Y);
|
||||
RID cylinder_material = vs->fixed_material_create();
|
||||
vs->fixed_material_set_param( cylinder_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
|
||||
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_ONTOP,true);
|
||||
//vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_WIREFRAME,true);
|
||||
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_DOUBLE_SIDED,true);
|
||||
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_UNSHADED,true);
|
||||
|
||||
RID cylinder_mesh = vs->mesh_create();
|
||||
Geometry::MeshData cylinder_data = Geometry::build_convex_mesh(cylinder_planes);
|
||||
vs->mesh_add_surface_from_mesh_data(cylinder_mesh,cylinder_data);
|
||||
vs->mesh_surface_set_material( cylinder_mesh, 0, cylinder_material );
|
||||
|
||||
meshA=vs->instance_create2(cylinder_mesh,scenario);
|
||||
meshB=vs->instance_create2(cylinder_mesh,scenario);
|
||||
boxA=vs->instance_create2(vs->get_test_cube(),scenario);
|
||||
boxB=vs->instance_create2(vs->get_test_cube(),scenario);
|
||||
|
||||
/*
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
|
||||
light = vs->instance_create2( lightaux );
|
||||
*/
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
//vs->light_set_shadow( lightaux, true );
|
||||
RID light = vs->instance_create2( lightaux,scenario );
|
||||
|
||||
//rot_a=Transform(Matrix3(Vector3(1,0,0),Math_PI/2.0),Vector3());
|
||||
rot_b=Transform(Matrix3(),Vector3(2,0,0));
|
||||
|
||||
//rot_x=0;
|
||||
//rot_y=0;
|
||||
quit=false;
|
||||
}
|
||||
virtual bool idle(float p_time) {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
vs->instance_set_transform(meshA,rot_a);
|
||||
vs->instance_set_transform(meshB,rot_b);
|
||||
|
||||
|
||||
neCollisionResult res;
|
||||
TConvex a;
|
||||
a.radius=0.5;
|
||||
a.half_height=1;
|
||||
Cylinder2CylinderTest(res,a,rot_a,a,rot_b);
|
||||
if (res.penetrate) {
|
||||
|
||||
Matrix3 scale;
|
||||
scale.scale(Vector3(0.1,0.1,0.1));
|
||||
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
|
||||
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
|
||||
print_line("depth: "+rtos(res.depth));
|
||||
} else {
|
||||
|
||||
Matrix3 scale;
|
||||
scale.scale(Vector3());
|
||||
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
|
||||
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
|
||||
|
||||
}
|
||||
print_line("collided: "+itos(res.penetrate));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
40
bin/tests/test_misc.h
Normal file
40
bin/tests/test_misc.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*************************************************************************/
|
||||
/* test_misc.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_MISC_H
|
||||
#define TEST_MISC_H
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestMisc {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
121
bin/tests/test_particles.cpp
Normal file
121
bin/tests/test_particles.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*************************************************************************/
|
||||
/* test_particles.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_particles.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
|
||||
namespace TestParticles {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
RID particles;
|
||||
RID instance;
|
||||
RID camera;
|
||||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
}
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
particles = vs->particles_create();
|
||||
vs->particles_set_amount(particles,1000);
|
||||
|
||||
instance = vs->instance_create2(particles,scenario);
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,20 ) ) );
|
||||
/*
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
|
||||
light = vs->instance_create2( lightaux );
|
||||
*/
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
light = vs->instance_create2( lightaux, scenario );
|
||||
|
||||
ofs=0;
|
||||
quit=false;
|
||||
}
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
// VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
ofs+=p_time;
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
43
bin/tests/test_particles.h
Normal file
43
bin/tests/test_particles.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*************************************************************************/
|
||||
/* test_particles.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_PARTICLES_H
|
||||
#define TEST_PARTICLES_H
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestParticles {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
662
bin/tests/test_physics.cpp
Normal file
662
bin/tests/test_physics.cpp
Normal file
@ -0,0 +1,662 @@
|
||||
/*************************************************************************/
|
||||
/* test_physics.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_physics.h"
|
||||
|
||||
|
||||
#include "servers/visual_server.h"
|
||||
#include "servers/physics_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
#include "map.h"
|
||||
#include "os/os.h"
|
||||
#include "quick_hull.h"
|
||||
|
||||
class TestPhysicsMainLoop : public MainLoop {
|
||||
|
||||
OBJ_TYPE( TestPhysicsMainLoop, MainLoop );
|
||||
|
||||
enum {
|
||||
LINK_COUNT = 20,
|
||||
};
|
||||
|
||||
RID test_cube;
|
||||
|
||||
RID plane;
|
||||
RID sphere;
|
||||
RID light;
|
||||
RID camera;
|
||||
RID mover;
|
||||
RID scenario;
|
||||
RID space;
|
||||
|
||||
RID character;
|
||||
|
||||
float ofs_x,ofs_y;
|
||||
|
||||
Point2 joy_direction;
|
||||
|
||||
List<RID> bodies;
|
||||
Map<PhysicsServer::ShapeType,RID> type_shape_map;
|
||||
Map<PhysicsServer::ShapeType,RID> type_mesh_map;
|
||||
|
||||
void body_changed_transform(Object *p_state, RID p_visual_instance) {
|
||||
|
||||
PhysicsDirectBodyState *state = (PhysicsDirectBodyState*)p_state;
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
Transform t=state->get_transform();
|
||||
//t.basis.scale( Vector3(1.0,0.5,0.2) );
|
||||
vs->instance_set_transform(p_visual_instance,t);
|
||||
}
|
||||
|
||||
bool quit;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
|
||||
}
|
||||
|
||||
RID create_body(PhysicsServer::ShapeType p_shape, PhysicsServer::BodyMode p_body,const Transform p_location,bool p_active_default=true,const Transform&p_shape_xform=Transform()) {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
|
||||
RID body = ps->body_create(p_body,!p_active_default);
|
||||
ps->body_set_space(body,space);
|
||||
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
|
||||
//todo set space
|
||||
ps->body_add_shape(body,type_shape_map[p_shape]);
|
||||
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
|
||||
|
||||
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
|
||||
bodies.push_back(body);
|
||||
|
||||
if (p_body==PhysicsServer::BODY_MODE_STATIC) {
|
||||
|
||||
vs->instance_set_transform(mesh_instance,p_location);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
RID create_static_plane(const Plane& p_plane) {
|
||||
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
RID plane_shape = ps->shape_create(PhysicsServer::SHAPE_PLANE);;
|
||||
ps->shape_set_data( plane_shape, p_plane );
|
||||
|
||||
RID b = ps->body_create( PhysicsServer::BODY_MODE_STATIC );
|
||||
ps->body_set_space(b,space);
|
||||
//todo set space
|
||||
ps->body_add_shape(b, plane_shape);
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
void configure_body(RID p_body,float p_mass, float p_friction, float p_bounce) {
|
||||
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_MASS, p_mass );
|
||||
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_FRICTION, p_friction );
|
||||
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_BOUNCE, p_bounce );
|
||||
|
||||
}
|
||||
|
||||
void init_shapes() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
/* SPHERE SHAPE */
|
||||
RID sphere_mesh = vs->make_sphere_mesh(10,20,0.5);
|
||||
RID sphere_material = vs->fixed_material_create();
|
||||
//vs->material_set_flag( sphere_material, VisualServer::MATERIAL_FLAG_WIREFRAME, true );
|
||||
vs->fixed_material_set_param( sphere_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.7,0.8,3.0) );
|
||||
vs->mesh_surface_set_material( sphere_mesh, 0, sphere_material );
|
||||
type_mesh_map[PhysicsServer::SHAPE_SPHERE]=sphere_mesh;
|
||||
|
||||
RID sphere_shape=ps->shape_create(PhysicsServer::SHAPE_SPHERE);
|
||||
ps->shape_set_data( sphere_shape, 0.5 );
|
||||
type_shape_map[PhysicsServer::SHAPE_SPHERE]=sphere_shape;
|
||||
|
||||
/* BOX SHAPE */
|
||||
|
||||
DVector<Plane> box_planes = Geometry::build_box_planes(Vector3(0.5,0.5,0.5));
|
||||
RID box_material = vs->fixed_material_create();
|
||||
vs->fixed_material_set_param( box_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.2,0.2) );
|
||||
RID box_mesh = vs->mesh_create();
|
||||
Geometry::MeshData box_data = Geometry::build_convex_mesh(box_planes);
|
||||
vs->mesh_add_surface_from_mesh_data(box_mesh,box_data);
|
||||
vs->mesh_surface_set_material( box_mesh, 0, box_material );
|
||||
type_mesh_map[PhysicsServer::SHAPE_BOX]=box_mesh;
|
||||
|
||||
RID box_shape=ps->shape_create(PhysicsServer::SHAPE_BOX);
|
||||
ps->shape_set_data( box_shape, Vector3(0.5,0.5,0.5) );
|
||||
type_shape_map[PhysicsServer::SHAPE_BOX]=box_shape;
|
||||
|
||||
|
||||
/* CAPSULE SHAPE */
|
||||
|
||||
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,0.7,12,Vector3::AXIS_Z);
|
||||
RID capsule_material = vs->fixed_material_create();
|
||||
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.3,0.4,1.0) );
|
||||
|
||||
RID capsule_mesh = vs->mesh_create();
|
||||
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
|
||||
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
|
||||
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
|
||||
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
|
||||
|
||||
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);
|
||||
Dictionary capsule_params;
|
||||
capsule_params["radius"]=0.5;
|
||||
capsule_params["height"]=1.4;
|
||||
ps->shape_set_data( capsule_shape, capsule_params );
|
||||
type_shape_map[PhysicsServer::SHAPE_CAPSULE]=capsule_shape;
|
||||
|
||||
/* CONVEX SHAPE */
|
||||
|
||||
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,5,Vector3::AXIS_Z);
|
||||
RID convex_material = vs->fixed_material_create();
|
||||
vs->fixed_material_set_param( convex_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
|
||||
|
||||
RID convex_mesh = vs->mesh_create();
|
||||
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
|
||||
QuickHull::build(convex_data.vertices,convex_data);
|
||||
vs->mesh_add_surface_from_mesh_data(convex_mesh,convex_data);
|
||||
vs->mesh_surface_set_material( convex_mesh, 0, convex_material );
|
||||
type_mesh_map[PhysicsServer::SHAPE_CONVEX_POLYGON]=convex_mesh;
|
||||
|
||||
RID convex_shape=ps->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON);
|
||||
ps->shape_set_data( convex_shape, convex_data.vertices );
|
||||
type_shape_map[PhysicsServer::SHAPE_CONVEX_POLYGON]=convex_shape;
|
||||
|
||||
}
|
||||
|
||||
void make_trimesh(Vector<Vector3> p_faces,const Transform& p_xform=Transform()) {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
RID trimesh_shape = ps->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON);
|
||||
ps->shape_set_data(trimesh_shape, p_faces);
|
||||
p_faces=ps->shape_get_data(trimesh_shape); // optimized one
|
||||
Vector<Vector3> normals; // for drawing
|
||||
for (int i=0;i<p_faces.size()/3;i++) {
|
||||
|
||||
Plane p( p_faces[i*3+0],p_faces[i*3+1], p_faces[i*3+2] );
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
}
|
||||
|
||||
RID trimesh_mesh = vs->mesh_create();
|
||||
Array d;
|
||||
d.resize(VS::ARRAY_MAX);
|
||||
d[VS::ARRAY_VERTEX]=p_faces;
|
||||
d[VS::ARRAY_NORMAL]=normals;
|
||||
vs->mesh_add_surface(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, d );
|
||||
RID trimesh_mat = vs->fixed_material_create();
|
||||
vs->fixed_material_set_param( trimesh_mat, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.5,0.8));
|
||||
//vs->material_set_flag( trimesh_mat, VisualServer::MATERIAL_FLAG_UNSHADED,true);
|
||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
||||
|
||||
RID triins = vs->instance_create2(trimesh_mesh,scenario);
|
||||
|
||||
|
||||
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC);
|
||||
ps->body_set_space(tribody,space);
|
||||
//todo set space
|
||||
ps->body_add_shape(tribody, trimesh_shape);
|
||||
Transform tritrans = p_xform;
|
||||
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
||||
vs->instance_set_transform( triins, tritrans );
|
||||
//RID trimesh_material = vs->fixed_material_create();
|
||||
//vs->material_generate( trimesh_material, Color(0.2,0.4,0.6) );
|
||||
//vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_material );
|
||||
|
||||
}
|
||||
|
||||
void make_grid(int p_width,int p_height,float p_cellsize,float p_cellheight,const Transform& p_xform=Transform()) {
|
||||
|
||||
Vector< Vector< float > > grid;
|
||||
|
||||
grid.resize(p_width);
|
||||
|
||||
for (int i=0;i<p_width;i++) {
|
||||
|
||||
grid[i].resize(p_height);
|
||||
|
||||
for (int j=0;j<p_height;j++) {
|
||||
|
||||
grid[i][j]=1.0+Math::random(-p_cellheight, p_cellheight );
|
||||
}
|
||||
}
|
||||
|
||||
Vector<Vector3> faces;
|
||||
|
||||
for (int i=1;i<p_width;i++) {
|
||||
|
||||
for (int j=1;j<p_height;j++) {
|
||||
|
||||
|
||||
#define MAKE_VERTEX(m_x,m_z)\
|
||||
faces.push_back( Vector3( (m_x-p_width/2)*p_cellsize, grid[m_x][m_z], (m_z-p_height/2)*p_cellsize ) )
|
||||
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i,j);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
MAKE_VERTEX(i-1,j-1);
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
make_trimesh(faces,p_xform);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||
|
||||
ofs_y-=p_event.mouse_motion.relative_y/200.0;
|
||||
ofs_x+=p_event.mouse_motion.relative_x/200.0;
|
||||
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&1) {
|
||||
|
||||
float y=-p_event.mouse_motion.relative_y/20.0;
|
||||
float x=p_event.mouse_motion.relative_x/20.0;
|
||||
|
||||
if (mover.is_valid()) {
|
||||
|
||||
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
Transform t = ps->body_get_state(mover,PhysicsServer::BODY_STATE_TRANSFORM);
|
||||
t.origin+=Vector3(x,y,0);
|
||||
|
||||
ps->body_set_state(mover,PhysicsServer::BODY_STATE_TRANSFORM,t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (p_event.type == InputEvent::JOYSTICK_MOTION) {
|
||||
|
||||
if (p_event.joy_motion.axis == 0) {
|
||||
|
||||
joy_direction.x = p_event.joy_motion.axis_value;
|
||||
};
|
||||
|
||||
if (p_event.joy_motion.axis == 1) {
|
||||
|
||||
joy_direction.y = p_event.joy_motion.axis_value;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
ofs_x=ofs_y=0;
|
||||
init_shapes();
|
||||
|
||||
PhysicsServer *ps = PhysicsServer::get_singleton();
|
||||
space=ps->space_create();
|
||||
ps->space_set_active(space,true);
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
/* LIGHT */
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
scenario = vs->scenario_create();
|
||||
vs->light_set_shadow(lightaux,true);
|
||||
light = vs->instance_create2( lightaux,scenario );
|
||||
Transform t;
|
||||
t.rotate(Vector3(1.0,0,0),0.6);
|
||||
vs->instance_set_transform(light,t);
|
||||
|
||||
|
||||
|
||||
/* CAMERA */
|
||||
|
||||
camera = vs->camera_create();
|
||||
RID viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
vs->viewport_set_scenario( viewport, scenario );
|
||||
|
||||
vs->camera_set_perspective(camera,60,0.1,40.0);
|
||||
vs->camera_set_transform(camera,Transform( Matrix3(), Vector3(0,9,12)));
|
||||
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
|
||||
|
||||
Transform gxf;
|
||||
gxf.basis.scale(Vector3(1.4,0.4,1.4));
|
||||
gxf.origin=Vector3(-2,1,-2);
|
||||
make_grid(5,5,2.5,1,gxf);
|
||||
// create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,gxf);
|
||||
//create_static_plane( Plane( Vector3(0,1,0), -2) );
|
||||
// test_joint();
|
||||
test_fall();
|
||||
//test_joint();
|
||||
|
||||
|
||||
/*
|
||||
Vector<Vector3> faces;
|
||||
faces.push_back( Vector3(10,0,-5) );
|
||||
faces.push_back( Vector3(0,0,10) );
|
||||
faces.push_back( Vector3(-10,-0.2,-5) );
|
||||
make_trimesh(faces);
|
||||
*/
|
||||
/* Make Trimesh */
|
||||
quit=false;
|
||||
return;
|
||||
|
||||
#if 0
|
||||
#define GRID_SIZE 5
|
||||
|
||||
float grid[GRID_SIZE][GRID_SIZE];
|
||||
|
||||
for (int i=0;i<GRID_SIZE;i++) {
|
||||
|
||||
for (int j=0;j<GRID_SIZE;j++) {
|
||||
|
||||
grid[j][i]=Math::random(0.0, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
Vector<Vector3> faces;
|
||||
|
||||
for (int i=1;i<GRID_SIZE;i++) {
|
||||
|
||||
for (int j=1;j<GRID_SIZE;j++) {
|
||||
|
||||
|
||||
#define MAKE_VERTEX(m_x,m_z)\
|
||||
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
|
||||
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i,j);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
MAKE_VERTEX(i-1,j-1);
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
faces.clear();
|
||||
faces.push_back( Vector3(0,0,-5) );
|
||||
faces.push_back( Vector3(1,0,-1) );
|
||||
faces.push_back( Vector3(-1,-0,-1) );
|
||||
*/
|
||||
|
||||
RID trimesh_shape = ps->shape_create();
|
||||
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
|
||||
faces=ps->shape_get_shape(trimesh_shape, 0);
|
||||
Vector<Vector3> normals; // for drawing
|
||||
for (int i=0;i<faces.size()/3;i++) {
|
||||
|
||||
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
}
|
||||
|
||||
RID trimesh_mesh = vs->mesh_create();
|
||||
vs->mesh_add_surface(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, VS::ARRAY_FORMAT_VERTEX|VS::ARRAY_FORMAT_NORMAL, faces.size() );
|
||||
vs->mesh_surface_set_array(trimesh_mesh,0,VS::ARRAY_VERTEX, faces );
|
||||
vs->mesh_surface_set_array(trimesh_mesh,0,VS::ARRAY_NORMAL, normals );
|
||||
RID trimesh_mat = vs->fixed_material_create();
|
||||
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
|
||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
||||
|
||||
RID triins = vs->instance_create2(trimesh_mesh);
|
||||
|
||||
|
||||
|
||||
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
|
||||
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
|
||||
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
||||
vs->instance_set_transform( triins, tritrans );
|
||||
RID trimesh_material = vs->fixed_material_create();
|
||||
vs->material_generate( trimesh_material, Color(0.2,0.4,0.6) );
|
||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_material );
|
||||
#endif
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
if (mover) {
|
||||
static float joy_speed = 10;
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
Transform t = ps->body_get_state(mover,PhysicsServer::BODY_STATE_TRANSFORM);
|
||||
t.origin+=Vector3(joy_speed * joy_direction.x * p_time, -joy_speed * joy_direction.y * p_time,0);
|
||||
ps->body_set_state(mover,PhysicsServer::BODY_STATE_TRANSFORM,t);
|
||||
};
|
||||
|
||||
|
||||
Transform cameratr;
|
||||
cameratr.rotate(Vector3(0,1,0),ofs_x);
|
||||
cameratr.rotate(Vector3(1,0,0),-ofs_y);
|
||||
cameratr.translate(Vector3(0,2,8));
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
vs->camera_set_transform(camera,cameratr);
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
void test_joint() {
|
||||
#if 0
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
mover = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,Transform(Matrix3(),Vector3(0,0,-24)));
|
||||
RID b = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
|
||||
|
||||
ps->joint_create_double_pin(b,Vector3(0,0,1.0),mover,Vector3(0,0,0));
|
||||
ps->body_add_collision_exception(mover,b);
|
||||
|
||||
|
||||
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
|
||||
int link_count = LINK_COUNT;
|
||||
if (cmdline.size() > 0 && cmdline[cmdline.size()-1].to_int()) {
|
||||
link_count = cmdline[cmdline.size()-1].to_int();
|
||||
};
|
||||
|
||||
for(int i=0;i<link_count;i++) {
|
||||
|
||||
RID c = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
|
||||
ps->joint_create_double_pin(b,Vector3(0,0,-0.7),c,Vector3(0,0,0.7));
|
||||
ps->body_add_collision_exception(c,b);
|
||||
b=c;
|
||||
}
|
||||
|
||||
|
||||
create_static_plane(Plane(Vector3(0,1,0),-8));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_hinge() {
|
||||
#if 0
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
|
||||
mover = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,Transform(Matrix3(),Vector3(0,0,-24)));
|
||||
RID b = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_RIGID,Transform());
|
||||
|
||||
ps->joint_create_double_hinge(b,Transform(Matrix3(),Vector3(1,1,1.0)),mover,Transform(Matrix3(),Vector3(0,0,0)));
|
||||
ps->body_add_collision_exception(mover,b);
|
||||
|
||||
/*
|
||||
for(int i=0;i<20;i++) {
|
||||
|
||||
RID c = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
|
||||
ps->joint_create_double_hinge(b,Transform(Matrix3(),Vector3(0,0,-0.7)),c,Transform(Matrix3(),Vector3(0,0,0.7)));
|
||||
ps->body_add_collision_exception(c,b);
|
||||
b=c;
|
||||
}
|
||||
|
||||
*/
|
||||
//create_static_plane(Plane(Vector3(0,1,0),-8));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_character() {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
|
||||
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,1,12,5,Vector3::AXIS_Y);
|
||||
RID capsule_material = vs->fixed_material_create();
|
||||
|
||||
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1,1,1) );
|
||||
|
||||
|
||||
RID capsule_mesh = vs->mesh_create();
|
||||
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
|
||||
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
|
||||
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
|
||||
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
|
||||
|
||||
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);
|
||||
Dictionary capsule_params;
|
||||
capsule_params["radius"]=0.5;
|
||||
capsule_params["height"]=1;
|
||||
Transform shape_xform;
|
||||
shape_xform.rotate(Vector3(1,0,0),Math_PI/2.0);
|
||||
//shape_xform.origin=Vector3(1,1,1);
|
||||
ps->shape_set_data( capsule_shape, capsule_params);
|
||||
|
||||
|
||||
RID mesh_instance = vs->instance_create2(capsule_mesh,scenario);
|
||||
character = ps->body_create(PhysicsServer::BODY_MODE_CHARACTER);
|
||||
ps->body_set_space(character,space);
|
||||
//todo add space
|
||||
ps->body_add_shape(character,capsule_shape);
|
||||
|
||||
ps->body_set_force_integration_callback(character,this,"body_changed_transform",mesh_instance);
|
||||
|
||||
|
||||
ps->body_set_state( character, PhysicsServer::BODY_STATE_TRANSFORM,Transform(Matrix3(),Vector3(-2,5,-2)));
|
||||
bodies.push_back(character);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_fall() {
|
||||
|
||||
|
||||
for (int i=0;i<35;i++) {
|
||||
|
||||
static const PhysicsServer::ShapeType shape_idx[]={
|
||||
PhysicsServer::SHAPE_CAPSULE,
|
||||
PhysicsServer::SHAPE_BOX,
|
||||
PhysicsServer::SHAPE_SPHERE,
|
||||
PhysicsServer::SHAPE_CONVEX_POLYGON
|
||||
};
|
||||
|
||||
PhysicsServer::ShapeType type=shape_idx[i%4];
|
||||
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
|
||||
|
||||
Transform t;
|
||||
|
||||
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
|
||||
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
|
||||
t.basis.rotate(Vector3(0.2,-1,0),Math_PI/2*0.6);
|
||||
//t.basis.rotate(Vector3(0,-1,0),Math_PI/4*i);
|
||||
//t.basis.rotate(Vector3(0,-1,0),Math_PI/4*i);
|
||||
//t.basis.rotate(Vector3(-1,0,0),Math_PI/4*i);
|
||||
|
||||
|
||||
RID b = create_body(type,PhysicsServer::BODY_MODE_RIGID,t);
|
||||
//RID b = create_body(type,i==0?PhysicsServer::BODY_MODE_STATIC:PhysicsServer::BODY_MODE_RIGID,t);
|
||||
|
||||
}
|
||||
|
||||
create_static_plane( Plane( Vector3(0,1,0), -1) );
|
||||
|
||||
|
||||
/*
|
||||
create_static_plane( Plane( Vector3(1,0,0), -2) );
|
||||
create_static_plane( Plane( Vector3(-1,0,0), -2) );
|
||||
create_static_plane( Plane( Vector3(0,0,1), -2) );
|
||||
create_static_plane( Plane( Vector3(0,0,-1), -2) );
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_activate() {
|
||||
|
||||
create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_RIGID,Transform(Matrix3(),Vector3(0,2,0)),true);
|
||||
//create_body(PhysicsServer::SHAPE_SPHERE,PhysicsServer::BODY_MODE_RIGID,Transform(Matrix3(),Vector3(0,6,0)),true);
|
||||
create_static_plane( Plane( Vector3(0,1,0), -1) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TestPhysicsMainLoop() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
namespace TestPhysics {
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew( TestPhysicsMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,19 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_PHYSICS_H
|
||||
#define TEST_PHYSICS_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestPhysics {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
467
bin/tests/test_physics_2d.cpp
Normal file
467
bin/tests/test_physics_2d.cpp
Normal file
File diff suppressed because one or more lines are too long
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,16 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_PHYSICS_2D_H
|
||||
#define TEST_PHYSICS_2D_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestPhysics2D {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif // TEST_PHYSICS_2D_H
|
||||
56
bin/tests/test_python.cpp
Normal file
56
bin/tests/test_python.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*************************************************************************/
|
||||
/* test_python.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_python.h"
|
||||
|
||||
#ifdef PYTHON_ENABLED
|
||||
|
||||
#include "Python.h"
|
||||
#include "print_string.h"
|
||||
|
||||
namespace TestPython {
|
||||
|
||||
void test() {
|
||||
|
||||
print_line("testing python");
|
||||
PyRun_SimpleString("import engine\n");
|
||||
PyRun_SimpleString("def test(self):\n\tprint(\"noway\")\n");
|
||||
PyRun_SimpleString("a=engine.ObjectPtr()\n");
|
||||
PyRun_SimpleString("a.noway(22,'hello')\n");
|
||||
PyRun_SimpleString("a.normalize()\n");
|
||||
PyRun_SimpleString("class Moch(engine.ObjectPtr):\n\tdef mooch(self):\n\t\tprint('muchi')\n");
|
||||
PyRun_SimpleString("b=Moch();\n");
|
||||
PyRun_SimpleString("b.mooch();\n");
|
||||
PyRun_SimpleString("b.meis();\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
43
bin/tests/test_python.h
Normal file
43
bin/tests/test_python.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*************************************************************************/
|
||||
/* test_python.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_PYTHON_H
|
||||
#define TEST_PYTHON_H
|
||||
|
||||
#ifdef PYTHON_ENABLED
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
namespace TestPython {
|
||||
|
||||
void test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
263
bin/tests/test_render.cpp
Normal file
263
bin/tests/test_render.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
/*************************************************************************/
|
||||
/* test_render.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_render.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
#include "os/os.h"
|
||||
#include "quick_hull.h"
|
||||
#include "os/keyboard.h"
|
||||
|
||||
#define OBJECT_COUNT 50
|
||||
|
||||
namespace TestRender {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
|
||||
RID test_cube;
|
||||
RID instance;
|
||||
RID camera;
|
||||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
protected:
|
||||
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
|
||||
quit=true;
|
||||
}
|
||||
|
||||
virtual void init() {
|
||||
|
||||
|
||||
print_line("INITIALIZING TEST RENDER");
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
test_cube = vs->get_test_cube();
|
||||
scenario = vs->scenario_create();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Vector<Vector3> vts;
|
||||
|
||||
/*
|
||||
DVector<Plane> sp = Geometry::build_sphere_planes(2,5,5);
|
||||
Geometry::MeshData md2 = Geometry::build_convex_mesh(sp);
|
||||
vts=md2.vertices;
|
||||
*/
|
||||
/*
|
||||
|
||||
static const int s = 20;
|
||||
for(int i=0;i<s;i++) {
|
||||
Matrix3 rot(Vector3(0,1,0),i*Math_PI/s);
|
||||
|
||||
for(int j=0;j<s;j++) {
|
||||
Vector3 v;
|
||||
v.x=Math::sin(j*Math_PI*2/s);
|
||||
v.y=Math::cos(j*Math_PI*2/s);
|
||||
|
||||
vts.push_back( rot.xform(v*2 ) );
|
||||
}
|
||||
}*/
|
||||
/*for(int i=0;i<100;i++) {
|
||||
|
||||
vts.push_back( Vector3(Math::randf()*2-1.0,Math::randf()*2-1.0,Math::randf()*2-1.0).normalized()*2);
|
||||
}*/
|
||||
/*
|
||||
vts.push_back(Vector3(0,0,1));
|
||||
vts.push_back(Vector3(0,0,-1));
|
||||
vts.push_back(Vector3(0,1,0));
|
||||
vts.push_back(Vector3(0,-1,0));
|
||||
vts.push_back(Vector3(1,0,0));
|
||||
vts.push_back(Vector3(-1,0,0));*/
|
||||
|
||||
vts.push_back(Vector3(1,1,1));
|
||||
vts.push_back(Vector3(1,-1,1));
|
||||
vts.push_back(Vector3(-1,1,1));
|
||||
vts.push_back(Vector3(-1,-1,1));
|
||||
vts.push_back(Vector3(1,1,-1));
|
||||
vts.push_back(Vector3(1,-1,-1));
|
||||
vts.push_back(Vector3(-1,1,-1));
|
||||
vts.push_back(Vector3(-1,-1,-1));
|
||||
|
||||
Geometry::MeshData md;
|
||||
Error err = QuickHull::build(vts,md);
|
||||
print_line("ERR: "+itos(err));
|
||||
test_cube = vs->mesh_create();
|
||||
vs->mesh_add_surface_from_mesh_data(test_cube,md);
|
||||
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
|
||||
|
||||
/*
|
||||
RID sm = vs->shader_create();
|
||||
//vs->shader_set_fragment_code(sm,"OUT_ALPHA=mod(TIME,1);");
|
||||
//vs->shader_set_vertex_code(sm,"OUT_VERTEX=IN_VERTEX*mod(TIME,1);");
|
||||
vs->shader_set_fragment_code(sm,"OUT_DIFFUSE=vec3(1,0,1);OUT_GLOW=abs(sin(TIME));");
|
||||
RID tcmat = vs->mesh_surface_get_material(test_cube,0);
|
||||
vs->material_set_shader(tcmat,sm);
|
||||
*/
|
||||
|
||||
|
||||
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
|
||||
int object_count = OBJECT_COUNT;
|
||||
if (cmdline.size() > 0 && cmdline[cmdline.size()-1].to_int()) {
|
||||
object_count = cmdline[cmdline.size()-1].to_int();
|
||||
};
|
||||
|
||||
for (int i=0;i<object_count;i++) {
|
||||
|
||||
InstanceInfo ii;
|
||||
|
||||
|
||||
ii.instance = vs->instance_create2( test_cube, scenario );
|
||||
|
||||
|
||||
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
|
||||
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
|
||||
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
|
||||
vs->instance_set_transform( ii.instance, ii.base );
|
||||
|
||||
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
|
||||
|
||||
instances.push_back(ii);
|
||||
|
||||
}
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_set_scenario( viewport, scenario );
|
||||
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,3,30 ) ) );
|
||||
vs->camera_set_perspective( camera, 60, 0.1, 1000);
|
||||
|
||||
|
||||
/*
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
|
||||
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
|
||||
light = vs->instance_create( lightaux );
|
||||
*/
|
||||
RID lightaux;
|
||||
|
||||
//*
|
||||
lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,1.0) );
|
||||
//vs->light_set_shadow( lightaux, true );
|
||||
light = vs->instance_create2( lightaux, scenario );
|
||||
Transform lla;
|
||||
//lla.set_look_at(Vector3(),Vector3(1,-1,1),Vector3(0,1,0));
|
||||
lla.set_look_at(Vector3(),Vector3(-0.000000,-0.836026,-0.548690),Vector3(0,1,0));
|
||||
|
||||
vs->instance_set_transform( light, lla );
|
||||
// */
|
||||
|
||||
//*
|
||||
lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
|
||||
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,1.0) );
|
||||
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,0.0) );
|
||||
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_RADIUS, 4 );
|
||||
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_ENERGY, 8 );
|
||||
//vs->light_set_shadow( lightaux, true );
|
||||
//light = vs->instance_create( lightaux );
|
||||
// */
|
||||
|
||||
ofs=0;
|
||||
quit=false;
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
//Transform t;
|
||||
//t.rotate(Vector3(0, 1, 0), ofs);
|
||||
//t.translate(Vector3(0,0,20 ));
|
||||
//vs->camera_set_transform(camera, t);
|
||||
|
||||
ofs+=p_time*0.05;
|
||||
|
||||
//return quit;
|
||||
|
||||
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
|
||||
|
||||
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
|
||||
vs->instance_set_transform( E->get().instance, pre * E->get().base );
|
||||
/*
|
||||
if( !E->next() ) {
|
||||
|
||||
vs->free( E->get().instance );
|
||||
instances.erase(E );
|
||||
}*/
|
||||
}
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
||||
virtual bool idle(float p_time) {
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,19 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_RENDER_H
|
||||
#define TEST_RENDER_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestRender {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
340
bin/tests/test_shader_lang.cpp
Normal file
340
bin/tests/test_shader_lang.cpp
Normal file
@ -0,0 +1,340 @@
|
||||
/*************************************************************************/
|
||||
/* test_shader_lang.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_shader_lang.h"
|
||||
|
||||
|
||||
#include "os/main_loop.h"
|
||||
#include "os/os.h"
|
||||
#include "os/file_access.h"
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
#include "print_string.h"
|
||||
#include "servers/visual/shader_language.h"
|
||||
#include "drivers/gles2/shader_compiler_gles2.h"
|
||||
|
||||
|
||||
typedef ShaderLanguage SL;
|
||||
|
||||
namespace TestShaderLang {
|
||||
|
||||
|
||||
static String _mktab(int p_level) {
|
||||
|
||||
String tb;
|
||||
for(int i=0;i<p_level;i++) {
|
||||
tb+="\t";
|
||||
}
|
||||
|
||||
return tb;
|
||||
}
|
||||
|
||||
static String _typestr(SL::DataType p_type) {
|
||||
|
||||
switch(p_type) {
|
||||
|
||||
case SL::TYPE_VOID: return "void";
|
||||
case SL::TYPE_BOOL: return "bool";
|
||||
case SL::TYPE_FLOAT: return "float";
|
||||
case SL::TYPE_VEC2: return "vec2";
|
||||
case SL::TYPE_VEC3: return "vec3";
|
||||
case SL::TYPE_VEC4: return "vec4";
|
||||
case SL::TYPE_MAT3: return "mat3";
|
||||
case SL::TYPE_MAT4: return "mat4";
|
||||
case SL::TYPE_TEXTURE: return "texture";
|
||||
case SL::TYPE_CUBEMAP: return "cubemap";
|
||||
default: {}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static String _opstr(SL::Operator p_op) {
|
||||
|
||||
switch(p_op) {
|
||||
case SL::OP_ASSIGN: return "=";
|
||||
case SL::OP_ADD: return "+";
|
||||
case SL::OP_SUB: return "-";
|
||||
case SL::OP_MUL: return "*";
|
||||
case SL::OP_DIV: return "/";
|
||||
case SL::OP_ASSIGN_ADD: return "+=";
|
||||
case SL::OP_ASSIGN_SUB: return "-=";
|
||||
case SL::OP_ASSIGN_MUL: return "*=";
|
||||
case SL::OP_ASSIGN_DIV: return "/=";
|
||||
case SL::OP_NEG: return "-";
|
||||
case SL::OP_NOT: return "!";
|
||||
case SL::OP_CMP_EQ: return "==";
|
||||
case SL::OP_CMP_NEQ: return "!=";
|
||||
case SL::OP_CMP_LEQ: return "<=";
|
||||
case SL::OP_CMP_GEQ: return ">=";
|
||||
case SL::OP_CMP_LESS: return "<";
|
||||
case SL::OP_CMP_GREATER: return ">";
|
||||
case SL::OP_CMP_OR: return "||";
|
||||
case SL::OP_CMP_AND: return "&&";
|
||||
default: return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static String dump_node_code(SL::Node *p_node,int p_level) {
|
||||
|
||||
String code;
|
||||
|
||||
switch(p_node->type) {
|
||||
|
||||
case SL::Node::TYPE_PROGRAM: {
|
||||
|
||||
SL::ProgramNode *pnode=(SL::ProgramNode*)p_node;
|
||||
|
||||
for(Map<StringName,SL::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
|
||||
|
||||
String ucode="uniform ";
|
||||
ucode+=_typestr(E->get().type)+"="+String(E->get().default_value)+"\n";
|
||||
code+=ucode;
|
||||
|
||||
}
|
||||
|
||||
for(int i=0;i<pnode->functions.size();i++) {
|
||||
|
||||
SL::FunctionNode *fnode=pnode->functions[i].function;
|
||||
|
||||
String header;
|
||||
header=_typestr(fnode->return_type)+" "+fnode->name+"(";
|
||||
for(int i=0;i<fnode->arguments.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
header+=", ";
|
||||
header+=_typestr(fnode->arguments[i].type)+" "+fnode->arguments[i].name;
|
||||
}
|
||||
|
||||
header+=") {\n";
|
||||
code+=header;
|
||||
code+=dump_node_code(fnode->body,p_level+1);
|
||||
code+="}\n";
|
||||
}
|
||||
|
||||
code+=dump_node_code(pnode->body,p_level);
|
||||
} break;
|
||||
case SL::Node::TYPE_FUNCTION: {
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_BLOCK: {
|
||||
SL::BlockNode *bnode=(SL::BlockNode*)p_node;
|
||||
|
||||
//variables
|
||||
for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {
|
||||
|
||||
code+=_mktab(p_level)+_typestr(E->value())+" "+E->key()+";\n";
|
||||
}
|
||||
|
||||
for(int i=0;i<bnode->statements.size();i++) {
|
||||
|
||||
code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";\n";
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_VARIABLE: {
|
||||
SL::VariableNode *vnode=(SL::VariableNode*)p_node;
|
||||
code=vnode->name;
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_CONSTANT: {
|
||||
SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
|
||||
switch(cnode->datatype) {
|
||||
|
||||
|
||||
case SL::TYPE_BOOL: code=cnode->value.operator bool()?"true":"false"; break;
|
||||
case SL::TYPE_FLOAT: code=cnode->value; break;
|
||||
case SL::TYPE_VEC2: { Vector2 v = cnode->value; code="vec2("+rtos(v.x)+", "+rtos(v.y)+")"; } break;
|
||||
case SL::TYPE_VEC3: { Vector3 v = cnode->value; code="vec3("+rtos(v.x)+", "+rtos(v.y)+", "+rtos(v.z)+")"; } break;
|
||||
case SL::TYPE_VEC4: { Plane v = cnode->value; code="vec4("+rtos(v.normal.x)+", "+rtos(v.normal.y)+", "+rtos(v.normal.z)+", "+rtos(v.d)+")"; } break;
|
||||
case SL::TYPE_MAT3: { Matrix3 x = cnode->value; code="mat3( vec3("+rtos(x.get_axis(0).x)+", "+rtos(x.get_axis(0).y)+", "+rtos(x.get_axis(0).z)+"), vec3("+rtos(x.get_axis(1).x)+", "+rtos(x.get_axis(1).y)+", "+rtos(x.get_axis(1).z)+"), vec3("+rtos(x.get_axis(2).x)+", "+rtos(x.get_axis(2).y)+", "+rtos(x.get_axis(2).z)+"))"; } break;
|
||||
case SL::TYPE_MAT4: { Transform x = cnode->value; code="mat4( vec3("+rtos(x.basis.get_axis(0).x)+", "+rtos(x.basis.get_axis(0).y)+", "+rtos(x.basis.get_axis(0).z)+"), vec3("+rtos(x.basis.get_axis(1).x)+", "+rtos(x.basis.get_axis(1).y)+", "+rtos(x.basis.get_axis(1).z)+"), vec3("+rtos(x.basis.get_axis(2).x)+", "+rtos(x.basis.get_axis(2).y)+", "+rtos(x.basis.get_axis(2).z)+"), vec3("+rtos(x.origin.x)+", "+rtos(x.origin.y)+", "+rtos(x.origin.z)+"))"; } break;
|
||||
default: code="<error: "+Variant::get_type_name(cnode->value.get_type())+" ("+itos(cnode->datatype)+">";
|
||||
}
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_OPERATOR: {
|
||||
SL::OperatorNode *onode=(SL::OperatorNode*)p_node;
|
||||
|
||||
|
||||
switch(onode->op) {
|
||||
|
||||
case SL::OP_ASSIGN:
|
||||
case SL::OP_ASSIGN_ADD:
|
||||
case SL::OP_ASSIGN_SUB:
|
||||
case SL::OP_ASSIGN_MUL:
|
||||
case SL::OP_ASSIGN_DIV:
|
||||
code=dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level);
|
||||
break;
|
||||
|
||||
case SL::OP_ADD:
|
||||
case SL::OP_SUB:
|
||||
case SL::OP_MUL:
|
||||
case SL::OP_DIV:
|
||||
case SL::OP_CMP_EQ:
|
||||
case SL::OP_CMP_NEQ:
|
||||
case SL::OP_CMP_LEQ:
|
||||
case SL::OP_CMP_GEQ:
|
||||
case SL::OP_CMP_LESS:
|
||||
case SL::OP_CMP_GREATER:
|
||||
case SL::OP_CMP_OR:
|
||||
case SL::OP_CMP_AND:
|
||||
|
||||
code="("+dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
|
||||
break;
|
||||
case SL::OP_NEG:
|
||||
case SL::OP_NOT:
|
||||
code=_opstr(onode->op)+dump_node_code(onode->arguments[0],p_level);
|
||||
break;
|
||||
case SL::OP_CALL:
|
||||
case SL::OP_CONSTRUCT:
|
||||
code=dump_node_code(onode->arguments[0],p_level)+"(";
|
||||
for(int i=1;i<onode->arguments.size();i++) {
|
||||
if (i>1)
|
||||
code+=", ";
|
||||
code+=dump_node_code(onode->arguments[i],p_level);
|
||||
}
|
||||
code+=")";
|
||||
break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_CONTROL_FLOW: {
|
||||
SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
|
||||
if (cfnode->flow_op==SL::FLOW_OP_IF) {
|
||||
|
||||
code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {\n";
|
||||
code+=dump_node_code(cfnode->statements[1],p_level+1);
|
||||
if (cfnode->statements.size()==3) {
|
||||
|
||||
code+="} else {\n";
|
||||
code+=dump_node_code(cfnode->statements[2],p_level+1);
|
||||
}
|
||||
|
||||
code+="}\n";
|
||||
|
||||
} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
|
||||
|
||||
if (cfnode->statements.size()) {
|
||||
code="return "+dump_node_code(cfnode->statements[0],p_level);
|
||||
} else {
|
||||
code="return";
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_MEMBER: {
|
||||
SL::MemberNode *mnode=(SL::MemberNode*)p_node;
|
||||
code=dump_node_code(mnode->owner,p_level)+"."+mnode->name;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
}
|
||||
|
||||
static Error recreate_code(void *p_str,SL::ProgramNode *p_program) {
|
||||
|
||||
print_line("recr");
|
||||
String *str=(String*)p_str;
|
||||
|
||||
*str=dump_node_code(p_program,0);
|
||||
|
||||
return OK;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
|
||||
|
||||
if (cmdlargs.empty()) {
|
||||
//try editor!
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String test = cmdlargs.back()->get();
|
||||
|
||||
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
|
||||
|
||||
if (!fa) {
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
String code;
|
||||
|
||||
while(true) {
|
||||
CharType c = fa->get_8();
|
||||
if (fa->eof_reached())
|
||||
break;
|
||||
code+=c;
|
||||
}
|
||||
|
||||
int errline;
|
||||
int errcol;
|
||||
String error;
|
||||
print_line(SL::lex_debug(code));
|
||||
Error err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,NULL,NULL,&error,&errline,&errcol);
|
||||
|
||||
if (err) {
|
||||
|
||||
print_line("Error: "+itos(errline)+":"+itos(errcol)+" "+error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
print_line("Compile OK! - pretty printing");
|
||||
|
||||
String rcode;
|
||||
err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,recreate_code,&rcode,&error,&errline,&errcol);
|
||||
|
||||
if (!err) {
|
||||
print_line(rcode);
|
||||
}
|
||||
|
||||
ShaderCompilerGLES2 comp;
|
||||
String codeline,globalsline;
|
||||
SL::VarInfo vi;
|
||||
vi.name="mongs";
|
||||
vi.type=SL::TYPE_VEC3;
|
||||
|
||||
|
||||
ShaderCompilerGLES2::Flags fl;
|
||||
comp.compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,codeline,globalsline,fl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,15 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_SHADER_LANG_H
|
||||
#define TEST_SHADER_LANG_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestShaderLang {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif // TEST_SHADER_LANG_H
|
||||
95
bin/tests/test_sound.cpp
Normal file
95
bin/tests/test_sound.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*************************************************************************/
|
||||
/* test_sound.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "test_sound.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "os/main_loop.h"
|
||||
#include "math_funcs.h"
|
||||
#include "scene/resources/sample.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "print_string.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "os/os.h"
|
||||
namespace TestSound {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
bool quit;
|
||||
Ref<Sample> sample;
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
}
|
||||
virtual void request_quit() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
|
||||
virtual void init() {
|
||||
|
||||
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
|
||||
quit=false;
|
||||
if (cmdline.size()) {
|
||||
|
||||
sample=ResourceLoader::load(cmdline.back()->get());
|
||||
ERR_FAIL_COND(sample.is_null());
|
||||
print_line("Sample loaded OK");
|
||||
}
|
||||
|
||||
RID voice = AudioServer::get_singleton()->voice_create();
|
||||
AudioServer::get_singleton()->voice_play( voice, sample->get_rid() );
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
40
bin/tests/test_sound.h
Normal file
40
bin/tests/test_sound.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*************************************************************************/
|
||||
/* test_sound.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef TEST_SOUND_H
|
||||
#define TEST_SOUND_H
|
||||
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestSound {
|
||||
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
#endif // TEST_SOUND_H
|
||||
912
bin/tests/test_string.cpp
Normal file
912
bin/tests/test_string.cpp
Normal file
@ -0,0 +1,912 @@
|
||||
/*************************************************************************/
|
||||
/* test_string.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "ustring.h"
|
||||
#include <wchar.h>
|
||||
//#include "math_funcs.h"
|
||||
#include <stdio.h>
|
||||
#include "os/os.h"
|
||||
#include "drivers/nrex/regex.h"
|
||||
|
||||
#include "test_string.h"
|
||||
|
||||
namespace TestString {
|
||||
|
||||
bool test_1() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
|
||||
|
||||
String s = "Hello";
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Hello\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
return (wcscmp(s.c_str(),L"Hello")==0);
|
||||
|
||||
}
|
||||
|
||||
bool test_2() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
|
||||
|
||||
String s = "Dolly";
|
||||
String t = s;
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Dolly\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
return (wcscmp(t.c_str(),L"Dolly")==0);
|
||||
|
||||
}
|
||||
|
||||
bool test_3() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
|
||||
|
||||
String s("Sheep");
|
||||
String t(s);
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Sheep\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
return (wcscmp(t.c_str(),L"Sheep")==0);
|
||||
|
||||
}
|
||||
|
||||
bool test_4() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
|
||||
|
||||
String s(L"Give me");
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Give me\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
return (wcscmp(s.c_str(),L"Give me")==0);
|
||||
|
||||
}
|
||||
|
||||
bool test_5() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
|
||||
|
||||
String s(L"Wool");
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Wool\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
return (wcscmp(s.c_str(),L"Wool")==0);
|
||||
|
||||
}
|
||||
|
||||
bool test_6() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
if (! ( s=="Test Compare" ) )
|
||||
return false;
|
||||
|
||||
if (! ( s==L"Test Compare" ) )
|
||||
return false;
|
||||
|
||||
if (! ( s==String("Test Compare") ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_7() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
if (! ( s!="Peanut" ) )
|
||||
return false;
|
||||
|
||||
if (! ( s!=L"Coconut" ) )
|
||||
return false;
|
||||
|
||||
if (! ( s!=String("Butter") ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_8() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
|
||||
|
||||
|
||||
String s="Bees";
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
|
||||
|
||||
if ( ! (s < "Elephant") )
|
||||
return false;
|
||||
|
||||
if ( s < L"Amber" )
|
||||
return false;
|
||||
|
||||
if ( s < String("Beatrix") )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_9() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
|
||||
|
||||
|
||||
String s;
|
||||
|
||||
s+="Have";
|
||||
s+=' ';
|
||||
s+='a';
|
||||
s+=String(" ");
|
||||
s = s + L"Nice";
|
||||
s = s + " ";
|
||||
s = s + String("Day");
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
|
||||
|
||||
return (s == "Have a Nice Day");
|
||||
|
||||
}
|
||||
|
||||
bool test_10() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
|
||||
|
||||
if (! String("").empty())
|
||||
return false;
|
||||
|
||||
if (String("Mellon").size() != 7)
|
||||
return false;
|
||||
|
||||
if (String("Oranges").length() != 7)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_11() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
|
||||
|
||||
String a="Kugar Sane";
|
||||
|
||||
a[0]='S';
|
||||
a[6]='C';
|
||||
|
||||
if (a != "Sugar Cane")
|
||||
return false;
|
||||
|
||||
if (a[1]!='u')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_12() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 12: case functions\n");
|
||||
|
||||
|
||||
String a="MoMoNgA";
|
||||
|
||||
if (a.to_upper() != "MOMONGA")
|
||||
return false;
|
||||
|
||||
if (a.nocasecmp_to("momonga")!=0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_13() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
|
||||
|
||||
/* how can i embed UTF in here? */
|
||||
|
||||
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
|
||||
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
|
||||
String s=ustr;
|
||||
|
||||
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
|
||||
s.parse_utf8( s.utf8().get_data() );
|
||||
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
|
||||
|
||||
return (s==ustr);
|
||||
|
||||
}
|
||||
|
||||
bool test_14() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
|
||||
|
||||
String s = L"Primero Leche";
|
||||
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
|
||||
|
||||
String t=s.ascii().get_data();
|
||||
return (s==t);
|
||||
|
||||
}
|
||||
|
||||
bool test_15() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 15: substr\n");
|
||||
|
||||
String s="Killer Baby";
|
||||
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
|
||||
|
||||
return (s.substr(3,4)=="ler ");
|
||||
|
||||
}
|
||||
|
||||
bool test_16() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 16: find\n");
|
||||
|
||||
String s="Pretty Woman";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
|
||||
|
||||
if (s.find("tty")!=3)
|
||||
return false;
|
||||
|
||||
if (s.find("Revenge of the Monster Truck")!=-1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_17() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 17: find no case\n");
|
||||
|
||||
String s="Pretty Whale";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_18() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 18: find no case\n");
|
||||
|
||||
String s="Pretty Whale";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_19() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
|
||||
|
||||
String s="Happy Birthday, Anna!";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
|
||||
s=s.replace("Birthday","Halloween");
|
||||
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
|
||||
|
||||
return (s=="Happy Halloween, Anna!");
|
||||
|
||||
}
|
||||
|
||||
bool test_20() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
|
||||
|
||||
String s="Who is Frederic?";
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
s=s.insert( s.find("?")," Chopin" );
|
||||
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
|
||||
|
||||
return (s=="Who is Frederic Chopin?");
|
||||
|
||||
}
|
||||
|
||||
bool test_21() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
|
||||
|
||||
OS::get_singleton()->print("\tPi is %f\n",33.141593);
|
||||
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
|
||||
|
||||
return String::num(3.141593)=="3.141593";
|
||||
|
||||
}
|
||||
|
||||
bool test_22() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
|
||||
|
||||
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
|
||||
static const int num[4]={ 1237461283, -22, 0, -1123412 };
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
|
||||
|
||||
if (String(nums[i]).to_int()!=num[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_23() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
|
||||
|
||||
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
|
||||
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
|
||||
|
||||
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_24() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
|
||||
|
||||
String s="Mars,Jupiter,Saturn,Uranus";
|
||||
|
||||
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
|
||||
|
||||
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
|
||||
|
||||
for (int i=0;i<s.get_slice_count(",");i++) {
|
||||
|
||||
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
|
||||
|
||||
|
||||
if (s.get_slice(",",i)!=slices[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool test_25() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
|
||||
|
||||
String s="Josephine is such a cute girl!";
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\tRemoving \"cute\"\n");
|
||||
|
||||
s.erase(s.find("cute "),String("cute ").length());
|
||||
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (s=="Josephine is such a girl!");
|
||||
|
||||
}
|
||||
|
||||
bool test_26() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 26: RegEx\n");
|
||||
RegEx regexp("(.*):(.*)");
|
||||
|
||||
int res = regexp.find("name:password");
|
||||
printf("\tmatch: %s\n", (res>=0)?"true":"false");
|
||||
|
||||
printf("\t%i captures:\n", regexp.get_capture_count());
|
||||
for (int i = 0; i<regexp.get_capture_count(); i++)
|
||||
{
|
||||
printf("%ls\n", regexp.get_capture(i).c_str());
|
||||
}
|
||||
return (res>=0);
|
||||
};
|
||||
|
||||
struct test_27_data {
|
||||
char const * data;
|
||||
char const * begin;
|
||||
bool expected;
|
||||
};
|
||||
|
||||
bool test_27() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 27: begins_with\n");
|
||||
test_27_data tc[] = {
|
||||
{"res://foobar", "res://", true},
|
||||
{"res", "res://", false},
|
||||
{"abc", "abc", true}
|
||||
};
|
||||
size_t count = sizeof(tc) / sizeof(tc[0]);
|
||||
bool state = true;
|
||||
for (size_t i = 0;state && i < count; ++i) {
|
||||
String s = tc[i].data;
|
||||
state = s.begins_with(tc[i].begin) == tc[i].expected;
|
||||
if (state) {
|
||||
String sb = tc[i].begin;
|
||||
state = s.begins_with(sb) == tc[i].expected;
|
||||
}
|
||||
if (!state) {
|
||||
OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n");
|
||||
break;
|
||||
}
|
||||
};
|
||||
return state;
|
||||
};
|
||||
|
||||
|
||||
bool test_28() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 28: sprintf\n");
|
||||
|
||||
bool success, state = true;
|
||||
char output_format[] = "\tTest:\t%ls => %ls (%s)\n";
|
||||
String format, output;
|
||||
Array args;
|
||||
bool error;
|
||||
|
||||
// %%
|
||||
format = "fish %% frog";
|
||||
args.clear();
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish % frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
//////// INTS
|
||||
|
||||
// Int
|
||||
format = "fish %d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 5 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int left padded with zeroes.
|
||||
format = "fish %05d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 00005 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int left padded with spaces.
|
||||
format = "fish %5d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 5 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int right padded with spaces.
|
||||
format = "fish %-5d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 5 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int with sign (positive).
|
||||
format = "fish %+d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish +5 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Negative int.
|
||||
format = "fish %d frog";
|
||||
args.clear();
|
||||
args.push_back(-5);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish -5 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Hex (lower)
|
||||
format = "fish %x frog";
|
||||
args.clear();
|
||||
args.push_back(45);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 2d frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Hex (upper)
|
||||
format = "fish %X frog";
|
||||
args.clear();
|
||||
args.push_back(45);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 2D frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Octal
|
||||
format = "fish %o frog";
|
||||
args.clear();
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 143 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
////// REALS
|
||||
|
||||
// Real
|
||||
format = "fish %f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.990000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real left-padded
|
||||
format = "fish %11f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.990000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real right-padded
|
||||
format = "fish %-11f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.990000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real given int.
|
||||
format = "fish %f frog";
|
||||
args.clear();
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.000000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with sign (positive).
|
||||
format = "fish %+f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish +99.990000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with 1 decimals.
|
||||
format = "fish %.1f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 100.0 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with 12 decimals.
|
||||
format = "fish %.12f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.990000000000 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with no decimals.
|
||||
format = "fish %.f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 100 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
/////// Strings.
|
||||
|
||||
// String
|
||||
format = "fish %s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish cheese frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// String left-padded
|
||||
format = "fish %10s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish cheese frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// String right-padded
|
||||
format = "fish %-10s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish cheese frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Characters
|
||||
|
||||
// Character as string.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back("A");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish A frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character as int.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back(65);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish A frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Dynamic width
|
||||
|
||||
// String dynamic width
|
||||
format = "fish %*s frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish cheese frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int dynamic width
|
||||
format = "fish %*d frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Float dynamic width
|
||||
format = "fish %*.*f frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back(3);
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == String("fish 99.990 frog") && !error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Errors
|
||||
|
||||
// More formats than arguments.
|
||||
format = "fish %s %s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "not enough arguments for format string" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// More arguments than formats.
|
||||
format = "fish %s frog";
|
||||
args.clear();
|
||||
args.push_back("hello");
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "not all arguments converted during string formatting" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Incomplete format.
|
||||
format = "fish %10";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "incomplete format" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Bad character in format string
|
||||
format = "fish %&f frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "unsupported format character" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Too many decimals.
|
||||
format = "fish %2.2.2f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "too many decimal points in format" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// * not a number
|
||||
format = "fish %*f frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "* wants number" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character too long.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back("sc");
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "%c requires number or single-character string" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character bad type.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back(Array());
|
||||
output = format.sprintf(args, &error);
|
||||
success = (output == "%c requires number or single-character string" && error);
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
typedef bool (*TestFunc)(void);
|
||||
|
||||
TestFunc test_funcs[] = {
|
||||
|
||||
test_1,
|
||||
test_2,
|
||||
test_3,
|
||||
test_4,
|
||||
test_5,
|
||||
test_6,
|
||||
test_7,
|
||||
test_8,
|
||||
test_9,
|
||||
test_10,
|
||||
test_11,
|
||||
test_12,
|
||||
test_13,
|
||||
test_14,
|
||||
test_15,
|
||||
test_16,
|
||||
test_17,
|
||||
test_18,
|
||||
test_19,
|
||||
test_20,
|
||||
test_21,
|
||||
test_22,
|
||||
test_23,
|
||||
test_24,
|
||||
test_25,
|
||||
test_26,
|
||||
test_27,
|
||||
test_28,
|
||||
0
|
||||
|
||||
};
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
/** A character length != wchar_t may be forced, so the tests wont work */
|
||||
|
||||
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
|
||||
|
||||
int count=0;
|
||||
int passed=0;
|
||||
|
||||
while(true) {
|
||||
if (!test_funcs[count])
|
||||
break;
|
||||
bool pass=test_funcs[count]();
|
||||
if (pass)
|
||||
passed++;
|
||||
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
OS::get_singleton()->print("\n\n\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
OS::get_singleton()->print("***TOTALS!***\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
|
||||
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,16 +26,19 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEST_STRING_H
|
||||
#define TEST_STRING_H
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "core/ustring.h"
|
||||
#include "ustring.h"
|
||||
#include "os/main_loop.h"
|
||||
|
||||
namespace TestString {
|
||||
|
||||
MainLoop *test();
|
||||
MainLoop* test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
68
compat.py
68
compat.py
@ -1,68 +0,0 @@
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3,):
|
||||
def isbasestring(s):
|
||||
return isinstance(s, basestring)
|
||||
def open_utf8(filename, mode):
|
||||
return open(filename, mode)
|
||||
def byte_to_str(x):
|
||||
return str(ord(x))
|
||||
import cStringIO
|
||||
def StringIO():
|
||||
return cStringIO.StringIO()
|
||||
def encode_utf8(x):
|
||||
return x
|
||||
def decode_utf8(x):
|
||||
return x
|
||||
def iteritems(d):
|
||||
return d.iteritems()
|
||||
def itervalues(d):
|
||||
return d.itervalues()
|
||||
def escape_string(s):
|
||||
if isinstance(s, unicode):
|
||||
s = s.encode('ascii')
|
||||
result = ''
|
||||
for c in s:
|
||||
if not (32 <= ord(c) < 127) or c in ('\\', '"'):
|
||||
result += '\\%03o' % ord(c)
|
||||
else:
|
||||
result += c
|
||||
return result
|
||||
|
||||
else:
|
||||
def isbasestring(s):
|
||||
return isinstance(s, (str, bytes))
|
||||
def open_utf8(filename, mode):
|
||||
return open(filename, mode, encoding="utf-8")
|
||||
def byte_to_str(x):
|
||||
return str(x)
|
||||
import io
|
||||
def StringIO():
|
||||
return io.StringIO()
|
||||
import codecs
|
||||
def encode_utf8(x):
|
||||
return codecs.utf_8_encode(x)[0]
|
||||
def decode_utf8(x):
|
||||
return codecs.utf_8_decode(x)[0]
|
||||
def iteritems(d):
|
||||
return iter(d.items())
|
||||
def itervalues(d):
|
||||
return iter(d.values())
|
||||
def charcode_to_c_escapes(c):
|
||||
rev_result = []
|
||||
while c >= 256:
|
||||
c, low = (c // 256, c % 256)
|
||||
rev_result.append('\\%03o' % low)
|
||||
rev_result.append('\\%03o' % c)
|
||||
return ''.join(reversed(rev_result))
|
||||
def escape_string(s):
|
||||
result = ''
|
||||
if isinstance(s, str):
|
||||
s = s.encode('utf-8')
|
||||
for c in s:
|
||||
if not(32 <= c < 127) or c in (ord('\\'), ord('"')):
|
||||
result += charcode_to_c_escapes(c)
|
||||
else:
|
||||
result += chr(c)
|
||||
return result
|
||||
|
||||
190
core/SCsub
190
core/SCsub
@ -1,173 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
import core_builders
|
||||
import make_binders
|
||||
from platform_methods import run_in_subprocess
|
||||
|
||||
env.core_sources = []
|
||||
env.core_sources=[]
|
||||
|
||||
|
||||
# Generate AES256 script encryption key
|
||||
gd_call=""
|
||||
gd_inc=""
|
||||
|
||||
for x in env.global_defaults:
|
||||
env.core_sources.append("#platform/"+x+"/globals/global_defaults.cpp")
|
||||
gd_inc+='#include "platform/'+x+'/globals/global_defaults.h"\n'
|
||||
gd_call+="\tregister_"+x+"_global_defaults();\n"
|
||||
|
||||
gd_cpp='#include "globals.h"\n'
|
||||
gd_cpp+=gd_inc
|
||||
gd_cpp+="void Globals::register_global_defaults() {\n"+gd_call+"\n}\n"
|
||||
|
||||
f = open("global_defaults.cpp","wb")
|
||||
f.write(gd_cpp)
|
||||
f.close()
|
||||
|
||||
import os
|
||||
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
|
||||
if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
|
||||
e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
|
||||
e=os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
|
||||
txt = ""
|
||||
ec_valid = True
|
||||
if (len(e) != 64):
|
||||
ec_valid = False
|
||||
ec_valid=True
|
||||
if (len(e)!=64):
|
||||
ec_valid=False
|
||||
else:
|
||||
|
||||
for i in range(len(e) >> 1):
|
||||
if (i > 0):
|
||||
txt += ","
|
||||
txts = "0x" + e[i * 2:i * 2 + 2]
|
||||
for i in range(len(e)>>1):
|
||||
if (i>0):
|
||||
txt+=","
|
||||
txts="0x"+e[i*2:i*2+2]
|
||||
try:
|
||||
int(txts, 16)
|
||||
int(txts,16)
|
||||
except:
|
||||
ec_valid = False
|
||||
txt += txts
|
||||
ec_valid=False
|
||||
txt+=txts
|
||||
if (not ec_valid):
|
||||
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
|
||||
print("Invalid AES256 encryption key, not 64 bits hex: " + e)
|
||||
print("Invalid AES256 encryption key, not 64 bits hex: "+e)
|
||||
|
||||
# NOTE: It is safe to generate this file here, since this is still executed serially
|
||||
with open("script_encryption_key.gen.cpp", "w") as f:
|
||||
f.write("#include \"core/project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
|
||||
f = open("script_encryption_key.cpp", "wb")
|
||||
f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
|
||||
f.close()
|
||||
|
||||
|
||||
# Add required thirdparty code.
|
||||
env_thirdparty = env.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
|
||||
# Misc thirdparty code: header paths are hardcoded, we don't need to append
|
||||
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
|
||||
thirdparty_misc_dir = "#thirdparty/misc/"
|
||||
thirdparty_misc_sources = [
|
||||
# C sources
|
||||
"fastlz.c",
|
||||
"smaz.c",
|
||||
|
||||
# C++ sources
|
||||
"hq2x.cpp",
|
||||
"pcg.cpp",
|
||||
"triangulator.cpp",
|
||||
"clipper.cpp",
|
||||
]
|
||||
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
|
||||
env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources)
|
||||
|
||||
# Zlib library, can be unbundled
|
||||
if env['builtin_zlib']:
|
||||
thirdparty_zlib_dir = "#thirdparty/zlib/"
|
||||
thirdparty_zlib_sources = [
|
||||
"adler32.c",
|
||||
"compress.c",
|
||||
"crc32.c",
|
||||
"deflate.c",
|
||||
"infback.c",
|
||||
"inffast.c",
|
||||
"inflate.c",
|
||||
"inftrees.c",
|
||||
"trees.c",
|
||||
"uncompr.c",
|
||||
"zutil.c",
|
||||
]
|
||||
thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
|
||||
|
||||
env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir])
|
||||
# Needs to be available in main env too
|
||||
env.Prepend(CPPPATH=[thirdparty_zlib_dir])
|
||||
if (env['target'] == 'debug'):
|
||||
env_thirdparty.Append(CPPDEFINES=['ZLIB_DEBUG'])
|
||||
|
||||
env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources)
|
||||
|
||||
# Minizip library, could be unbundled in theory
|
||||
# However, our version has some custom modifications, so it won't compile with the system one
|
||||
thirdparty_minizip_dir = "#thirdparty/minizip/"
|
||||
thirdparty_minizip_sources = [
|
||||
"ioapi.c",
|
||||
"unzip.c",
|
||||
"zip.c",
|
||||
]
|
||||
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
|
||||
env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
|
||||
|
||||
# Zstd library, can be unbundled in theory
|
||||
# though we currently use some private symbols
|
||||
# https://github.com/godotengine/godot/issues/17374
|
||||
if env['builtin_zstd']:
|
||||
thirdparty_zstd_dir = "#thirdparty/zstd/"
|
||||
thirdparty_zstd_sources = [
|
||||
"common/debug.c",
|
||||
"common/entropy_common.c",
|
||||
"common/error_private.c",
|
||||
"common/fse_decompress.c",
|
||||
"common/pool.c",
|
||||
"common/threading.c",
|
||||
"common/xxhash.c",
|
||||
"common/zstd_common.c",
|
||||
"compress/fse_compress.c",
|
||||
"compress/hist.c",
|
||||
"compress/huf_compress.c",
|
||||
"compress/zstd_compress.c",
|
||||
"compress/zstd_double_fast.c",
|
||||
"compress/zstd_fast.c",
|
||||
"compress/zstd_lazy.c",
|
||||
"compress/zstd_ldm.c",
|
||||
"compress/zstd_opt.c",
|
||||
"compress/zstdmt_compress.c",
|
||||
"compress/zstd_compress_literals.c",
|
||||
"compress/zstd_compress_sequences.c",
|
||||
"decompress/huf_decompress.c",
|
||||
"decompress/zstd_ddict.c",
|
||||
"decompress/zstd_decompress_block.c",
|
||||
"decompress/zstd_decompress.c",
|
||||
]
|
||||
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
|
||||
|
||||
env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
|
||||
env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
|
||||
env.Prepend(CPPPATH=thirdparty_zstd_dir)
|
||||
# Also needed in main env includes will trigger warnings
|
||||
env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
|
||||
|
||||
env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources)
|
||||
env.add_source_files(env.core_sources,"*.cpp")
|
||||
|
||||
|
||||
# Godot's own sources
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
Export('env')
|
||||
|
||||
# Certificates
|
||||
env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificates.crt", env.Value(env['builtin_certs']), env.Value(env['system_certs_path'])])
|
||||
env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header))
|
||||
import make_binders
|
||||
env.Command(['method_bind.inc','method_bind_ext.inc'], 'make_binders.py', make_binders.run)
|
||||
|
||||
# Make binders
|
||||
env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc', 'method_bind_free_func.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))
|
||||
SConscript('os/SCsub');
|
||||
SConscript('math/SCsub');
|
||||
SConscript('io/SCsub');
|
||||
SConscript('bind/SCsub');
|
||||
|
||||
# Authors
|
||||
env.Depends('#core/authors.gen.h', "../AUTHORS.md")
|
||||
env.CommandNoCache('#core/authors.gen.h', "../AUTHORS.md", run_in_subprocess(core_builders.make_authors_header))
|
||||
lib = env.Library("core",env.core_sources)
|
||||
|
||||
# Donors
|
||||
env.Depends('#core/donors.gen.h', "../DONORS.md")
|
||||
env.CommandNoCache('#core/donors.gen.h', "../DONORS.md", run_in_subprocess(core_builders.make_donors_header))
|
||||
|
||||
# License
|
||||
env.Depends('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
|
||||
env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(core_builders.make_license_header))
|
||||
|
||||
# Chain load SCsubs
|
||||
SConscript('os/SCsub')
|
||||
SConscript('math/SCsub')
|
||||
SConscript('crypto/SCsub')
|
||||
SConscript('io/SCsub')
|
||||
SConscript('bind/SCsub')
|
||||
|
||||
|
||||
# Build it all as a library
|
||||
lib = env.add_library("core", env.core_sources)
|
||||
env.Prepend(LIBS=[lib])
|
||||
|
||||
198
core/allocators.h
Normal file
198
core/allocators.h
Normal file
@ -0,0 +1,198 @@
|
||||
/*************************************************************************/
|
||||
/* allocators.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef ALLOCATORS_H
|
||||
#define ALLOCATORS_H
|
||||
|
||||
#include "os/memory.h"
|
||||
template<int PREALLOC_COUNT=64, int MAX_HANDS=8>
|
||||
class BalloonAllocator {
|
||||
|
||||
enum {
|
||||
|
||||
USED_FLAG=(1<<30),
|
||||
USED_MASK=USED_FLAG-1
|
||||
};
|
||||
|
||||
struct Balloon {
|
||||
|
||||
Balloon *next;
|
||||
Balloon *prev;
|
||||
uint32_t hand;
|
||||
};
|
||||
|
||||
|
||||
struct Hand {
|
||||
|
||||
int used;
|
||||
int allocated;
|
||||
Balloon *first;
|
||||
Balloon *last;
|
||||
};
|
||||
|
||||
|
||||
Hand hands[MAX_HANDS];
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
void* alloc(size_t p_size) {
|
||||
|
||||
size_t max=(1<<MAX_HANDS);
|
||||
ERR_FAIL_COND_V( p_size>max, NULL );
|
||||
|
||||
unsigned int hand=0;
|
||||
|
||||
while(p_size>(size_t)(1<<hand)) ++hand;
|
||||
|
||||
Hand &h=hands[hand];
|
||||
|
||||
if (h.used==h.allocated) {
|
||||
|
||||
for(int i=0;i<PREALLOC_COUNT;i++) {
|
||||
|
||||
Balloon *b = (Balloon*)memalloc(sizeof(Balloon)+(1<<hand));
|
||||
b->hand=hand;
|
||||
if (h.last) {
|
||||
|
||||
b->prev=h.last;
|
||||
h.last->next=b;
|
||||
h.last=b;
|
||||
} else {
|
||||
|
||||
b->prev=NULL;
|
||||
h.last=b;
|
||||
h.first=b;
|
||||
}
|
||||
}
|
||||
|
||||
h.last->next=NULL;
|
||||
h.allocated+=PREALLOC_COUNT;
|
||||
}
|
||||
|
||||
Balloon *pick=h.last;
|
||||
|
||||
ERR_FAIL_COND_V( (pick->hand&USED_FLAG), NULL );
|
||||
|
||||
// remove last
|
||||
h.last=h.last->prev;
|
||||
h.last->next=NULL;
|
||||
|
||||
pick->next=h.first;
|
||||
h.first->prev=pick;
|
||||
pick->prev=NULL;
|
||||
h.first=pick;
|
||||
h.used++;
|
||||
pick->hand|=USED_FLAG;
|
||||
|
||||
return (void*)(pick+1);
|
||||
}
|
||||
|
||||
void free(void* p_ptr) {
|
||||
|
||||
Balloon *b=(Balloon*)p_ptr;
|
||||
b-=1;
|
||||
|
||||
ERR_FAIL_COND(!(b->hand&USED_FLAG) );
|
||||
|
||||
b->hand=b->hand&USED_MASK; // not used
|
||||
int hand=b->hand;
|
||||
|
||||
Hand &h=hands[hand];
|
||||
|
||||
if (b==h.first)
|
||||
h.first=b->next;
|
||||
|
||||
if (b->prev)
|
||||
b->prev->next=b->next;
|
||||
if (b->next)
|
||||
b->next->prev=b->prev;
|
||||
|
||||
if (h.last!=b) {
|
||||
h.last->next=b;
|
||||
b->prev=h.last;
|
||||
b->next=NULL;
|
||||
h.last=b;
|
||||
}
|
||||
|
||||
h.used--;
|
||||
|
||||
if (h.used<=(h.allocated-(PREALLOC_COUNT*2))) { // this is done to ensure no alloc/free is done constantly
|
||||
|
||||
for(int i=0;i<PREALLOC_COUNT;i++) {
|
||||
ERR_CONTINUE( h.last->hand& USED_FLAG );
|
||||
|
||||
Balloon *new_last=h.last->prev;
|
||||
if (new_last)
|
||||
new_last->next=NULL;
|
||||
memfree( h.last );
|
||||
h.last=new_last;
|
||||
}
|
||||
h.allocated-=PREALLOC_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
BalloonAllocator() {
|
||||
|
||||
for(int i=0;i<MAX_HANDS;i++) {
|
||||
|
||||
hands[i].allocated=0;
|
||||
hands[i].used=0;
|
||||
hands[i].first=NULL;
|
||||
hands[i].last=NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void clear() {
|
||||
|
||||
for(int i=0;i<MAX_HANDS;i++) {
|
||||
|
||||
while(hands[i].first) {
|
||||
|
||||
Balloon *b=hands[i].first;
|
||||
hands[i].first=b->next;
|
||||
memfree(b);
|
||||
}
|
||||
|
||||
hands[i].allocated=0;
|
||||
hands[i].used=0;
|
||||
hands[i].first=NULL;
|
||||
hands[i].last=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~BalloonAllocator() {
|
||||
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // ALLOCATORS_H
|
||||
401
core/array.cpp
401
core/array.cpp
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,36 +26,48 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "array.h"
|
||||
#include "vector.h"
|
||||
#include "hashfuncs.h"
|
||||
#include "variant.h"
|
||||
#include "object.h"
|
||||
|
||||
#include "core/hashfuncs.h"
|
||||
#include "core/object.h"
|
||||
#include "core/variant.h"
|
||||
#include "core/vector.h"
|
||||
struct ArrayPrivate {
|
||||
|
||||
class ArrayPrivate {
|
||||
public:
|
||||
SafeRefCount refcount;
|
||||
Vector<Variant> array;
|
||||
bool shared;
|
||||
};
|
||||
|
||||
void Array::_ref(const Array &p_from) const {
|
||||
void Array::_ref(const Array& p_from) const {
|
||||
|
||||
ArrayPrivate *_fp = p_from._p;
|
||||
|
||||
ERR_FAIL_COND(!_fp); // should NOT happen.
|
||||
|
||||
if (_fp == _p)
|
||||
return; // whatever it is, nothing to do here move along
|
||||
return; //wathever it is, nothing to do here move along
|
||||
|
||||
bool success = _fp->refcount.ref();
|
||||
|
||||
ERR_FAIL_COND(!success); // should really not happen either
|
||||
ERR_FAIL_COND(!success); //should really not happen either
|
||||
|
||||
_unref();
|
||||
|
||||
if (_fp->shared) {
|
||||
|
||||
_p = p_from._p;
|
||||
|
||||
} else {
|
||||
|
||||
_p = memnew( ArrayPrivate );
|
||||
_p->shared=false;
|
||||
_p->refcount.init();
|
||||
_p->array=_fp->array;
|
||||
|
||||
if (_fp->refcount.unref())
|
||||
memdelete(_fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Array::_unref() const {
|
||||
@ -67,19 +78,21 @@ void Array::_unref() const {
|
||||
if (_p->refcount.unref()) {
|
||||
memdelete(_p);
|
||||
}
|
||||
_p = NULL;
|
||||
_p=NULL;
|
||||
}
|
||||
|
||||
Variant &Array::operator[](int p_idx) {
|
||||
|
||||
return _p->array.write[p_idx];
|
||||
}
|
||||
|
||||
const Variant &Array::operator[](int p_idx) const {
|
||||
Variant& Array::operator[](int p_idx) {
|
||||
|
||||
return _p->array[p_idx];
|
||||
}
|
||||
|
||||
const Variant& Array::operator[](int p_idx) const {
|
||||
|
||||
return _p->array[p_idx];
|
||||
|
||||
}
|
||||
|
||||
int Array::size() const {
|
||||
|
||||
return _p->array.size();
|
||||
@ -93,26 +106,31 @@ void Array::clear() {
|
||||
_p->array.clear();
|
||||
}
|
||||
|
||||
bool Array::operator==(const Array &p_array) const {
|
||||
bool Array::is_shared() const {
|
||||
|
||||
return _p == p_array._p;
|
||||
return _p->shared;
|
||||
}
|
||||
|
||||
bool Array::operator==(const Array& p_array) const {
|
||||
|
||||
return _p==p_array._p;
|
||||
}
|
||||
|
||||
uint32_t Array::hash() const {
|
||||
|
||||
uint32_t h = hash_djb2_one_32(0);
|
||||
uint32_t h=hash_djb2_one_32(0);
|
||||
|
||||
for (int i = 0; i < _p->array.size(); i++) {
|
||||
for (int i=0;i<_p->array.size();i++) {
|
||||
|
||||
h = hash_djb2_one_32(_p->array[i].hash(), h);
|
||||
h = hash_djb2_one_32( _p->array[i].hash(), h);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
void Array::operator=(const Array &p_array) {
|
||||
void Array::operator=(const Array& p_array) {
|
||||
|
||||
_ref(p_array);
|
||||
}
|
||||
void Array::push_back(const Variant &p_value) {
|
||||
void Array::push_back(const Variant& p_value) {
|
||||
|
||||
_p->array.push_back(p_value);
|
||||
}
|
||||
@ -122,78 +140,19 @@ Error Array::resize(int p_new_size) {
|
||||
return _p->array.resize(p_new_size);
|
||||
}
|
||||
|
||||
void Array::insert(int p_pos, const Variant &p_value) {
|
||||
void Array::insert(int p_pos, const Variant& p_value) {
|
||||
|
||||
_p->array.insert(p_pos, p_value);
|
||||
_p->array.insert(p_pos,p_value);
|
||||
}
|
||||
|
||||
void Array::erase(const Variant &p_value) {
|
||||
void Array::erase(const Variant& p_value) {
|
||||
|
||||
_p->array.erase(p_value);
|
||||
}
|
||||
|
||||
Variant Array::front() const {
|
||||
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
|
||||
return operator[](0);
|
||||
}
|
||||
int Array::find(const Variant& p_value) const {
|
||||
|
||||
Variant Array::back() const {
|
||||
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
|
||||
return operator[](_p->array.size() - 1);
|
||||
}
|
||||
|
||||
int Array::find(const Variant &p_value, int p_from) const {
|
||||
|
||||
return _p->array.find(p_value, p_from);
|
||||
}
|
||||
|
||||
int Array::rfind(const Variant &p_value, int p_from) const {
|
||||
|
||||
if (_p->array.size() == 0)
|
||||
return -1;
|
||||
|
||||
if (p_from < 0) {
|
||||
// Relative offset from the end
|
||||
p_from = _p->array.size() + p_from;
|
||||
}
|
||||
if (p_from < 0 || p_from >= _p->array.size()) {
|
||||
// Limit to array boundaries
|
||||
p_from = _p->array.size() - 1;
|
||||
}
|
||||
|
||||
for (int i = p_from; i >= 0; i--) {
|
||||
|
||||
if (_p->array[i] == p_value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Array::find_last(const Variant &p_value) const {
|
||||
|
||||
return rfind(p_value);
|
||||
}
|
||||
|
||||
int Array::count(const Variant &p_value) const {
|
||||
|
||||
if (_p->array.size() == 0)
|
||||
return 0;
|
||||
|
||||
int amount = 0;
|
||||
for (int i = 0; i < _p->array.size(); i++) {
|
||||
|
||||
if (_p->array[i] == p_value) {
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
bool Array::has(const Variant &p_value) const {
|
||||
return _p->array.find(p_value, 0) != -1;
|
||||
return _p->array.find(p_value);
|
||||
}
|
||||
|
||||
void Array::remove(int p_pos) {
|
||||
@ -201,103 +160,33 @@ void Array::remove(int p_pos) {
|
||||
_p->array.remove(p_pos);
|
||||
}
|
||||
|
||||
void Array::set(int p_idx, const Variant &p_value) {
|
||||
|
||||
operator[](p_idx) = p_value;
|
||||
void Array::set(int p_idx,const Variant& p_value) {
|
||||
|
||||
operator[](p_idx)=p_value;
|
||||
}
|
||||
|
||||
const Variant &Array::get(int p_idx) const {
|
||||
const Variant& Array::get(int p_idx) const {
|
||||
|
||||
return operator[](p_idx);
|
||||
}
|
||||
|
||||
Array Array::duplicate(bool p_deep) const {
|
||||
|
||||
Array new_arr;
|
||||
int element_count = size();
|
||||
new_arr.resize(element_count);
|
||||
for (int i = 0; i < element_count; i++) {
|
||||
new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
|
||||
}
|
||||
|
||||
return new_arr;
|
||||
}
|
||||
|
||||
int Array::_fix_slice_index(int p_index, int p_arr_len, int p_top_mod) {
|
||||
p_index = CLAMP(p_index, -p_arr_len, p_arr_len + p_top_mod);
|
||||
if (p_index < 0) {
|
||||
p_index = (p_index % p_arr_len + p_arr_len) % p_arr_len; // positive modulo
|
||||
}
|
||||
return p_index;
|
||||
}
|
||||
|
||||
int Array::_clamp_index(int p_index) const {
|
||||
return CLAMP(p_index, -size() + 1, size() - 1);
|
||||
}
|
||||
|
||||
#define ARRAY_GET_DEEP(idx, is_deep) is_deep ? get(idx).duplicate(is_deep) : get(idx)
|
||||
|
||||
Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
|
||||
Array new_arr;
|
||||
|
||||
if (empty()) // Don't try to slice empty arrays.
|
||||
return new_arr;
|
||||
|
||||
p_begin = Array::_fix_slice_index(p_begin, size(), -1); // can't start out of range
|
||||
p_end = Array::_fix_slice_index(p_end, size(), 0);
|
||||
|
||||
int x = p_begin;
|
||||
int new_arr_i = 0;
|
||||
|
||||
ERR_FAIL_COND_V(p_step == 0, new_arr);
|
||||
if (Array::_clamp_index(p_begin) == Array::_clamp_index(p_end)) { // don't include element twice
|
||||
new_arr.resize(1);
|
||||
// new_arr[0] = 1;
|
||||
new_arr[0] = ARRAY_GET_DEEP(Array::_clamp_index(p_begin), p_deep);
|
||||
return new_arr;
|
||||
} else {
|
||||
int element_count = ceil((int)MAX(0, (p_end - p_begin) / p_step)) + 1;
|
||||
if (element_count == 1) { // delta going in wrong direction to reach end
|
||||
new_arr.resize(0);
|
||||
return new_arr;
|
||||
}
|
||||
new_arr.resize(element_count);
|
||||
}
|
||||
|
||||
// if going backwards, have to have a different terminating condition
|
||||
if (p_step < 0) {
|
||||
while (x >= p_end) {
|
||||
new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
|
||||
x += p_step;
|
||||
new_arr_i += 1;
|
||||
}
|
||||
} else if (p_step > 0) {
|
||||
while (x <= p_end) {
|
||||
new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
|
||||
x += p_step;
|
||||
new_arr_i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new_arr;
|
||||
}
|
||||
|
||||
struct _ArrayVariantSort {
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
|
||||
bool valid = false;
|
||||
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
|
||||
bool valid=false;
|
||||
Variant res;
|
||||
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
|
||||
Variant::evaluate(Variant::OP_LESS,p_l,p_r,res,valid);
|
||||
if (!valid)
|
||||
res = false;
|
||||
res=false;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
Array &Array::sort() {
|
||||
void Array::sort() {
|
||||
|
||||
_p->array.sort_custom<_ArrayVariantSort>();
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
struct _ArrayVariantSortCustom {
|
||||
@ -305,176 +194,64 @@ struct _ArrayVariantSortCustom {
|
||||
Object *obj;
|
||||
StringName func;
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
|
||||
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
|
||||
|
||||
const Variant *args[2] = { &p_l, &p_r };
|
||||
const Variant*args[2]={&p_l,&p_r};
|
||||
Variant::CallError err;
|
||||
bool res = obj->call(func, args, 2, err);
|
||||
if (err.error != Variant::CallError::CALL_OK)
|
||||
res = false;
|
||||
bool res = obj->call(func,args,2,err);
|
||||
if (err.error!=Variant::CallError::CALL_OK)
|
||||
res=false;
|
||||
return res;
|
||||
|
||||
}
|
||||
};
|
||||
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
|
||||
void Array::sort_custom(Object *p_obj,const StringName& p_function){
|
||||
|
||||
ERR_FAIL_NULL_V(p_obj, *this);
|
||||
ERR_FAIL_NULL(p_obj);
|
||||
|
||||
SortArray<Variant,_ArrayVariantSortCustom> avs;
|
||||
avs.compare.obj=p_obj;
|
||||
avs.compare.func=p_function;
|
||||
avs.sort(_p->array.ptr(),_p->array.size());
|
||||
|
||||
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
|
||||
avs.compare.obj = p_obj;
|
||||
avs.compare.func = p_function;
|
||||
avs.sort(_p->array.ptrw(), _p->array.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Array::shuffle() {
|
||||
|
||||
const int n = _p->array.size();
|
||||
if (n < 2)
|
||||
return;
|
||||
Variant *data = _p->array.ptrw();
|
||||
for (int i = n - 1; i >= 1; i--) {
|
||||
const int j = Math::rand() % (i + 1);
|
||||
const Variant tmp = data[j];
|
||||
data[j] = data[i];
|
||||
data[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Less>
|
||||
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
|
||||
|
||||
int lo = 0;
|
||||
int hi = p_array.size();
|
||||
if (p_before) {
|
||||
while (lo < hi) {
|
||||
const int mid = (lo + hi) / 2;
|
||||
if (p_less(p_array.get(mid), p_value)) {
|
||||
lo = mid + 1;
|
||||
} else {
|
||||
hi = mid;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (lo < hi) {
|
||||
const int mid = (lo + hi) / 2;
|
||||
if (p_less(p_value, p_array.get(mid))) {
|
||||
hi = mid;
|
||||
} else {
|
||||
lo = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lo;
|
||||
}
|
||||
|
||||
int Array::bsearch(const Variant &p_value, bool p_before) {
|
||||
|
||||
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
|
||||
}
|
||||
|
||||
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
|
||||
|
||||
ERR_FAIL_NULL_V(p_obj, 0);
|
||||
|
||||
_ArrayVariantSortCustom less;
|
||||
less.obj = p_obj;
|
||||
less.func = p_function;
|
||||
|
||||
return bisect(_p->array, p_value, p_before, less);
|
||||
}
|
||||
|
||||
Array &Array::invert() {
|
||||
void Array::invert(){
|
||||
|
||||
_p->array.invert();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Array::push_front(const Variant &p_value) {
|
||||
|
||||
_p->array.insert(0, p_value);
|
||||
void Array::push_front(const Variant& p_value) {
|
||||
|
||||
_p->array.insert(0,p_value);
|
||||
}
|
||||
|
||||
Variant Array::pop_back() {
|
||||
void Array::pop_back(){
|
||||
|
||||
if (!_p->array.empty())
|
||||
_p->array.resize( _p->array.size() -1 );
|
||||
|
||||
if (!_p->array.empty()) {
|
||||
int n = _p->array.size() - 1;
|
||||
Variant ret = _p->array.get(n);
|
||||
_p->array.resize(n);
|
||||
return ret;
|
||||
}
|
||||
return Variant();
|
||||
}
|
||||
void Array::pop_front(){
|
||||
|
||||
Variant Array::pop_front() {
|
||||
|
||||
if (!_p->array.empty()) {
|
||||
Variant ret = _p->array.get(0);
|
||||
if (!_p->array.empty())
|
||||
_p->array.remove(0);
|
||||
return ret;
|
||||
}
|
||||
return Variant();
|
||||
|
||||
}
|
||||
|
||||
Variant Array::min() const {
|
||||
|
||||
Variant minval;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (i == 0) {
|
||||
minval = get(i);
|
||||
} else {
|
||||
bool valid;
|
||||
Variant ret;
|
||||
Variant test = get(i);
|
||||
Variant::evaluate(Variant::OP_LESS, test, minval, ret, valid);
|
||||
if (!valid) {
|
||||
return Variant(); //not a valid comparison
|
||||
}
|
||||
if (bool(ret)) {
|
||||
//is less
|
||||
minval = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
return minval;
|
||||
}
|
||||
Array::Array(const Array& p_from) {
|
||||
|
||||
Variant Array::max() const {
|
||||
|
||||
Variant maxval;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (i == 0) {
|
||||
maxval = get(i);
|
||||
} else {
|
||||
bool valid;
|
||||
Variant ret;
|
||||
Variant test = get(i);
|
||||
Variant::evaluate(Variant::OP_GREATER, test, maxval, ret, valid);
|
||||
if (!valid) {
|
||||
return Variant(); //not a valid comparison
|
||||
}
|
||||
if (bool(ret)) {
|
||||
//is less
|
||||
maxval = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxval;
|
||||
}
|
||||
|
||||
const void *Array::id() const {
|
||||
return _p->array.ptr();
|
||||
}
|
||||
|
||||
Array::Array(const Array &p_from) {
|
||||
|
||||
_p = NULL;
|
||||
_p=NULL;
|
||||
_ref(p_from);
|
||||
|
||||
}
|
||||
Array::Array(bool p_shared) {
|
||||
|
||||
Array::Array() {
|
||||
|
||||
_p = memnew(ArrayPrivate);
|
||||
_p = memnew( ArrayPrivate );
|
||||
_p->refcount.init();
|
||||
_p->shared=p_shared;
|
||||
}
|
||||
Array::~Array() {
|
||||
|
||||
|
||||
75
core/array.h
75
core/array.h
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,12 +26,10 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef ARRAY_H
|
||||
#define ARRAY_H
|
||||
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#include "typedefs.h"
|
||||
class Variant;
|
||||
class ArrayPrivate;
|
||||
class Object;
|
||||
@ -41,69 +38,51 @@ class StringName;
|
||||
class Array {
|
||||
|
||||
mutable ArrayPrivate *_p;
|
||||
void _ref(const Array &p_from) const;
|
||||
void _ref(const Array& p_from) const;
|
||||
void _unref() const;
|
||||
|
||||
int _clamp_index(int p_index) const;
|
||||
static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod);
|
||||
|
||||
public:
|
||||
Variant &operator[](int p_idx);
|
||||
const Variant &operator[](int p_idx) const;
|
||||
|
||||
void set(int p_idx, const Variant &p_value);
|
||||
const Variant &get(int p_idx) const;
|
||||
Variant& operator[](int p_idx);
|
||||
const Variant& operator[](int p_idx) const;
|
||||
|
||||
void set(int p_idx,const Variant& p_value);
|
||||
const Variant& get(int p_idx) const;
|
||||
|
||||
int size() const;
|
||||
bool empty() const;
|
||||
void clear();
|
||||
|
||||
bool operator==(const Array &p_array) const;
|
||||
bool is_shared() const;
|
||||
|
||||
bool operator==(const Array& p_array) const;
|
||||
|
||||
uint32_t hash() const;
|
||||
void operator=(const Array &p_array);
|
||||
void operator=(const Array& p_array);
|
||||
|
||||
void push_back(const Variant &p_value);
|
||||
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
|
||||
void push_back(const Variant& p_value);
|
||||
_FORCE_INLINE_ void append(const Variant& p_value) { push_back(p_value); } //for python compatibility
|
||||
Error resize(int p_new_size);
|
||||
|
||||
void insert(int p_pos, const Variant &p_value);
|
||||
void insert(int p_pos, const Variant& p_value);
|
||||
void remove(int p_pos);
|
||||
|
||||
Variant front() const;
|
||||
Variant back() const;
|
||||
void sort();
|
||||
void sort_custom(Object *p_obj,const StringName& p_function);
|
||||
void invert();
|
||||
|
||||
Array &sort();
|
||||
Array &sort_custom(Object *p_obj, const StringName &p_function);
|
||||
void shuffle();
|
||||
int bsearch(const Variant &p_value, bool p_before = true);
|
||||
int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
|
||||
Array &invert();
|
||||
int find(const Variant& p_value) const;
|
||||
|
||||
int find(const Variant &p_value, int p_from = 0) const;
|
||||
int rfind(const Variant &p_value, int p_from = -1) const;
|
||||
int find_last(const Variant &p_value) const;
|
||||
int count(const Variant &p_value) const;
|
||||
bool has(const Variant &p_value) const;
|
||||
void erase(const Variant& p_value);
|
||||
|
||||
void erase(const Variant &p_value);
|
||||
void push_front(const Variant& p_value);
|
||||
void pop_back();
|
||||
void pop_front();
|
||||
|
||||
void push_front(const Variant &p_value);
|
||||
Variant pop_back();
|
||||
Variant pop_front();
|
||||
|
||||
Array duplicate(bool p_deep = false) const;
|
||||
|
||||
Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
|
||||
|
||||
Variant min() const;
|
||||
Variant max() const;
|
||||
|
||||
const void *id() const;
|
||||
|
||||
Array(const Array &p_from);
|
||||
Array();
|
||||
Array(const Array& p_from);
|
||||
Array(bool p_shared=false);
|
||||
~Array();
|
||||
|
||||
};
|
||||
|
||||
#endif // ARRAY_H
|
||||
|
||||
35
core/balloon_allocator.h
Normal file
35
core/balloon_allocator.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*************************************************************************/
|
||||
/* balloon_allocator.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef BALLOON_ALLOCATOR_H
|
||||
#define BALLOON_ALLOCATOR_H
|
||||
|
||||
#include "os/memory.h"
|
||||
|
||||
#include "allocators.h"
|
||||
#endif // BALLOON_ALLOCATOR_H
|
||||
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
env.add_source_files(env.core_sources,"*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,120 +1,73 @@
|
||||
/*************************************************************************/
|
||||
/* core_bind.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef CORE_BIND_H
|
||||
#define CORE_BIND_H
|
||||
|
||||
#include "core/image.h"
|
||||
#include "core/io/compression.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#include "core/os/dir_access.h"
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/os/semaphore.h"
|
||||
#include "core/os/thread.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/file_access.h"
|
||||
#include "os/dir_access.h"
|
||||
#include "os/thread.h"
|
||||
#include "os/semaphore.h"
|
||||
|
||||
|
||||
class _ResourceLoader : public Object {
|
||||
GDCLASS(_ResourceLoader, Object);
|
||||
OBJ_TYPE(_ResourceLoader,Object);
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
static _ResourceLoader *singleton;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static _ResourceLoader *get_singleton() { return singleton; }
|
||||
Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "");
|
||||
RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
|
||||
PoolVector<String> get_recognized_extensions_for_type(const String &p_type);
|
||||
Ref<ResourceInteractiveLoader> load_interactive(const String& p_path,const String& p_type_hint="");
|
||||
RES load(const String &p_path,const String& p_type_hint="", bool p_no_cache = false);
|
||||
DVector<String> get_recognized_extensions_for_type(const String& p_type);
|
||||
void set_abort_on_missing_resources(bool p_abort);
|
||||
PoolStringArray get_dependencies(const String &p_path);
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
bool has(const String &p_path);
|
||||
#endif // DISABLE_DEPRECATED
|
||||
bool has_cached(const String &p_path);
|
||||
bool exists(const String &p_path, const String &p_type_hint = "");
|
||||
StringArray get_dependencies(const String& p_path);
|
||||
bool has(const String& p_path);
|
||||
|
||||
_ResourceLoader();
|
||||
};
|
||||
|
||||
class _ResourceSaver : public Object {
|
||||
GDCLASS(_ResourceSaver, Object);
|
||||
OBJ_TYPE(_ResourceSaver,Object);
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
static _ResourceSaver *singleton;
|
||||
|
||||
public:
|
||||
|
||||
enum SaverFlags {
|
||||
|
||||
FLAG_RELATIVE_PATHS = 1,
|
||||
FLAG_BUNDLE_RESOURCES = 2,
|
||||
FLAG_CHANGE_PATH = 4,
|
||||
FLAG_OMIT_EDITOR_PROPERTIES = 8,
|
||||
FLAG_SAVE_BIG_ENDIAN = 16,
|
||||
FLAG_COMPRESS = 32,
|
||||
FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
|
||||
FLAG_RELATIVE_PATHS=1,
|
||||
FLAG_BUNDLE_RESOURCES=2,
|
||||
FLAG_CHANGE_PATH=4,
|
||||
FLAG_OMIT_EDITOR_PROPERTIES=8,
|
||||
FLAG_SAVE_BIG_ENDIAN=16,
|
||||
FLAG_COMPRESS=32,
|
||||
};
|
||||
|
||||
static _ResourceSaver *get_singleton() { return singleton; }
|
||||
|
||||
Error save(const String &p_path, const RES &p_resource, SaverFlags p_flags);
|
||||
PoolVector<String> get_recognized_extensions(const RES &p_resource);
|
||||
Error save(const String &p_path,const RES& p_resource, uint32_t p_flags);
|
||||
DVector<String> get_recognized_extensions(const RES& p_resource);
|
||||
|
||||
|
||||
_ResourceSaver();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_ResourceSaver::SaverFlags);
|
||||
|
||||
class MainLoop;
|
||||
|
||||
class _OS : public Object {
|
||||
GDCLASS(_OS, Object);
|
||||
OBJ_TYPE(_OS,Object);
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
static _OS *singleton;
|
||||
|
||||
public:
|
||||
enum VideoDriver {
|
||||
VIDEO_DRIVER_GLES3,
|
||||
VIDEO_DRIVER_GLES2,
|
||||
};
|
||||
|
||||
enum PowerState {
|
||||
POWERSTATE_UNKNOWN, // Cannot determine power status.
|
||||
POWERSTATE_ON_BATTERY, // Not plugged in, running on the battery.
|
||||
POWERSTATE_NO_BATTERY, // Plugged in, no battery available.
|
||||
POWERSTATE_CHARGING, // Plugged in, charging battery.
|
||||
POWERSTATE_CHARGED // Plugged in, battery charged.
|
||||
};
|
||||
|
||||
enum Weekday {
|
||||
DAY_SUNDAY,
|
||||
@ -127,9 +80,7 @@ public:
|
||||
};
|
||||
|
||||
enum Month {
|
||||
// Start at 1 to follow Windows SYSTEMTIME structure
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
|
||||
MONTH_JANUARY = 1,
|
||||
MONTH_JANUARY,
|
||||
MONTH_FEBRUARY,
|
||||
MONTH_MARCH,
|
||||
MONTH_APRIL,
|
||||
@ -143,51 +94,30 @@ public:
|
||||
MONTH_DECEMBER
|
||||
};
|
||||
|
||||
void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
|
||||
void global_menu_add_separator(const String &p_menu);
|
||||
void global_menu_remove_item(const String &p_menu, int p_idx);
|
||||
void global_menu_clear(const String &p_menu);
|
||||
|
||||
Point2 get_mouse_position() const;
|
||||
void set_window_title(const String &p_title);
|
||||
Point2 get_mouse_pos() const;
|
||||
void set_window_title(const String& p_title);
|
||||
int get_mouse_button_state() const;
|
||||
|
||||
void set_clipboard(const String &p_text);
|
||||
|
||||
void set_clipboard(const String& p_text);
|
||||
String get_clipboard() const;
|
||||
|
||||
void set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen = 0);
|
||||
Size2 get_video_mode(int p_screen = 0) const;
|
||||
bool is_video_mode_fullscreen(int p_screen = 0) const;
|
||||
bool is_video_mode_resizable(int p_screen = 0) const;
|
||||
Array get_fullscreen_mode_list(int p_screen = 0) const;
|
||||
void set_video_mode(const Size2& p_size, bool p_fullscreen,bool p_resizeable,int p_screen=0);
|
||||
Size2 get_video_mode(int p_screen=0) const;
|
||||
bool is_video_mode_fullscreen(int p_screen=0) const;
|
||||
bool is_video_mode_resizable(int p_screen=0) const;
|
||||
Array get_fullscreen_mode_list(int p_screen=0) const;
|
||||
|
||||
virtual int get_video_driver_count() const;
|
||||
virtual String get_video_driver_name(VideoDriver p_driver) const;
|
||||
virtual VideoDriver get_current_video_driver() const;
|
||||
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual String get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual PoolStringArray get_connected_midi_inputs();
|
||||
virtual void open_midi_inputs();
|
||||
virtual void close_midi_inputs();
|
||||
|
||||
virtual int get_screen_count() const;
|
||||
virtual int get_current_screen() const;
|
||||
virtual void set_current_screen(int p_screen);
|
||||
virtual Point2 get_screen_position(int p_screen = -1) const;
|
||||
virtual Size2 get_screen_size(int p_screen = -1) const;
|
||||
virtual int get_screen_dpi(int p_screen = -1) const;
|
||||
virtual Point2 get_screen_position(int p_screen=0) const;
|
||||
virtual Size2 get_screen_size(int p_screen=0) const;
|
||||
virtual Point2 get_window_position() const;
|
||||
virtual void set_window_position(const Point2 &p_position);
|
||||
virtual Size2 get_max_window_size() const;
|
||||
virtual Size2 get_min_window_size() const;
|
||||
virtual void set_window_position(const Point2& p_position);
|
||||
virtual Size2 get_window_size() const;
|
||||
virtual Size2 get_real_window_size() const;
|
||||
virtual Rect2 get_window_safe_area() const;
|
||||
virtual void set_max_window_size(const Size2 &p_size);
|
||||
virtual void set_min_window_size(const Size2 &p_size);
|
||||
virtual void set_window_size(const Size2 &p_size);
|
||||
virtual void set_window_size(const Size2& p_size);
|
||||
virtual void set_window_fullscreen(bool p_enabled);
|
||||
virtual bool is_window_fullscreen() const;
|
||||
virtual void set_window_resizable(bool p_enabled);
|
||||
@ -196,23 +126,7 @@ public:
|
||||
virtual bool is_window_minimized() const;
|
||||
virtual void set_window_maximized(bool p_enabled);
|
||||
virtual bool is_window_maximized() const;
|
||||
virtual void set_window_always_on_top(bool p_enabled);
|
||||
virtual bool is_window_always_on_top() const;
|
||||
virtual bool is_window_focused() const;
|
||||
virtual void request_attention();
|
||||
virtual void center_window();
|
||||
virtual void move_window_to_foreground();
|
||||
|
||||
virtual void set_borderless_window(bool p_borderless);
|
||||
virtual bool get_borderless_window() const;
|
||||
|
||||
virtual bool get_window_per_pixel_transparency_enabled() const;
|
||||
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
|
||||
|
||||
virtual void set_ime_active(const bool p_active);
|
||||
virtual void set_ime_position(const Point2 &p_pos);
|
||||
virtual Point2 get_ime_selection() const;
|
||||
virtual String get_ime_text() const;
|
||||
|
||||
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
|
||||
bool native_video_is_playing();
|
||||
@ -220,86 +134,97 @@ public:
|
||||
void native_video_unpause();
|
||||
void native_video_stop();
|
||||
|
||||
void set_iterations_per_second(int p_ips);
|
||||
int get_iterations_per_second() const;
|
||||
|
||||
void set_target_fps(int p_fps);
|
||||
float get_target_fps() const;
|
||||
|
||||
void set_low_processor_usage_mode(bool p_enabled);
|
||||
bool is_in_low_processor_usage_mode() const;
|
||||
|
||||
void set_low_processor_usage_mode_sleep_usec(int p_usec);
|
||||
int get_low_processor_usage_mode_sleep_usec() const;
|
||||
|
||||
String get_executable_path() const;
|
||||
int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true, Array p_output = Array(), bool p_read_stderr = false);
|
||||
int execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking,Array p_output=Array());
|
||||
|
||||
Error kill(int p_pid);
|
||||
Error shell_open(String p_uri);
|
||||
|
||||
int get_process_id() const;
|
||||
int get_process_ID() const;
|
||||
|
||||
bool has_environment(const String &p_var) const;
|
||||
String get_environment(const String &p_var) const;
|
||||
bool has_environment(const String& p_var) const;
|
||||
String get_environment(const String& p_var) const;
|
||||
|
||||
String get_name() const;
|
||||
Vector<String> get_cmdline_args();
|
||||
|
||||
String get_locale() const;
|
||||
String get_latin_keyboard_variant() const;
|
||||
|
||||
String get_model_name() const;
|
||||
MainLoop *get_main_loop() const;
|
||||
|
||||
void dump_memory_to_file(const String &p_file);
|
||||
void dump_resources_to_file(const String &p_file);
|
||||
String get_custom_level() const;
|
||||
|
||||
bool has_virtual_keyboard() const;
|
||||
void show_virtual_keyboard(const String &p_existing_text = "");
|
||||
void hide_virtual_keyboard();
|
||||
int get_virtual_keyboard_height();
|
||||
float get_frames_per_second() const;
|
||||
|
||||
void print_resources_in_use(bool p_short = false);
|
||||
void print_all_resources(const String &p_to_file);
|
||||
void dump_memory_to_file(const String& p_file);
|
||||
void dump_resources_to_file(const String& p_file);
|
||||
|
||||
void print_resources_in_use(bool p_short=false);
|
||||
void print_all_resources(const String& p_to_file);
|
||||
void print_all_textures_by_size();
|
||||
void print_resources_by_type(const Vector<String> &p_types);
|
||||
void print_resources_by_type(const Vector<String>& p_types);
|
||||
|
||||
bool has_touchscreen_ui_hint() const;
|
||||
|
||||
bool is_debug_build() const;
|
||||
|
||||
String get_unique_id() const;
|
||||
String get_unique_ID() const;
|
||||
|
||||
String get_scancode_string(uint32_t p_code) const;
|
||||
bool is_scancode_unicode(uint32_t p_unicode) const;
|
||||
int find_scancode_from_string(const String &p_code) const;
|
||||
int find_scancode_from_string(const String& p_code) const;
|
||||
|
||||
|
||||
/*
|
||||
struct Date {
|
||||
|
||||
int year;
|
||||
Month month;
|
||||
int day;
|
||||
Weekday weekday;
|
||||
bool dst;
|
||||
};
|
||||
|
||||
struct Time {
|
||||
|
||||
int hour;
|
||||
int min;
|
||||
int sec;
|
||||
};
|
||||
*/
|
||||
|
||||
void set_use_file_access_save_and_swap(bool p_enable);
|
||||
|
||||
void set_native_icon(const String &p_filename);
|
||||
void set_icon(const Ref<Image> &p_icon);
|
||||
|
||||
int get_exit_code() const;
|
||||
void set_exit_code(int p_code);
|
||||
void set_icon(const Image& p_icon);
|
||||
Dictionary get_date(bool utc) const;
|
||||
Dictionary get_time(bool utc) const;
|
||||
Dictionary get_datetime(bool utc) const;
|
||||
Dictionary get_datetime_from_unix_time(int64_t unix_time_val) const;
|
||||
int64_t get_unix_time_from_datetime(Dictionary datetime) const;
|
||||
Dictionary get_time_zone_info() const;
|
||||
uint64_t get_unix_time() const;
|
||||
uint64_t get_system_time_secs() const;
|
||||
uint64_t get_system_time_msecs() const;
|
||||
|
||||
uint64_t get_static_memory_usage() const;
|
||||
uint64_t get_static_memory_peak_usage() const;
|
||||
uint64_t get_dynamic_memory_usage() const;
|
||||
int get_static_memory_usage() const;
|
||||
int get_static_memory_peak_usage() const;
|
||||
int get_dynamic_memory_usage() const;
|
||||
|
||||
void delay_usec(uint32_t p_usec) const;
|
||||
void delay_msec(uint32_t p_msec) const;
|
||||
uint32_t get_ticks_msec() const;
|
||||
uint64_t get_ticks_usec() const;
|
||||
uint32_t get_splash_tick_msec() const;
|
||||
|
||||
bool can_use_threads() const;
|
||||
|
||||
bool can_draw() const;
|
||||
|
||||
bool is_userfs_persistent() const;
|
||||
int get_frames_drawn();
|
||||
|
||||
bool is_stdout_verbose() const;
|
||||
|
||||
@ -329,9 +254,11 @@ public:
|
||||
|
||||
String get_system_dir(SystemDir p_dir) const;
|
||||
|
||||
String get_user_data_dir() const;
|
||||
|
||||
void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
String get_data_dir() const;
|
||||
|
||||
void alert(const String& p_alert,const String& p_title="ALERT!");
|
||||
|
||||
|
||||
void set_screen_orientation(ScreenOrientation p_orientation);
|
||||
ScreenOrientation get_screen_orientation() const;
|
||||
@ -339,244 +266,169 @@ public:
|
||||
void set_keep_screen_on(bool p_enabled);
|
||||
bool is_keep_screen_on() const;
|
||||
|
||||
void set_time_scale(float p_scale);
|
||||
float get_time_scale();
|
||||
|
||||
bool is_ok_left_and_cancel_right() const;
|
||||
|
||||
Error set_thread_name(const String &p_name);
|
||||
|
||||
void set_use_vsync(bool p_enable);
|
||||
bool is_vsync_enabled() const;
|
||||
|
||||
void set_vsync_via_compositor(bool p_enable);
|
||||
bool is_vsync_via_compositor_enabled() const;
|
||||
|
||||
PowerState get_power_state();
|
||||
int get_power_seconds_left();
|
||||
int get_power_percent_left();
|
||||
|
||||
bool has_feature(const String &p_feature) const;
|
||||
|
||||
bool request_permission(const String &p_name);
|
||||
bool request_permissions();
|
||||
Vector<String> get_granted_permissions() const;
|
||||
Error set_thread_name(const String& p_name);
|
||||
|
||||
static _OS *get_singleton() { return singleton; }
|
||||
|
||||
_OS();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_OS::VideoDriver);
|
||||
VARIANT_ENUM_CAST(_OS::PowerState);
|
||||
VARIANT_ENUM_CAST(_OS::Weekday);
|
||||
VARIANT_ENUM_CAST(_OS::Month);
|
||||
VARIANT_ENUM_CAST(_OS::SystemDir);
|
||||
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
|
||||
|
||||
|
||||
class _Geometry : public Object {
|
||||
|
||||
GDCLASS(_Geometry, Object);
|
||||
OBJ_TYPE(_Geometry, Object);
|
||||
|
||||
static _Geometry *singleton;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
static _Geometry *get_singleton();
|
||||
PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
|
||||
PoolVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
|
||||
PoolVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
|
||||
Variant segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
|
||||
Variant line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b);
|
||||
PoolVector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
|
||||
PoolVector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
|
||||
Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
|
||||
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
|
||||
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
|
||||
Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
|
||||
Variant ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
|
||||
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
|
||||
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
|
||||
DVector<Plane> build_box_planes(const Vector3& p_extents);
|
||||
DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z);
|
||||
DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis=Vector3::AXIS_Z);
|
||||
Variant segment_intersects_segment_2d(const Vector2& p_from_a,const Vector2& p_to_a,const Vector2& p_from_b,const Vector2& p_to_b);
|
||||
DVector<Vector2> get_closest_points_between_segments_2d( const Vector2& p1,const Vector2& q1, const Vector2& p2,const Vector2& q2);
|
||||
DVector<Vector3> get_closest_points_between_segments(const Vector3& p1,const Vector3& p2,const Vector3& q1,const Vector3& q2);
|
||||
Vector3 get_closest_point_to_segment(const Vector3& p_point, const Vector3& p_a,const Vector3& p_b);
|
||||
Variant ray_intersects_triangle( const Vector3& p_from, const Vector3& p_dir, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
|
||||
Variant segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
|
||||
bool point_is_inside_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) const;
|
||||
|
||||
PoolVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
|
||||
PoolVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
|
||||
PoolVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
|
||||
bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius);
|
||||
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
|
||||
int get_uv84_normal_bit(const Vector3 &p_vector);
|
||||
DVector<Vector3> segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius);
|
||||
DVector<Vector3> segment_intersects_cylinder( const Vector3& p_from, const Vector3& p_to, float p_height,float p_radius);
|
||||
DVector<Vector3> segment_intersects_convex(const Vector3& p_from, const Vector3& p_to,const Vector<Plane>& p_planes);
|
||||
real_t segment_intersects_circle(const Vector2& p_from, const Vector2& p_to, const Vector2& p_circle_pos, real_t p_circle_radius);
|
||||
int get_uv84_normal_bit(const Vector3& p_vector);
|
||||
|
||||
bool is_polygon_clockwise(const Vector<Vector2> &p_polygon);
|
||||
bool is_point_in_polygon(const Point2 &p_point, const Vector<Vector2> &p_polygon);
|
||||
Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon);
|
||||
Vector<int> triangulate_delaunay_2d(const Vector<Vector2> &p_points);
|
||||
Vector<Point2> convex_hull_2d(const Vector<Point2> &p_points);
|
||||
Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane);
|
||||
Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon);
|
||||
|
||||
enum PolyBooleanOperation {
|
||||
OPERATION_UNION,
|
||||
OPERATION_DIFFERENCE,
|
||||
OPERATION_INTERSECTION,
|
||||
OPERATION_XOR
|
||||
};
|
||||
// 2D polygon boolean operations.
|
||||
Array merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Union (add).
|
||||
Array clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Difference (subtract).
|
||||
Array intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Common area (multiply).
|
||||
Array exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // All but common area (xor).
|
||||
|
||||
// 2D polyline vs polygon operations.
|
||||
Array clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Cut.
|
||||
Array intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Chop.
|
||||
|
||||
// 2D offset polygons/polylines.
|
||||
enum PolyJoinType {
|
||||
JOIN_SQUARE,
|
||||
JOIN_ROUND,
|
||||
JOIN_MITER
|
||||
};
|
||||
enum PolyEndType {
|
||||
END_POLYGON,
|
||||
END_JOINED,
|
||||
END_BUTT,
|
||||
END_SQUARE,
|
||||
END_ROUND
|
||||
};
|
||||
Array offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE);
|
||||
Array offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, PolyEndType p_end_type = END_SQUARE);
|
||||
|
||||
Dictionary make_atlas(const Vector<Size2> &p_rects);
|
||||
Dictionary make_atlas(const Vector<Size2>& p_rects);
|
||||
|
||||
_Geometry();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_Geometry::PolyBooleanOperation);
|
||||
VARIANT_ENUM_CAST(_Geometry::PolyJoinType);
|
||||
VARIANT_ENUM_CAST(_Geometry::PolyEndType);
|
||||
|
||||
|
||||
|
||||
class _File : public Reference {
|
||||
|
||||
GDCLASS(_File, Reference);
|
||||
OBJ_TYPE(_File,Reference);
|
||||
FileAccess *f;
|
||||
bool eswap;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
enum ModeFlags {
|
||||
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
READ_WRITE = 3,
|
||||
WRITE_READ = 7,
|
||||
READ=1,
|
||||
WRITE=2,
|
||||
READ_WRITE=3,
|
||||
WRITE_READ=7,
|
||||
};
|
||||
|
||||
enum CompressionMode {
|
||||
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
|
||||
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
|
||||
COMPRESSION_ZSTD = Compression::MODE_ZSTD,
|
||||
COMPRESSION_GZIP = Compression::MODE_GZIP
|
||||
};
|
||||
Error open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key);
|
||||
Error open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass);
|
||||
|
||||
Error open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key);
|
||||
Error open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass);
|
||||
Error open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ);
|
||||
|
||||
Error open(const String &p_path, ModeFlags p_mode_flags); // open a file.
|
||||
void close(); // Close a file.
|
||||
bool is_open() const; // True when file is open.
|
||||
Error open(const String& p_path, int p_mode_flags); ///< open a file
|
||||
void close(); ///< close a file
|
||||
bool is_open() const; ///< true when file is open
|
||||
|
||||
String get_path() const; // Returns the path for the current open file.
|
||||
String get_path_absolute() const; // Returns the absolute path for the current open file.
|
||||
void seek(int64_t p_position); ///< seek to a given position
|
||||
void seek_end(int64_t p_position=0); ///< seek from the end of file
|
||||
int64_t get_pos() const; ///< get position in the file
|
||||
int64_t get_len() const; ///< get size of the file
|
||||
|
||||
void seek(int64_t p_position); // Seek to a given position.
|
||||
void seek_end(int64_t p_position = 0); // Seek from the end of file.
|
||||
int64_t get_position() const; // Get position in the file.
|
||||
int64_t get_len() const; // Get size of the file.
|
||||
bool eof_reached() const; ///< reading passed EOF
|
||||
|
||||
bool eof_reached() const; // Reading passed EOF.
|
||||
|
||||
uint8_t get_8() const; // Get a byte.
|
||||
uint16_t get_16() const; // Get 16 bits uint.
|
||||
uint32_t get_32() const; // Get 32 bits uint.
|
||||
uint64_t get_64() const; // Get 64 bits uint.
|
||||
uint8_t get_8() const; ///< get a byte
|
||||
uint16_t get_16() const; ///< get 16 bits uint
|
||||
uint32_t get_32() const; ///< get 32 bits uint
|
||||
uint64_t get_64() const; ///< get 64 bits uint
|
||||
|
||||
float get_float() const;
|
||||
double get_double() const;
|
||||
real_t get_real() const;
|
||||
|
||||
Variant get_var(bool p_allow_objects = false) const;
|
||||
Variant get_var() const;
|
||||
|
||||
PoolVector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes.
|
||||
DVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
|
||||
String get_line() const;
|
||||
Vector<String> get_csv_line(const String &p_delim = ",") const;
|
||||
String get_as_text() const;
|
||||
String get_md5(const String &p_path) const;
|
||||
String get_sha256(const String &p_path) const;
|
||||
|
||||
/* Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac).
|
||||
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
|
||||
* It's not about the current CPU type but file formats.
|
||||
* This flags get reset to false (little endian) on each open.
|
||||
* this flags get reset to false (little endian) on each open
|
||||
*/
|
||||
|
||||
void set_endian_swap(bool p_swap);
|
||||
bool get_endian_swap();
|
||||
|
||||
Error get_error() const; // Get last error.
|
||||
Error get_error() const; ///< get last error
|
||||
|
||||
void store_8(uint8_t p_dest); // Store a byte.
|
||||
void store_16(uint16_t p_dest); // Store 16 bits uint.
|
||||
void store_32(uint32_t p_dest); // Store 32 bits uint.
|
||||
void store_64(uint64_t p_dest); // Store 64 bits uint.
|
||||
void store_8(uint8_t p_dest); ///< store a byte
|
||||
void store_16(uint16_t p_dest); ///< store 16 bits uint
|
||||
void store_32(uint32_t p_dest); ///< store 32 bits uint
|
||||
void store_64(uint64_t p_dest); ///< store 64 bits uint
|
||||
|
||||
void store_float(float p_dest);
|
||||
void store_double(double p_dest);
|
||||
void store_real(real_t p_real);
|
||||
|
||||
void store_string(const String &p_string);
|
||||
void store_line(const String &p_string);
|
||||
void store_csv_line(const Vector<String> &p_values, const String &p_delim = ",");
|
||||
void store_string(const String& p_string);
|
||||
void store_line(const String& p_string);
|
||||
|
||||
virtual void store_pascal_string(const String &p_string);
|
||||
virtual void store_pascal_string(const String& p_string);
|
||||
virtual String get_pascal_string();
|
||||
|
||||
void store_buffer(const PoolVector<uint8_t> &p_buffer); // Store an array of bytes.
|
||||
Vector<String> get_csv_line(String delim=",") const;
|
||||
|
||||
void store_var(const Variant &p_var, bool p_full_objects = false);
|
||||
|
||||
bool file_exists(const String &p_name) const; // Return true if a file exists.
|
||||
void store_buffer(const DVector<uint8_t>& p_buffer); ///< store an array of bytes
|
||||
|
||||
uint64_t get_modified_time(const String &p_file) const;
|
||||
void store_var(const Variant& p_var);
|
||||
|
||||
bool file_exists(const String& p_name) const; ///< return true if a file exists
|
||||
|
||||
_File();
|
||||
virtual ~_File();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_File::ModeFlags);
|
||||
VARIANT_ENUM_CAST(_File::CompressionMode);
|
||||
};
|
||||
|
||||
class _Directory : public Reference {
|
||||
|
||||
GDCLASS(_Directory, Reference);
|
||||
OBJ_TYPE(_Directory,Reference);
|
||||
DirAccess *d;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
Error open(const String &p_path);
|
||||
|
||||
Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); // This starts dir listing.
|
||||
Error open(const String& p_path);
|
||||
|
||||
bool list_dir_begin(); ///< This starts dir listing
|
||||
String get_next();
|
||||
bool current_is_dir() const;
|
||||
|
||||
void list_dir_end();
|
||||
void list_dir_end(); ///<
|
||||
|
||||
int get_drive_count();
|
||||
String get_drive(int p_drive);
|
||||
int get_current_drive();
|
||||
|
||||
Error change_dir(String p_dir); // Can be relative or absolute, return false on success.
|
||||
String get_current_dir(); // Return current dir location.
|
||||
Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
|
||||
String get_current_dir(); ///< return current dir location
|
||||
|
||||
Error make_dir(String p_dir);
|
||||
Error make_dir_recursive(String p_dir);
|
||||
@ -586,51 +438,48 @@ public:
|
||||
|
||||
int get_space_left();
|
||||
|
||||
Error copy(String p_from, String p_to);
|
||||
Error copy(String p_from,String p_to);
|
||||
Error rename(String p_from, String p_to);
|
||||
Error remove(String p_name);
|
||||
|
||||
|
||||
_Directory();
|
||||
virtual ~_Directory();
|
||||
|
||||
private:
|
||||
bool _list_skip_navigational;
|
||||
bool _list_skip_hidden;
|
||||
};
|
||||
|
||||
class _Marshalls : public Reference {
|
||||
|
||||
GDCLASS(_Marshalls, Reference);
|
||||
|
||||
static _Marshalls *singleton;
|
||||
OBJ_TYPE(_Marshalls,Reference);
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
|
||||
public:
|
||||
static _Marshalls *get_singleton();
|
||||
|
||||
String variant_to_base64(const Variant &p_var, bool p_full_objects = false);
|
||||
Variant base64_to_variant(const String &p_str, bool p_allow_objects = false);
|
||||
String variant_to_base64(const Variant& p_var);
|
||||
Variant base64_to_variant(const String& p_str);
|
||||
|
||||
String raw_to_base64(const PoolVector<uint8_t> &p_arr);
|
||||
PoolVector<uint8_t> base64_to_raw(const String &p_str);
|
||||
String raw_to_base64(const DVector<uint8_t>& p_arr);
|
||||
DVector<uint8_t> base64_to_raw(const String& p_str);
|
||||
|
||||
String utf8_to_base64(const String &p_str);
|
||||
String base64_to_utf8(const String &p_str);
|
||||
String utf8_to_base64(const String& p_str);
|
||||
String base64_to_utf8(const String& p_str);
|
||||
|
||||
_Marshalls() { singleton = this; }
|
||||
~_Marshalls() { singleton = NULL; }
|
||||
_Marshalls() {};
|
||||
};
|
||||
|
||||
|
||||
class _Mutex : public Reference {
|
||||
|
||||
GDCLASS(_Mutex, Reference);
|
||||
OBJ_TYPE(_Mutex,Reference);
|
||||
Mutex *mutex;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void lock();
|
||||
Error try_lock();
|
||||
void unlock();
|
||||
@ -641,12 +490,12 @@ public:
|
||||
|
||||
class _Semaphore : public Reference {
|
||||
|
||||
GDCLASS(_Semaphore, Reference);
|
||||
OBJ_TYPE(_Semaphore,Reference);
|
||||
Semaphore *semaphore;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
Error wait();
|
||||
Error post();
|
||||
|
||||
@ -656,9 +505,10 @@ public:
|
||||
|
||||
class _Thread : public Reference {
|
||||
|
||||
GDCLASS(_Thread, Reference);
|
||||
OBJ_TYPE(_Thread,Reference);
|
||||
|
||||
protected:
|
||||
|
||||
Variant ret;
|
||||
Variant userdata;
|
||||
volatile bool active;
|
||||
@ -667,17 +517,16 @@ protected:
|
||||
Thread *thread;
|
||||
static void _bind_methods();
|
||||
static void _start_func(void *ud);
|
||||
|
||||
public:
|
||||
|
||||
enum Priority {
|
||||
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_HIGH,
|
||||
PRIORITY_MAX
|
||||
PRIORITY_HIGH
|
||||
};
|
||||
|
||||
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), Priority p_priority = PRIORITY_NORMAL);
|
||||
Error start(Object *p_instance,const StringName& p_method,const Variant& p_userdata=Variant(),int p_priority=PRIORITY_NORMAL);
|
||||
String get_id() const;
|
||||
bool is_active() const;
|
||||
Variant wait_to_finish();
|
||||
@ -686,142 +535,4 @@ public:
|
||||
~_Thread();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_Thread::Priority);
|
||||
|
||||
class _ClassDB : public Object {
|
||||
|
||||
GDCLASS(_ClassDB, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
PoolStringArray get_class_list() const;
|
||||
PoolStringArray get_inheriters_from_class(const StringName &p_class) const;
|
||||
StringName get_parent_class(const StringName &p_class) const;
|
||||
bool class_exists(const StringName &p_class) const;
|
||||
bool is_parent_class(const StringName &p_class, const StringName &p_inherits) const;
|
||||
bool can_instance(const StringName &p_class) const;
|
||||
Variant instance(const StringName &p_class) const;
|
||||
|
||||
bool has_signal(StringName p_class, StringName p_signal) const;
|
||||
Dictionary get_signal(StringName p_class, StringName p_signal) const;
|
||||
Array get_signal_list(StringName p_class, bool p_no_inheritance = false) const;
|
||||
|
||||
Array get_property_list(StringName p_class, bool p_no_inheritance = false) const;
|
||||
Variant get_property(Object *p_object, const StringName &p_property) const;
|
||||
Error set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const;
|
||||
|
||||
bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const;
|
||||
|
||||
Array get_method_list(StringName p_class, bool p_no_inheritance = false) const;
|
||||
|
||||
PoolStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
|
||||
bool has_integer_constant(const StringName &p_class, const StringName &p_name) const;
|
||||
int get_integer_constant(const StringName &p_class, const StringName &p_name) const;
|
||||
StringName get_category(const StringName &p_node) const;
|
||||
|
||||
bool is_class_enabled(StringName p_class) const;
|
||||
|
||||
_ClassDB();
|
||||
~_ClassDB();
|
||||
};
|
||||
|
||||
class _Engine : public Object {
|
||||
GDCLASS(_Engine, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
static _Engine *singleton;
|
||||
|
||||
public:
|
||||
static _Engine *get_singleton() { return singleton; }
|
||||
void set_iterations_per_second(int p_ips);
|
||||
int get_iterations_per_second() const;
|
||||
|
||||
void set_physics_jitter_fix(float p_threshold);
|
||||
float get_physics_jitter_fix() const;
|
||||
float get_physics_interpolation_fraction() const;
|
||||
|
||||
void set_target_fps(int p_fps);
|
||||
int get_target_fps() const;
|
||||
|
||||
float get_frames_per_second() const;
|
||||
uint64_t get_physics_frames() const;
|
||||
uint64_t get_idle_frames() const;
|
||||
|
||||
int get_frames_drawn();
|
||||
|
||||
void set_time_scale(float p_scale);
|
||||
float get_time_scale();
|
||||
|
||||
MainLoop *get_main_loop() const;
|
||||
|
||||
Dictionary get_version_info() const;
|
||||
Dictionary get_author_info() const;
|
||||
Array get_copyright_info() const;
|
||||
Dictionary get_donor_info() const;
|
||||
Dictionary get_license_info() const;
|
||||
String get_license_text() const;
|
||||
|
||||
bool is_in_physics_frame() const;
|
||||
|
||||
bool has_singleton(const String &p_name) const;
|
||||
Object *get_singleton_object(const String &p_name) const;
|
||||
|
||||
void set_editor_hint(bool p_enabled);
|
||||
bool is_editor_hint() const;
|
||||
|
||||
_Engine();
|
||||
};
|
||||
|
||||
class _JSON;
|
||||
|
||||
class JSONParseResult : public Reference {
|
||||
GDCLASS(JSONParseResult, Reference);
|
||||
|
||||
friend class _JSON;
|
||||
|
||||
Error error;
|
||||
String error_string;
|
||||
int error_line;
|
||||
|
||||
Variant result;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_error(Error p_error);
|
||||
Error get_error() const;
|
||||
|
||||
void set_error_string(const String &p_error_string);
|
||||
String get_error_string() const;
|
||||
|
||||
void set_error_line(int p_error_line);
|
||||
int get_error_line() const;
|
||||
|
||||
void set_result(const Variant &p_result);
|
||||
Variant get_result() const;
|
||||
|
||||
JSONParseResult() :
|
||||
error_line(-1) {}
|
||||
};
|
||||
|
||||
class _JSON : public Object {
|
||||
GDCLASS(_JSON, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
static _JSON *singleton;
|
||||
|
||||
public:
|
||||
static _JSON *get_singleton() { return singleton; }
|
||||
|
||||
String print(const Variant &p_value, const String &p_indent = "", bool p_sort_keys = false);
|
||||
Ref<JSONParseResult> parse(const String &p_json);
|
||||
|
||||
_JSON();
|
||||
};
|
||||
|
||||
#endif // CORE_BIND_H
|
||||
|
||||
1475
core/class_db.cpp
1475
core/class_db.cpp
File diff suppressed because it is too large
Load Diff
428
core/class_db.h
428
core/class_db.h
@ -1,428 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* class_db.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef CLASS_DB_H
|
||||
#define CLASS_DB_H
|
||||
|
||||
#include "core/method_bind.h"
|
||||
#include "core/object.h"
|
||||
#include "core/print_string.h"
|
||||
|
||||
/** To bind more then 6 parameters include this:
|
||||
* #include "core/method_bind_ext.gen.inc"
|
||||
*/
|
||||
|
||||
#define DEFVAL(m_defval) (m_defval)
|
||||
|
||||
//#define SIMPLE_METHODDEF
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
||||
struct MethodDefinition {
|
||||
|
||||
StringName name;
|
||||
Vector<StringName> args;
|
||||
MethodDefinition() {}
|
||||
MethodDefinition(const char *p_name) :
|
||||
name(p_name) {}
|
||||
MethodDefinition(const StringName &p_name) :
|
||||
name(p_name) {}
|
||||
};
|
||||
|
||||
MethodDefinition D_METHOD(const char *p_name);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
|
||||
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
|
||||
|
||||
#else
|
||||
|
||||
//#define NO_VARIADIC_MACROS
|
||||
|
||||
#ifdef NO_VARIADIC_MACROS
|
||||
|
||||
static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// When DEBUG_METHODS_ENABLED is set this will let the engine know
|
||||
// the argument names for easier debugging.
|
||||
#define D_METHOD(m_c, ...) m_c
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
class ClassDB {
|
||||
public:
|
||||
enum APIType {
|
||||
API_CORE,
|
||||
API_EDITOR,
|
||||
API_NONE
|
||||
};
|
||||
|
||||
public:
|
||||
struct PropertySetGet {
|
||||
|
||||
int index;
|
||||
StringName setter;
|
||||
StringName getter;
|
||||
MethodBind *_setptr;
|
||||
MethodBind *_getptr;
|
||||
Variant::Type type;
|
||||
};
|
||||
|
||||
struct ClassInfo {
|
||||
|
||||
APIType api;
|
||||
ClassInfo *inherits_ptr;
|
||||
void *class_ptr;
|
||||
HashMap<StringName, MethodBind *> method_map;
|
||||
HashMap<StringName, int> constant_map;
|
||||
HashMap<StringName, List<StringName> > enum_map;
|
||||
HashMap<StringName, MethodInfo> signal_map;
|
||||
List<PropertyInfo> property_list;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
List<StringName> constant_order;
|
||||
List<StringName> method_order;
|
||||
Set<StringName> methods_in_properties;
|
||||
List<MethodInfo> virtual_methods;
|
||||
StringName category;
|
||||
#endif
|
||||
HashMap<StringName, PropertySetGet> property_setget;
|
||||
|
||||
StringName inherits;
|
||||
StringName name;
|
||||
bool disabled;
|
||||
bool exposed;
|
||||
Object *(*creation_func)();
|
||||
ClassInfo();
|
||||
~ClassInfo();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static Object *creator() {
|
||||
return memnew(T);
|
||||
}
|
||||
|
||||
static RWLock *lock;
|
||||
static HashMap<StringName, ClassInfo> classes;
|
||||
static HashMap<StringName, StringName> resource_base_extensions;
|
||||
static HashMap<StringName, StringName> compat_classes;
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
|
||||
#else
|
||||
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount);
|
||||
#endif
|
||||
|
||||
static APIType current_api;
|
||||
|
||||
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
|
||||
|
||||
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
|
||||
static Set<StringName> default_values_cached;
|
||||
|
||||
public:
|
||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||
template <class T>
|
||||
static void _add_class() {
|
||||
|
||||
_add_class2(T::get_class_static(), T::get_parent_class_static());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void register_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
t->creation_func = &creator<T>;
|
||||
t->exposed = true;
|
||||
t->class_ptr = T::get_class_ptr_static();
|
||||
T::register_custom_data_to_otdb();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void register_virtual_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
t->exposed = true;
|
||||
t->class_ptr = T::get_class_ptr_static();
|
||||
//nothing
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static Object *_create_ptr_func() {
|
||||
|
||||
return T::create();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void register_custom_instance_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
t->creation_func = &_create_ptr_func<T>;
|
||||
t->exposed = true;
|
||||
t->class_ptr = T::get_class_ptr_static();
|
||||
T::register_custom_data_to_otdb();
|
||||
}
|
||||
|
||||
static void get_class_list(List<StringName> *p_classes);
|
||||
static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
|
||||
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
|
||||
static StringName get_parent_class_nocheck(const StringName &p_class);
|
||||
static StringName get_parent_class(const StringName &p_class);
|
||||
static bool class_exists(const StringName &p_class);
|
||||
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
|
||||
static bool can_instance(const StringName &p_class);
|
||||
static Object *instance(const StringName &p_class);
|
||||
static APIType get_api_type(const StringName &p_class);
|
||||
|
||||
static uint64_t get_api_hash(APIType p_api);
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, NULL, 0); //use static function, much smaller binary usage
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[1] = { &p_def1 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 1);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[2] = { &p_def1, &p_def2 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 2);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 3);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 4);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 5);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8);
|
||||
}
|
||||
|
||||
template <class M>
|
||||
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
|
||||
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
||||
ERR_FAIL_COND_V(!bind, NULL);
|
||||
|
||||
bind->set_name(p_name);
|
||||
bind->set_default_arguments(p_default_args);
|
||||
|
||||
String instance_type = bind->get_instance_class();
|
||||
|
||||
ClassInfo *type = classes.getptr(instance_type);
|
||||
if (!type) {
|
||||
memdelete(bind);
|
||||
ERR_FAIL_COND_V(!type, NULL);
|
||||
}
|
||||
|
||||
if (type->method_map.has(p_name)) {
|
||||
memdelete(bind);
|
||||
// overloading not supported
|
||||
ERR_FAIL_V_MSG(NULL, "Method already bound: " + instance_type + "::" + p_name + ".");
|
||||
}
|
||||
type->method_map[p_name] = bind;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
// FIXME: <reduz> set_return_type is no longer in MethodBind, so I guess it should be moved to vararg method bind
|
||||
//bind->set_return_type("Variant");
|
||||
type->method_order.push_back(p_name);
|
||||
#endif
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
static void add_signal(StringName p_class, const MethodInfo &p_signal);
|
||||
static bool has_signal(StringName p_class, StringName p_signal);
|
||||
static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal);
|
||||
static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
|
||||
|
||||
static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = "");
|
||||
static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||
static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
|
||||
static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = NULL);
|
||||
static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = NULL);
|
||||
static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
|
||||
static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
|
||||
static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
|
||||
static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
|
||||
static StringName get_property_setter(StringName p_class, const StringName &p_property);
|
||||
static StringName get_property_getter(StringName p_class, const StringName &p_property);
|
||||
|
||||
static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false);
|
||||
static void set_method_flags(StringName p_class, StringName p_method, int p_flags);
|
||||
|
||||
static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
|
||||
static MethodBind *get_method(StringName p_class, StringName p_name);
|
||||
|
||||
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
|
||||
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
|
||||
|
||||
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
|
||||
static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
|
||||
static int get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = NULL);
|
||||
|
||||
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
|
||||
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
|
||||
|
||||
static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = NULL);
|
||||
|
||||
static StringName get_category(const StringName &p_node);
|
||||
|
||||
static void set_class_enabled(StringName p_class, bool p_enable);
|
||||
static bool is_class_enabled(StringName p_class);
|
||||
|
||||
static bool is_class_exposed(StringName p_class);
|
||||
|
||||
static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
|
||||
static void get_resource_base_extensions(List<String> *p_extensions);
|
||||
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
|
||||
|
||||
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
|
||||
static void init();
|
||||
|
||||
static void set_current_api(APIType p_api);
|
||||
static APIType get_current_api();
|
||||
static void cleanup_defaults();
|
||||
static void cleanup();
|
||||
};
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
||||
#define BIND_CONSTANT(m_constant) \
|
||||
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
|
||||
|
||||
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||
ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
||||
|
||||
#else
|
||||
|
||||
#define BIND_CONSTANT(m_constant) \
|
||||
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
|
||||
|
||||
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#define BIND_VMETHOD(m_method) \
|
||||
ClassDB::add_virtual_method(get_class_static(), m_method);
|
||||
|
||||
#else
|
||||
|
||||
#define BIND_VMETHOD(m_method)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // CLASS_DB_H
|
||||
576
core/color.cpp
576
core/color.cpp
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,135 +26,81 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "color.h"
|
||||
#include "math_funcs.h"
|
||||
#include "print_string.h"
|
||||
|
||||
#include "core/color_names.inc"
|
||||
#include "core/map.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/print_string.h"
|
||||
uint32_t Color::to_ARGB32() const {
|
||||
|
||||
uint32_t Color::to_argb32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(a * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(r * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(g * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(b * 255);
|
||||
uint32_t c=(uint8_t)(a*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(r*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(g*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(b*255);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t Color::to_abgr32() const {
|
||||
uint32_t Color::to_32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(a * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(b * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(g * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(r * 255);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t Color::to_rgba32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(r * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(g * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(b * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(a * 255);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t Color::to_abgr64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(a * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(b * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(g * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(r * 65535);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t Color::to_argb64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(a * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(r * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(g * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(b * 65535);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t Color::to_rgba64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(r * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(g * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(b * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(a * 65535);
|
||||
uint32_t c=(uint8_t)(a*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(r*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(g*255);
|
||||
c<<=8;
|
||||
c|=(uint8_t)(b*255);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
float Color::get_h() const {
|
||||
|
||||
float min = MIN(r, g);
|
||||
min = MIN(min, b);
|
||||
float max = MAX(r, g);
|
||||
max = MAX(max, b);
|
||||
float min = MIN( r, g );
|
||||
min = MIN( min, b );
|
||||
float max = MAX( r, g );
|
||||
max = MAX( max, b );
|
||||
|
||||
float delta = max - min;
|
||||
|
||||
if (delta == 0)
|
||||
if( delta == 0 )
|
||||
return 0;
|
||||
|
||||
float h;
|
||||
if (r == max)
|
||||
h = (g - b) / delta; // between yellow & magenta
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / delta; // between cyan & yellow
|
||||
if( r == max )
|
||||
h = ( g - b ) / delta; // between yellow & magenta
|
||||
else if( g == max )
|
||||
h = 2 + ( b - r ) / delta; // between cyan & yellow
|
||||
else
|
||||
h = 4 + (r - g) / delta; // between magenta & cyan
|
||||
h = 4 + ( r - g ) / delta; // between magenta & cyan
|
||||
|
||||
h /= 6.0;
|
||||
if (h < 0)
|
||||
h += 1.0;
|
||||
h/=6.0;
|
||||
if (h<0)
|
||||
h+=1.0;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
float Color::get_s() const {
|
||||
|
||||
float min = MIN(r, g);
|
||||
min = MIN(min, b);
|
||||
float max = MAX(r, g);
|
||||
max = MAX(max, b);
|
||||
|
||||
float min = MIN( r, g );
|
||||
min = MIN( min, b );
|
||||
float max = MAX( r, g );
|
||||
max = MAX( max, b );
|
||||
|
||||
float delta = max - min;
|
||||
|
||||
return (max != 0) ? (delta / max) : 0;
|
||||
return (max!=0) ? (delta / max) : 0;
|
||||
|
||||
}
|
||||
|
||||
float Color::get_v() const {
|
||||
|
||||
float max = MAX(r, g);
|
||||
max = MAX(max, b);
|
||||
float max = MAX( r, g );
|
||||
max = MAX( max, b );
|
||||
return max;
|
||||
}
|
||||
|
||||
@ -163,24 +108,24 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
|
||||
int i;
|
||||
float f, p, q, t;
|
||||
a = p_alpha;
|
||||
a=p_alpha;
|
||||
|
||||
if (p_s == 0) {
|
||||
if( p_s == 0 ) {
|
||||
// acp_hromatic (grey)
|
||||
r = g = b = p_v;
|
||||
return;
|
||||
}
|
||||
|
||||
p_h *= 6.0;
|
||||
p_h = Math::fmod(p_h, 6);
|
||||
i = Math::floor(p_h);
|
||||
p_h *=6.0;
|
||||
p_h = Math::fmod(p_h,6);
|
||||
i = Math::floor( p_h );
|
||||
|
||||
f = p_h - i;
|
||||
p = p_v * (1 - p_s);
|
||||
q = p_v * (1 - p_s * f);
|
||||
t = p_v * (1 - p_s * (1 - f));
|
||||
p = p_v * ( 1 - p_s );
|
||||
q = p_v * ( 1 - p_s * f );
|
||||
t = p_v * ( 1 - p_s * ( 1 - f ) );
|
||||
|
||||
switch (i) {
|
||||
switch( i ) {
|
||||
case 0: // Red is the dominant color
|
||||
r = p_v;
|
||||
g = t;
|
||||
@ -214,426 +159,221 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Color::is_equal_approx(const Color &p_color) const {
|
||||
|
||||
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
|
||||
}
|
||||
|
||||
void Color::invert() {
|
||||
|
||||
r = 1.0 - r;
|
||||
g = 1.0 - g;
|
||||
b = 1.0 - b;
|
||||
r=1.0-r;
|
||||
g=1.0-g;
|
||||
b=1.0-b;
|
||||
}
|
||||
void Color::contrast() {
|
||||
|
||||
r = Math::fmod(r + 0.5, 1.0);
|
||||
g = Math::fmod(g + 0.5, 1.0);
|
||||
b = Math::fmod(b + 0.5, 1.0);
|
||||
r=Math::fmod(r+0.5,1.0);
|
||||
g=Math::fmod(g+0.5,1.0);
|
||||
b=Math::fmod(b+0.5,1.0);
|
||||
}
|
||||
|
||||
Color Color::hex(uint32_t p_hex) {
|
||||
|
||||
float a = (p_hex & 0xFF) / 255.0;
|
||||
p_hex >>= 8;
|
||||
float b = (p_hex & 0xFF) / 255.0;
|
||||
p_hex >>= 8;
|
||||
float g = (p_hex & 0xFF) / 255.0;
|
||||
p_hex >>= 8;
|
||||
float r = (p_hex & 0xFF) / 255.0;
|
||||
float a = (p_hex&0xFF)/255.0;
|
||||
p_hex>>=8;
|
||||
float b = (p_hex&0xFF)/255.0;
|
||||
p_hex>>=8;
|
||||
float g = (p_hex&0xFF)/255.0;
|
||||
p_hex>>=8;
|
||||
float r = (p_hex&0xFF)/255.0;
|
||||
|
||||
return Color(r, g, b, a);
|
||||
return Color(r,g,b,a);
|
||||
}
|
||||
|
||||
Color Color::hex64(uint64_t p_hex) {
|
||||
static float _parse_col(const String& p_str, int p_ofs) {
|
||||
|
||||
float a = (p_hex & 0xFFFF) / 65535.0;
|
||||
p_hex >>= 16;
|
||||
float b = (p_hex & 0xFFFF) / 65535.0;
|
||||
p_hex >>= 16;
|
||||
float g = (p_hex & 0xFFFF) / 65535.0;
|
||||
p_hex >>= 16;
|
||||
float r = (p_hex & 0xFFFF) / 65535.0;
|
||||
int ig=0;
|
||||
|
||||
return Color(r, g, b, a);
|
||||
}
|
||||
for(int i=0;i<2;i++) {
|
||||
|
||||
Color Color::from_rgbe9995(uint32_t p_rgbe) {
|
||||
int c=p_str[i+p_ofs];
|
||||
int v=0;
|
||||
|
||||
float r = p_rgbe & 0x1ff;
|
||||
float g = (p_rgbe >> 9) & 0x1ff;
|
||||
float b = (p_rgbe >> 18) & 0x1ff;
|
||||
float e = (p_rgbe >> 27);
|
||||
float m = Math::pow(2, e - 15.0 - 9.0);
|
||||
|
||||
float rd = r * m;
|
||||
float gd = g * m;
|
||||
float bd = b * m;
|
||||
|
||||
return Color(rd, gd, bd, 1.0f);
|
||||
}
|
||||
|
||||
static float _parse_col(const String &p_str, int p_ofs) {
|
||||
|
||||
int ig = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
int c = p_str[i + p_ofs];
|
||||
int v = 0;
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
v = c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
v = c - 'a';
|
||||
v += 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
v = c - 'A';
|
||||
v += 10;
|
||||
if (c>='0' && c<='9') {
|
||||
v=c-'0';
|
||||
} else if (c>='a' && c<='f') {
|
||||
v=c-'a';
|
||||
v+=10;
|
||||
} else if (c>='A' && c<='F') {
|
||||
v=c-'A';
|
||||
v+=10;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
ig += v * 16;
|
||||
if (i==0)
|
||||
ig+=v*16;
|
||||
else
|
||||
ig += v;
|
||||
ig+=v;
|
||||
|
||||
}
|
||||
|
||||
return ig;
|
||||
|
||||
}
|
||||
|
||||
Color Color::inverted() const {
|
||||
|
||||
Color c = *this;
|
||||
Color c=*this;
|
||||
c.invert();
|
||||
return c;
|
||||
}
|
||||
|
||||
Color Color::contrasted() const {
|
||||
|
||||
Color c = *this;
|
||||
Color c=*this;
|
||||
c.contrast();
|
||||
return c;
|
||||
}
|
||||
|
||||
Color Color::html(const String &p_color) {
|
||||
|
||||
Color Color::html(const String& p_color) {
|
||||
|
||||
String color = p_color;
|
||||
if (color.length() == 0)
|
||||
if (color.length()==0)
|
||||
return Color();
|
||||
if (color[0] == '#')
|
||||
color = color.substr(1, color.length() - 1);
|
||||
if (color.length() == 3 || color.length() == 4) {
|
||||
String exp_color;
|
||||
for (int i = 0; i < color.length(); i++) {
|
||||
exp_color += color[i];
|
||||
exp_color += color[i];
|
||||
}
|
||||
color = exp_color;
|
||||
}
|
||||
if (color[0]=='#')
|
||||
color=color.substr(1,color.length()-1);
|
||||
|
||||
bool alpha = false;
|
||||
bool alpha=false;
|
||||
|
||||
if (color.length() == 8) {
|
||||
alpha = true;
|
||||
} else if (color.length() == 6) {
|
||||
alpha = false;
|
||||
if (color.length()==8) {
|
||||
alpha=true;
|
||||
} else if (color.length()==6) {
|
||||
alpha=false;
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + ".");
|
||||
ERR_EXPLAIN("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
|
||||
int a = 255;
|
||||
int a=255;
|
||||
if (alpha) {
|
||||
a = _parse_col(color, 0);
|
||||
ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + ".");
|
||||
a=_parse_col(color,0);
|
||||
if (a<0) {
|
||||
ERR_EXPLAIN("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
}
|
||||
|
||||
int from = alpha ? 2 : 0;
|
||||
int from=alpha?2:0;
|
||||
|
||||
int r = _parse_col(color, from + 0);
|
||||
ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + ".");
|
||||
int g = _parse_col(color, from + 2);
|
||||
ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + ".");
|
||||
int b = _parse_col(color, from + 4);
|
||||
ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_color + ".");
|
||||
int r=_parse_col(color,from+0);
|
||||
if (r<0) {
|
||||
ERR_EXPLAIN("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
int g=_parse_col(color,from+2);
|
||||
if (g<0) {
|
||||
ERR_EXPLAIN("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
int b=_parse_col(color,from+4);
|
||||
if (b<0) {
|
||||
ERR_EXPLAIN("Invalid Color Code: "+p_color);
|
||||
ERR_FAIL_V(Color());
|
||||
}
|
||||
|
||||
return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||
return Color(r/255.0,g/255.0,b/255.0,a/255.0);
|
||||
}
|
||||
|
||||
bool Color::html_is_valid(const String &p_color) {
|
||||
bool Color::html_is_valid(const String& p_color) {
|
||||
|
||||
String color = p_color;
|
||||
|
||||
if (color.length() == 0)
|
||||
if (color.length()==0)
|
||||
return false;
|
||||
if (color[0] == '#')
|
||||
color = color.substr(1, color.length() - 1);
|
||||
if (color[0]=='#')
|
||||
color=color.substr(1,color.length()-1);
|
||||
|
||||
bool alpha = false;
|
||||
bool alpha=false;
|
||||
|
||||
if (color.length() == 8) {
|
||||
alpha = true;
|
||||
} else if (color.length() == 6) {
|
||||
alpha = false;
|
||||
if (color.length()==8) {
|
||||
alpha=true;
|
||||
} else if (color.length()==6) {
|
||||
alpha=false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
int a=255;
|
||||
if (alpha) {
|
||||
int a = _parse_col(color, 0);
|
||||
if (a < 0) {
|
||||
a=_parse_col(color,0);
|
||||
if (a<0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int from = alpha ? 2 : 0;
|
||||
int from=alpha?2:0;
|
||||
|
||||
int r = _parse_col(color, from + 0);
|
||||
if (r < 0) {
|
||||
int r=_parse_col(color,from+0);
|
||||
if (r<0) {
|
||||
return false;
|
||||
}
|
||||
int g = _parse_col(color, from + 2);
|
||||
if (g < 0) {
|
||||
int g=_parse_col(color,from+2);
|
||||
if (g<0) {
|
||||
return false;
|
||||
}
|
||||
int b = _parse_col(color, from + 4);
|
||||
if (b < 0) {
|
||||
int b=_parse_col(color,from+4);
|
||||
if (b<0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Color Color::named(const String &p_name) {
|
||||
if (_named_colors.empty()) _populate_named_colors(); // from color_names.inc
|
||||
String name = p_name;
|
||||
// Normalize name
|
||||
name = name.replace(" ", "");
|
||||
name = name.replace("-", "");
|
||||
name = name.replace("_", "");
|
||||
name = name.replace("'", "");
|
||||
name = name.replace(".", "");
|
||||
name = name.to_lower();
|
||||
|
||||
const Map<String, Color>::Element *color = _named_colors.find(name);
|
||||
ERR_FAIL_NULL_V_MSG(color, Color(), "Invalid color name: " + p_name + ".");
|
||||
return color->value();
|
||||
}
|
||||
|
||||
String _to_hex(float p_val) {
|
||||
|
||||
int v = Math::round(p_val * 255);
|
||||
v = CLAMP(v, 0, 255);
|
||||
int v = p_val * 255;
|
||||
v = CLAMP(v,0,255);
|
||||
String ret;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for(int i=0;i<2;i++) {
|
||||
|
||||
CharType c[2] = { 0, 0 };
|
||||
int lv = v & 0xF;
|
||||
if (lv < 10)
|
||||
c[0] = '0' + lv;
|
||||
CharType c[2]={0,0};
|
||||
int lv = v&0xF;
|
||||
if (lv<10)
|
||||
c[0]='0'+lv;
|
||||
else
|
||||
c[0] = 'a' + lv - 10;
|
||||
c[0]='a'+lv-10;
|
||||
|
||||
v >>= 4;
|
||||
String cs = (const CharType *)c;
|
||||
v>>=4;
|
||||
String cs=(const CharType*)c;
|
||||
ret = cs + ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
String Color::to_html(bool p_alpha) const {
|
||||
|
||||
String txt;
|
||||
txt += _to_hex(r);
|
||||
txt += _to_hex(g);
|
||||
txt += _to_hex(b);
|
||||
txt+=_to_hex(r);
|
||||
txt+=_to_hex(g);
|
||||
txt+=_to_hex(b);
|
||||
if (p_alpha)
|
||||
txt = _to_hex(a) + txt;
|
||||
txt=_to_hex(a)+txt;
|
||||
return txt;
|
||||
|
||||
}
|
||||
|
||||
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
|
||||
|
||||
p_h = Math::fmod(p_h * 360.0f, 360.0f);
|
||||
if (p_h < 0.0)
|
||||
p_h += 360.0f;
|
||||
|
||||
const float h_ = p_h / 60.0f;
|
||||
const float c = p_v * p_s;
|
||||
const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
|
||||
float r, g, b;
|
||||
|
||||
switch ((int)h_) {
|
||||
case 0: {
|
||||
r = c;
|
||||
g = x;
|
||||
b = 0;
|
||||
} break;
|
||||
case 1: {
|
||||
r = x;
|
||||
g = c;
|
||||
b = 0;
|
||||
} break;
|
||||
case 2: {
|
||||
r = 0;
|
||||
g = c;
|
||||
b = x;
|
||||
} break;
|
||||
case 3: {
|
||||
r = 0;
|
||||
g = x;
|
||||
b = c;
|
||||
} break;
|
||||
case 4: {
|
||||
r = x;
|
||||
g = 0;
|
||||
b = c;
|
||||
} break;
|
||||
case 5: {
|
||||
r = c;
|
||||
g = 0;
|
||||
b = x;
|
||||
} break;
|
||||
default: {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} break;
|
||||
}
|
||||
|
||||
const float m = p_v - c;
|
||||
return Color(m + r, m + g, m + b, p_a);
|
||||
}
|
||||
|
||||
// FIXME: Remove once Godot 3.1 has been released
|
||||
float Color::gray() const {
|
||||
|
||||
WARN_DEPRECATED_MSG("'Color.gray()' is deprecated and will be removed in a future version. Use 'Color.v' for a better grayscale approximation.");
|
||||
return (r + g + b) / 3.0;
|
||||
return (r+g+b)/3.0;
|
||||
}
|
||||
|
||||
Color::operator String() const {
|
||||
|
||||
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
|
||||
return rtos(r)+", "+rtos(g)+", "+rtos(b)+", "+rtos(a);
|
||||
}
|
||||
|
||||
Color Color::operator+(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r + p_color.r,
|
||||
g + p_color.g,
|
||||
b + p_color.b,
|
||||
a + p_color.a);
|
||||
}
|
||||
|
||||
void Color::operator+=(const Color &p_color) {
|
||||
|
||||
r = r + p_color.r;
|
||||
g = g + p_color.g;
|
||||
b = b + p_color.b;
|
||||
a = a + p_color.a;
|
||||
}
|
||||
|
||||
Color Color::operator-(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r - p_color.r,
|
||||
g - p_color.g,
|
||||
b - p_color.b,
|
||||
a - p_color.a);
|
||||
}
|
||||
|
||||
void Color::operator-=(const Color &p_color) {
|
||||
|
||||
r = r - p_color.r;
|
||||
g = g - p_color.g;
|
||||
b = b - p_color.b;
|
||||
a = a - p_color.a;
|
||||
}
|
||||
|
||||
Color Color::operator*(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r * p_color.r,
|
||||
g * p_color.g,
|
||||
b * p_color.b,
|
||||
a * p_color.a);
|
||||
}
|
||||
|
||||
Color Color::operator*(const real_t &rvalue) const {
|
||||
|
||||
return Color(
|
||||
r * rvalue,
|
||||
g * rvalue,
|
||||
b * rvalue,
|
||||
a * rvalue);
|
||||
}
|
||||
|
||||
void Color::operator*=(const Color &p_color) {
|
||||
|
||||
r = r * p_color.r;
|
||||
g = g * p_color.g;
|
||||
b = b * p_color.b;
|
||||
a = a * p_color.a;
|
||||
}
|
||||
|
||||
void Color::operator*=(const real_t &rvalue) {
|
||||
|
||||
r = r * rvalue;
|
||||
g = g * rvalue;
|
||||
b = b * rvalue;
|
||||
a = a * rvalue;
|
||||
}
|
||||
|
||||
Color Color::operator/(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r / p_color.r,
|
||||
g / p_color.g,
|
||||
b / p_color.b,
|
||||
a / p_color.a);
|
||||
}
|
||||
|
||||
Color Color::operator/(const real_t &rvalue) const {
|
||||
|
||||
return Color(
|
||||
r / rvalue,
|
||||
g / rvalue,
|
||||
b / rvalue,
|
||||
a / rvalue);
|
||||
}
|
||||
|
||||
void Color::operator/=(const Color &p_color) {
|
||||
|
||||
r = r / p_color.r;
|
||||
g = g / p_color.g;
|
||||
b = b / p_color.b;
|
||||
a = a / p_color.a;
|
||||
}
|
||||
|
||||
void Color::operator/=(const real_t &rvalue) {
|
||||
|
||||
if (rvalue == 0) {
|
||||
r = 1.0;
|
||||
g = 1.0;
|
||||
b = 1.0;
|
||||
a = 1.0;
|
||||
} else {
|
||||
r = r / rvalue;
|
||||
g = g / rvalue;
|
||||
b = b / rvalue;
|
||||
a = a / rvalue;
|
||||
}
|
||||
};
|
||||
|
||||
Color Color::operator-() const {
|
||||
|
||||
return Color(
|
||||
1.0 - r,
|
||||
1.0 - g,
|
||||
1.0 - b,
|
||||
1.0 - a);
|
||||
}
|
||||
|
||||
185
core/color.h
185
core/color.h
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,13 +26,14 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#include "ustring.h"
|
||||
#include "math_funcs.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
struct Color {
|
||||
|
||||
union {
|
||||
@ -47,127 +47,53 @@ struct Color {
|
||||
float components[4];
|
||||
};
|
||||
|
||||
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
|
||||
bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); }
|
||||
bool operator==(const Color &p_color) const { return (r==p_color.r && g==p_color.g && b==p_color.b && a==p_color.a ); }
|
||||
bool operator!=(const Color &p_color) const { return (r!=p_color.r || g!=p_color.g || b!=p_color.b || a!=p_color.a ); }
|
||||
|
||||
uint32_t to_rgba32() const;
|
||||
uint32_t to_argb32() const;
|
||||
uint32_t to_abgr32() const;
|
||||
uint64_t to_rgba64() const;
|
||||
uint64_t to_argb64() const;
|
||||
uint64_t to_abgr64() const;
|
||||
uint32_t to_32() const;
|
||||
uint32_t to_ARGB32() const;
|
||||
float gray() const;
|
||||
float get_h() const;
|
||||
float get_s() const;
|
||||
float get_v() const;
|
||||
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
|
||||
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
|
||||
|
||||
_FORCE_INLINE_ float &operator[](int idx) {
|
||||
_FORCE_INLINE_ float& operator[](int idx) {
|
||||
return components[idx];
|
||||
}
|
||||
_FORCE_INLINE_ const float &operator[](int idx) const {
|
||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||
return components[idx];
|
||||
}
|
||||
|
||||
Color operator+(const Color &p_color) const;
|
||||
void operator+=(const Color &p_color);
|
||||
|
||||
Color operator-() const;
|
||||
Color operator-(const Color &p_color) const;
|
||||
void operator-=(const Color &p_color);
|
||||
|
||||
Color operator*(const Color &p_color) const;
|
||||
Color operator*(const real_t &rvalue) const;
|
||||
void operator*=(const Color &p_color);
|
||||
void operator*=(const real_t &rvalue);
|
||||
|
||||
Color operator/(const Color &p_color) const;
|
||||
Color operator/(const real_t &rvalue) const;
|
||||
void operator/=(const Color &p_color);
|
||||
void operator/=(const real_t &rvalue);
|
||||
|
||||
bool is_equal_approx(const Color &p_color) const;
|
||||
|
||||
void invert();
|
||||
void contrast();
|
||||
Color inverted() const;
|
||||
Color contrasted() const;
|
||||
|
||||
_FORCE_INLINE_ Color linear_interpolate(const Color &p_b, float p_t) const {
|
||||
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
|
||||
|
||||
Color res = *this;
|
||||
Color res=*this;
|
||||
|
||||
res.r += (p_t * (p_b.r - r));
|
||||
res.g += (p_t * (p_b.g - g));
|
||||
res.b += (p_t * (p_b.b - b));
|
||||
res.a += (p_t * (p_b.a - a));
|
||||
res.r+= (p_t * (p_b.r-r));
|
||||
res.g+= (p_t * (p_b.g-g));
|
||||
res.b+= (p_t * (p_b.b-b));
|
||||
res.a+= (p_t * (p_b.a-a));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color darkened(float p_amount) const {
|
||||
_FORCE_INLINE_ Color blend(const Color& p_over) const {
|
||||
|
||||
Color res = *this;
|
||||
res.r = res.r * (1.0f - p_amount);
|
||||
res.g = res.g * (1.0f - p_amount);
|
||||
res.b = res.b * (1.0f - p_amount);
|
||||
return res;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color lightened(float p_amount) const {
|
||||
|
||||
Color res = *this;
|
||||
res.r = res.r + (1.0f - res.r) * p_amount;
|
||||
res.g = res.g + (1.0f - res.g) * p_amount;
|
||||
res.b = res.b + (1.0f - res.b) * p_amount;
|
||||
return res;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
|
||||
|
||||
const float pow2to9 = 512.0f;
|
||||
const float B = 15.0f;
|
||||
//const float Emax = 31.0f;
|
||||
const float N = 9.0f;
|
||||
|
||||
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
|
||||
|
||||
float cRed = MAX(0.0f, MIN(sharedexp, r));
|
||||
float cGreen = MAX(0.0f, MIN(sharedexp, g));
|
||||
float cBlue = MAX(0.0f, MIN(sharedexp, b));
|
||||
|
||||
float cMax = MAX(cRed, MAX(cGreen, cBlue));
|
||||
|
||||
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
|
||||
|
||||
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
|
||||
|
||||
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
|
||||
|
||||
float exps = expp + 1.0f;
|
||||
|
||||
if (0.0 <= sMax && sMax < pow2to9) {
|
||||
exps = expp;
|
||||
}
|
||||
|
||||
float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
|
||||
float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
|
||||
float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
|
||||
|
||||
return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color blend(const Color &p_over) const {
|
||||
|
||||
Color res;
|
||||
float sa = 1.0 - p_over.a;
|
||||
res.a = a * sa + p_over.a;
|
||||
if (res.a == 0) {
|
||||
return Color(0, 0, 0, 0);
|
||||
res.a = a*sa+p_over.a;
|
||||
if (res.a==0) {
|
||||
return Color(0,0,0,0);
|
||||
} else {
|
||||
res.r = (r * a * sa + p_over.r * p_over.a) / res.a;
|
||||
res.g = (g * a * sa + p_over.g * p_over.a) / res.a;
|
||||
res.b = (b * a * sa + p_over.b * p_over.a) / res.a;
|
||||
res.r = (r*a*sa + p_over.r * p_over.a)/res.a;
|
||||
res.g = (g*a*sa + p_over.g * p_over.a)/res.a;
|
||||
res.b = (b*a*sa + p_over.b * p_over.a)/res.a;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -175,64 +101,47 @@ struct Color {
|
||||
_FORCE_INLINE_ Color to_linear() const {
|
||||
|
||||
return Color(
|
||||
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
a);
|
||||
}
|
||||
_FORCE_INLINE_ Color to_srgb() const {
|
||||
|
||||
return Color(
|
||||
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
|
||||
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
|
||||
b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
|
||||
r<0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
g<0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
b<0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
a
|
||||
);
|
||||
}
|
||||
|
||||
static Color hex(uint32_t p_hex);
|
||||
static Color hex64(uint64_t p_hex);
|
||||
static Color html(const String &p_color);
|
||||
static bool html_is_valid(const String &p_color);
|
||||
static Color named(const String &p_name);
|
||||
String to_html(bool p_alpha = true) const;
|
||||
Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
|
||||
static Color from_rgbe9995(uint32_t p_rgbe);
|
||||
static Color html(const String& p_color);
|
||||
static bool html_is_valid(const String& p_color);
|
||||
String to_html(bool p_alpha=true) const;
|
||||
|
||||
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
|
||||
_FORCE_INLINE_ bool operator<(const Color& p_color) const; //used in set keys
|
||||
operator String() const;
|
||||
|
||||
/**
|
||||
* No construct parameters, r=0, g=0, b=0. a=255
|
||||
*/
|
||||
_FORCE_INLINE_ Color() {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 1.0;
|
||||
r=0; g=0; b=0; a=1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0
|
||||
*/
|
||||
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a = 1.0) {
|
||||
r = p_r;
|
||||
g = p_g;
|
||||
b = p_b;
|
||||
a = p_a;
|
||||
}
|
||||
_FORCE_INLINE_ Color(float p_r,float p_g,float p_b,float p_a=1.0) { r=p_r; g=p_g; b=p_b; a=p_a; }
|
||||
};
|
||||
|
||||
bool Color::operator<(const Color &p_color) const {
|
||||
bool Color::operator<(const Color& p_color) const {
|
||||
|
||||
if (r == p_color.r) {
|
||||
if (g == p_color.g) {
|
||||
if (b == p_color.b) {
|
||||
return (a < p_color.a);
|
||||
if (r==p_color.r) {
|
||||
if (g==p_color.g) {
|
||||
if(b==p_color.b) {
|
||||
return (a<p_color.a);
|
||||
} else
|
||||
return (b < p_color.b);
|
||||
return (b<p_color.b);
|
||||
} else
|
||||
return g < p_color.g;
|
||||
return g<p_color.g;
|
||||
} else
|
||||
return r < p_color.r;
|
||||
return r<p_color.r;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,153 +0,0 @@
|
||||
// Names from https://en.wikipedia.org/wiki/X11_color_names
|
||||
#include "core/map.h"
|
||||
|
||||
static Map<String, Color> _named_colors;
|
||||
static void _populate_named_colors() {
|
||||
if (!_named_colors.empty()) return;
|
||||
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
|
||||
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
|
||||
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
|
||||
_named_colors.insert("aquamarine", Color(0.50, 1.00, 0.83));
|
||||
_named_colors.insert("azure", Color(0.94, 1.00, 1.00));
|
||||
_named_colors.insert("beige", Color(0.96, 0.96, 0.86));
|
||||
_named_colors.insert("bisque", Color(1.00, 0.89, 0.77));
|
||||
_named_colors.insert("black", Color(0.00, 0.00, 0.00));
|
||||
_named_colors.insert("blanchedalmond", Color(1.00, 0.92, 0.80));
|
||||
_named_colors.insert("blue", Color(0.00, 0.00, 1.00));
|
||||
_named_colors.insert("blueviolet", Color(0.54, 0.17, 0.89));
|
||||
_named_colors.insert("brown", Color(0.65, 0.16, 0.16));
|
||||
_named_colors.insert("burlywood", Color(0.87, 0.72, 0.53));
|
||||
_named_colors.insert("cadetblue", Color(0.37, 0.62, 0.63));
|
||||
_named_colors.insert("chartreuse", Color(0.50, 1.00, 0.00));
|
||||
_named_colors.insert("chocolate", Color(0.82, 0.41, 0.12));
|
||||
_named_colors.insert("coral", Color(1.00, 0.50, 0.31));
|
||||
_named_colors.insert("cornflower", Color(0.39, 0.58, 0.93));
|
||||
_named_colors.insert("cornsilk", Color(1.00, 0.97, 0.86));
|
||||
_named_colors.insert("crimson", Color(0.86, 0.08, 0.24));
|
||||
_named_colors.insert("cyan", Color(0.00, 1.00, 1.00));
|
||||
_named_colors.insert("darkblue", Color(0.00, 0.00, 0.55));
|
||||
_named_colors.insert("darkcyan", Color(0.00, 0.55, 0.55));
|
||||
_named_colors.insert("darkgoldenrod", Color(0.72, 0.53, 0.04));
|
||||
_named_colors.insert("darkgray", Color(0.66, 0.66, 0.66));
|
||||
_named_colors.insert("darkgreen", Color(0.00, 0.39, 0.00));
|
||||
_named_colors.insert("darkkhaki", Color(0.74, 0.72, 0.42));
|
||||
_named_colors.insert("darkmagenta", Color(0.55, 0.00, 0.55));
|
||||
_named_colors.insert("darkolivegreen", Color(0.33, 0.42, 0.18));
|
||||
_named_colors.insert("darkorange", Color(1.00, 0.55, 0.00));
|
||||
_named_colors.insert("darkorchid", Color(0.60, 0.20, 0.80));
|
||||
_named_colors.insert("darkred", Color(0.55, 0.00, 0.00));
|
||||
_named_colors.insert("darksalmon", Color(0.91, 0.59, 0.48));
|
||||
_named_colors.insert("darkseagreen", Color(0.56, 0.74, 0.56));
|
||||
_named_colors.insert("darkslateblue", Color(0.28, 0.24, 0.55));
|
||||
_named_colors.insert("darkslategray", Color(0.18, 0.31, 0.31));
|
||||
_named_colors.insert("darkturquoise", Color(0.00, 0.81, 0.82));
|
||||
_named_colors.insert("darkviolet", Color(0.58, 0.00, 0.83));
|
||||
_named_colors.insert("deeppink", Color(1.00, 0.08, 0.58));
|
||||
_named_colors.insert("deepskyblue", Color(0.00, 0.75, 1.00));
|
||||
_named_colors.insert("dimgray", Color(0.41, 0.41, 0.41));
|
||||
_named_colors.insert("dodgerblue", Color(0.12, 0.56, 1.00));
|
||||
_named_colors.insert("firebrick", Color(0.70, 0.13, 0.13));
|
||||
_named_colors.insert("floralwhite", Color(1.00, 0.98, 0.94));
|
||||
_named_colors.insert("forestgreen", Color(0.13, 0.55, 0.13));
|
||||
_named_colors.insert("fuchsia", Color(1.00, 0.00, 1.00));
|
||||
_named_colors.insert("gainsboro", Color(0.86, 0.86, 0.86));
|
||||
_named_colors.insert("ghostwhite", Color(0.97, 0.97, 1.00));
|
||||
_named_colors.insert("gold", Color(1.00, 0.84, 0.00));
|
||||
_named_colors.insert("goldenrod", Color(0.85, 0.65, 0.13));
|
||||
_named_colors.insert("gray", Color(0.75, 0.75, 0.75));
|
||||
_named_colors.insert("webgray", Color(0.50, 0.50, 0.50));
|
||||
_named_colors.insert("green", Color(0.00, 1.00, 0.00));
|
||||
_named_colors.insert("webgreen", Color(0.00, 0.50, 0.00));
|
||||
_named_colors.insert("greenyellow", Color(0.68, 1.00, 0.18));
|
||||
_named_colors.insert("honeydew", Color(0.94, 1.00, 0.94));
|
||||
_named_colors.insert("hotpink", Color(1.00, 0.41, 0.71));
|
||||
_named_colors.insert("indianred", Color(0.80, 0.36, 0.36));
|
||||
_named_colors.insert("indigo", Color(0.29, 0.00, 0.51));
|
||||
_named_colors.insert("ivory", Color(1.00, 1.00, 0.94));
|
||||
_named_colors.insert("khaki", Color(0.94, 0.90, 0.55));
|
||||
_named_colors.insert("lavender", Color(0.90, 0.90, 0.98));
|
||||
_named_colors.insert("lavenderblush", Color(1.00, 0.94, 0.96));
|
||||
_named_colors.insert("lawngreen", Color(0.49, 0.99, 0.00));
|
||||
_named_colors.insert("lemonchiffon", Color(1.00, 0.98, 0.80));
|
||||
_named_colors.insert("lightblue", Color(0.68, 0.85, 0.90));
|
||||
_named_colors.insert("lightcoral", Color(0.94, 0.50, 0.50));
|
||||
_named_colors.insert("lightcyan", Color(0.88, 1.00, 1.00));
|
||||
_named_colors.insert("lightgoldenrod", Color(0.98, 0.98, 0.82));
|
||||
_named_colors.insert("lightgray", Color(0.83, 0.83, 0.83));
|
||||
_named_colors.insert("lightgreen", Color(0.56, 0.93, 0.56));
|
||||
_named_colors.insert("lightpink", Color(1.00, 0.71, 0.76));
|
||||
_named_colors.insert("lightsalmon", Color(1.00, 0.63, 0.48));
|
||||
_named_colors.insert("lightseagreen", Color(0.13, 0.70, 0.67));
|
||||
_named_colors.insert("lightskyblue", Color(0.53, 0.81, 0.98));
|
||||
_named_colors.insert("lightslategray", Color(0.47, 0.53, 0.60));
|
||||
_named_colors.insert("lightsteelblue", Color(0.69, 0.77, 0.87));
|
||||
_named_colors.insert("lightyellow", Color(1.00, 1.00, 0.88));
|
||||
_named_colors.insert("lime", Color(0.00, 1.00, 0.00));
|
||||
_named_colors.insert("limegreen", Color(0.20, 0.80, 0.20));
|
||||
_named_colors.insert("linen", Color(0.98, 0.94, 0.90));
|
||||
_named_colors.insert("magenta", Color(1.00, 0.00, 1.00));
|
||||
_named_colors.insert("maroon", Color(0.69, 0.19, 0.38));
|
||||
_named_colors.insert("webmaroon", Color(0.50, 0.00, 0.00));
|
||||
_named_colors.insert("mediumaquamarine", Color(0.40, 0.80, 0.67));
|
||||
_named_colors.insert("mediumblue", Color(0.00, 0.00, 0.80));
|
||||
_named_colors.insert("mediumorchid", Color(0.73, 0.33, 0.83));
|
||||
_named_colors.insert("mediumpurple", Color(0.58, 0.44, 0.86));
|
||||
_named_colors.insert("mediumseagreen", Color(0.24, 0.70, 0.44));
|
||||
_named_colors.insert("mediumslateblue", Color(0.48, 0.41, 0.93));
|
||||
_named_colors.insert("mediumspringgreen", Color(0.00, 0.98, 0.60));
|
||||
_named_colors.insert("mediumturquoise", Color(0.28, 0.82, 0.80));
|
||||
_named_colors.insert("mediumvioletred", Color(0.78, 0.08, 0.52));
|
||||
_named_colors.insert("midnightblue", Color(0.10, 0.10, 0.44));
|
||||
_named_colors.insert("mintcream", Color(0.96, 1.00, 0.98));
|
||||
_named_colors.insert("mistyrose", Color(1.00, 0.89, 0.88));
|
||||
_named_colors.insert("moccasin", Color(1.00, 0.89, 0.71));
|
||||
_named_colors.insert("navajowhite", Color(1.00, 0.87, 0.68));
|
||||
_named_colors.insert("navyblue", Color(0.00, 0.00, 0.50));
|
||||
_named_colors.insert("oldlace", Color(0.99, 0.96, 0.90));
|
||||
_named_colors.insert("olive", Color(0.50, 0.50, 0.00));
|
||||
_named_colors.insert("olivedrab", Color(0.42, 0.56, 0.14));
|
||||
_named_colors.insert("orange", Color(1.00, 0.65, 0.00));
|
||||
_named_colors.insert("orangered", Color(1.00, 0.27, 0.00));
|
||||
_named_colors.insert("orchid", Color(0.85, 0.44, 0.84));
|
||||
_named_colors.insert("palegoldenrod", Color(0.93, 0.91, 0.67));
|
||||
_named_colors.insert("palegreen", Color(0.60, 0.98, 0.60));
|
||||
_named_colors.insert("paleturquoise", Color(0.69, 0.93, 0.93));
|
||||
_named_colors.insert("palevioletred", Color(0.86, 0.44, 0.58));
|
||||
_named_colors.insert("papayawhip", Color(1.00, 0.94, 0.84));
|
||||
_named_colors.insert("peachpuff", Color(1.00, 0.85, 0.73));
|
||||
_named_colors.insert("peru", Color(0.80, 0.52, 0.25));
|
||||
_named_colors.insert("pink", Color(1.00, 0.75, 0.80));
|
||||
_named_colors.insert("plum", Color(0.87, 0.63, 0.87));
|
||||
_named_colors.insert("powderblue", Color(0.69, 0.88, 0.90));
|
||||
_named_colors.insert("purple", Color(0.63, 0.13, 0.94));
|
||||
_named_colors.insert("webpurple", Color(0.50, 0.00, 0.50));
|
||||
_named_colors.insert("rebeccapurple", Color(0.40, 0.20, 0.60));
|
||||
_named_colors.insert("red", Color(1.00, 0.00, 0.00));
|
||||
_named_colors.insert("rosybrown", Color(0.74, 0.56, 0.56));
|
||||
_named_colors.insert("royalblue", Color(0.25, 0.41, 0.88));
|
||||
_named_colors.insert("saddlebrown", Color(0.55, 0.27, 0.07));
|
||||
_named_colors.insert("salmon", Color(0.98, 0.50, 0.45));
|
||||
_named_colors.insert("sandybrown", Color(0.96, 0.64, 0.38));
|
||||
_named_colors.insert("seagreen", Color(0.18, 0.55, 0.34));
|
||||
_named_colors.insert("seashell", Color(1.00, 0.96, 0.93));
|
||||
_named_colors.insert("sienna", Color(0.63, 0.32, 0.18));
|
||||
_named_colors.insert("silver", Color(0.75, 0.75, 0.75));
|
||||
_named_colors.insert("skyblue", Color(0.53, 0.81, 0.92));
|
||||
_named_colors.insert("slateblue", Color(0.42, 0.35, 0.80));
|
||||
_named_colors.insert("slategray", Color(0.44, 0.50, 0.56));
|
||||
_named_colors.insert("snow", Color(1.00, 0.98, 0.98));
|
||||
_named_colors.insert("springgreen", Color(0.00, 1.00, 0.50));
|
||||
_named_colors.insert("steelblue", Color(0.27, 0.51, 0.71));
|
||||
_named_colors.insert("tan", Color(0.82, 0.71, 0.55));
|
||||
_named_colors.insert("teal", Color(0.00, 0.50, 0.50));
|
||||
_named_colors.insert("thistle", Color(0.85, 0.75, 0.85));
|
||||
_named_colors.insert("tomato", Color(1.00, 0.39, 0.28));
|
||||
_named_colors.insert("turquoise", Color(0.25, 0.88, 0.82));
|
||||
_named_colors.insert("transparent", Color(1.00, 1.00, 1.00, 0.00));
|
||||
_named_colors.insert("violet", Color(0.93, 0.51, 0.93));
|
||||
_named_colors.insert("wheat", Color(0.96, 0.87, 0.70));
|
||||
_named_colors.insert("white", Color(1.00, 1.00, 1.00));
|
||||
_named_colors.insert("whitesmoke", Color(0.96, 0.96, 0.96));
|
||||
_named_colors.insert("yellow", Color(1.00, 1.00, 0.00));
|
||||
_named_colors.insert("yellowgreen", Color(0.60, 0.80, 0.20));
|
||||
}
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,10 +26,8 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "command_queue_mt.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
#include "os/os.h"
|
||||
|
||||
void CommandQueueMT::lock() {
|
||||
|
||||
@ -50,24 +47,22 @@ void CommandQueueMT::wait_for_flush() {
|
||||
OS::get_singleton()->delay_usec(1000);
|
||||
}
|
||||
|
||||
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
|
||||
CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
|
||||
|
||||
int idx = -1;
|
||||
int idx=-1;
|
||||
|
||||
while (true) {
|
||||
while(true) {
|
||||
|
||||
lock();
|
||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||
|
||||
if (!sync_sems[i].in_use) {
|
||||
sync_sems[i].in_use = true;
|
||||
idx = i;
|
||||
sync_sems[i].in_use=true;
|
||||
idx=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
||||
if (idx == -1) {
|
||||
if (idx==-1) {
|
||||
wait_for_flush();
|
||||
} else {
|
||||
break;
|
||||
@ -77,57 +72,36 @@ CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
|
||||
return &sync_sems[idx];
|
||||
}
|
||||
|
||||
bool CommandQueueMT::dealloc_one() {
|
||||
tryagain:
|
||||
if (dealloc_ptr == write_ptr) {
|
||||
// The queue is empty
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t size = *(uint32_t *)&command_mem[dealloc_ptr];
|
||||
CommandQueueMT::CommandQueueMT(bool p_sync){
|
||||
|
||||
if (size == 0) {
|
||||
// End of command buffer wrap down
|
||||
dealloc_ptr = 0;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
if (size & 1) {
|
||||
// Still used, nothing can be deallocated
|
||||
return false;
|
||||
}
|
||||
|
||||
dealloc_ptr += (size >> 1) + 8;
|
||||
return true;
|
||||
}
|
||||
|
||||
CommandQueueMT::CommandQueueMT(bool p_sync) {
|
||||
|
||||
read_ptr = 0;
|
||||
write_ptr = 0;
|
||||
dealloc_ptr = 0;
|
||||
read_ptr=0;
|
||||
write_ptr=0;
|
||||
mutex = Mutex::create();
|
||||
command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
|
||||
|
||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||
|
||||
sync_sems[i].sem=Semaphore::create();
|
||||
sync_sems[i].in_use=false;
|
||||
|
||||
|
||||
sync_sems[i].sem = Semaphore::create();
|
||||
sync_sems[i].in_use = false;
|
||||
}
|
||||
if (p_sync)
|
||||
sync = Semaphore::create();
|
||||
else
|
||||
sync = NULL;
|
||||
sync=NULL;
|
||||
}
|
||||
|
||||
|
||||
CommandQueueMT::~CommandQueueMT() {
|
||||
|
||||
if (sync)
|
||||
memdelete(sync);
|
||||
memdelete(mutex);
|
||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||
|
||||
memdelete(sync_sems[i].sem);
|
||||
}
|
||||
memfree(command_mem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,15 +26,222 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "compressed_translation.h"
|
||||
#include "pair.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "core/pair.h"
|
||||
/////////// SMAZ /////////////
|
||||
|
||||
extern "C" {
|
||||
#include "thirdparty/misc/smaz.h"
|
||||
/*
|
||||
Copyright (c) 2006-2009, Salvatore Sanfilippo
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Smaz nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/* Our compression codebook, used for compression */
|
||||
static const char *Smaz_cb[241] = {
|
||||
"\002s,\266", "\003had\232\002leW", "\003on \216", "", "\001yS",
|
||||
"\002ma\255\002li\227", "\003or \260", "", "\002ll\230\003s t\277",
|
||||
"\004fromg\002mel", "", "\003its\332", "\001z\333", "\003ingF", "\001>\336",
|
||||
"\001 \000\003 (\002nc\344", "\002nd=\003 on\312",
|
||||
"\002ne\213\003hat\276\003re q", "", "\002ngT\003herz\004have\306\003s o\225",
|
||||
"", "\003ionk\003s a\254\002ly\352", "\003hisL\003 inN\003 be\252", "",
|
||||
"\003 fo\325\003 of \003 ha\311", "", "\002of\005",
|
||||
"\003 co\241\002no\267\003 ma\370", "", "", "\003 cl\356\003enta\003 an7",
|
||||
"\002ns\300\001\"e", "\003n t\217\002ntP\003s, \205",
|
||||
"\002pe\320\003 we\351\002om\223", "\002on\037", "", "\002y G", "\003 wa\271",
|
||||
"\003 re\321\002or*", "", "\002=\"\251\002ot\337", "\003forD\002ou[",
|
||||
"\003 toR", "\003 th\r", "\003 it\366",
|
||||
"\003but\261\002ra\202\003 wi\363\002</\361", "\003 wh\237", "\002 4",
|
||||
"\003nd ?", "\002re!", "", "\003ng c", "",
|
||||
"\003ly \307\003ass\323\001a\004\002rir", "", "", "", "\002se_", "\003of \"",
|
||||
"\003div\364\002ros\003ere\240", "", "\002ta\310\001bZ\002si\324", "",
|
||||
"\003and\a\002rs\335", "\002rt\362", "\002teE", "\003ati\316", "\002so\263",
|
||||
"\002th\021", "\002tiJ\001c\034\003allp", "\003ate\345", "\002ss\246",
|
||||
"\002stM", "", "\002><\346", "\002to\024", "\003arew", "\001d\030",
|
||||
"\002tr\303", "", "\001\n1\003 a \222", "\003f tv\002veo", "\002un\340", "",
|
||||
"\003e o\242", "\002a \243\002wa\326\001e\002", "\002ur\226\003e a\274",
|
||||
"\002us\244\003\n\r\n\247", "\002ut\304\003e c\373", "\002we\221", "", "",
|
||||
"\002wh\302", "\001f,", "", "", "", "\003d t\206", "", "", "\003th \343",
|
||||
"\001g;", "", "", "\001\r9\003e s\265", "\003e t\234", "", "\003to Y",
|
||||
"\003e\r\n\236", "\002d \036\001h\022", "", "\001,Q", "\002 a\031", "\002 b^",
|
||||
"\002\r\n\025\002 cI", "\002 d\245", "\002 e\253", "\002 fh\001i\b\002e \v",
|
||||
"", "\002 hU\001-\314", "\002 i8", "", "", "\002 l\315", "\002 m{",
|
||||
"\002f :\002 n\354", "\002 o\035", "\002 p}\001.n\003\r\n\r\250", "",
|
||||
"\002 r\275", "\002 s>", "\002 t\016", "", "\002g \235\005which+\003whi\367",
|
||||
"\002 w5", "\001/\305", "\003as \214", "\003at \207", "", "\003who\331", "",
|
||||
"\001l\026\002h \212", "", "\002, $", "", "\004withV", "", "", "", "\001m-", "",
|
||||
"", "\002ac\357", "\002ad\350", "\003TheH", "", "", "\004this\233\001n\t",
|
||||
"", "\002. y", "", "\002alX\003e, \365", "\003tio\215\002be\\",
|
||||
"\002an\032\003ver\347", "", "\004that0\003tha\313\001o\006", "\003was2",
|
||||
"\002arO", "\002as.", "\002at'\003the\001\004they\200\005there\322\005theird",
|
||||
"\002ce\210", "\004were]", "", "\002ch\231\002l \264\001p<", "", "",
|
||||
"\003one\256", "", "\003he \023\002dej", "\003ter\270", "\002cou", "",
|
||||
"\002by\177\002di\201\002eax", "", "\002ec\327", "\002edB", "\002ee\353", "",
|
||||
"", "\001r\f\002n )", "", "", "", "\002el\262", "", "\003in i\002en3", "",
|
||||
"\002o `\001s\n", "", "\002er\033", "\003is t\002es6", "", "\002ge\371",
|
||||
"\004.com\375", "\002fo\334\003our\330", "\003ch \301\001t\003", "\002hab", "",
|
||||
"\003men\374", "", "\002he\020", "", "", "\001u&", "\002hif", "",
|
||||
"\003not\204\002ic\203", "\003ed @\002id\355", "", "", "\002ho\273",
|
||||
"\002r K\001vm", "", "", "", "\003t t\257\002il\360", "\002im\342",
|
||||
"\003en \317\002in\017", "\002io\220", "\002s \027\001wA", "", "\003er |",
|
||||
"\003es ~\002is%", "\002it/", "", "\002iv\272", "",
|
||||
"\002t #\ahttp://C\001x\372", "\002la\211", "\001<\341", "\003, a\224"
|
||||
};
|
||||
|
||||
/* Reverse compression codebook, used for decompression */
|
||||
static const char *Smaz_rcb[254] = {
|
||||
" ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
|
||||
" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
|
||||
"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
|
||||
" ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
|
||||
" ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
|
||||
"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
|
||||
"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
|
||||
"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
|
||||
"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
|
||||
"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
|
||||
"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
|
||||
"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
|
||||
"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
|
||||
" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
|
||||
"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
|
||||
"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
|
||||
"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
|
||||
"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
|
||||
"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
|
||||
" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
|
||||
"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com"
|
||||
};
|
||||
|
||||
static int smaz_compress(const char *in, int inlen, char *out, int outlen) {
|
||||
unsigned int h1,h2,h3=0;
|
||||
int verblen = 0, _outlen = outlen;
|
||||
char verb[256], *_out = out;
|
||||
|
||||
while(inlen) {
|
||||
int j = 7, needed;
|
||||
char *flush = NULL;
|
||||
const char *slot;
|
||||
|
||||
h1 = h2 = in[0]<<3;
|
||||
if (inlen > 1) h2 += in[1];
|
||||
if (inlen > 2) h3 = h2^in[2];
|
||||
if (j > inlen) j = inlen;
|
||||
|
||||
/* Try to lookup substrings into the hash table, starting from the
|
||||
* longer to the shorter substrings */
|
||||
for (; j > 0; j--) {
|
||||
switch(j) {
|
||||
case 1: slot = Smaz_cb[h1%241]; break;
|
||||
case 2: slot = Smaz_cb[h2%241]; break;
|
||||
default: slot = Smaz_cb[h3%241]; break;
|
||||
}
|
||||
while(slot[0]) {
|
||||
if (slot[0] == j && memcmp(slot+1,in,j) == 0) {
|
||||
/* Match found in the hash table,
|
||||
* prepare a verbatim bytes flush if needed */
|
||||
if (verblen) {
|
||||
needed = (verblen == 1) ? 2 : 2+verblen;
|
||||
flush = out;
|
||||
out += needed;
|
||||
outlen -= needed;
|
||||
}
|
||||
/* Emit the byte */
|
||||
if (outlen <= 0) return _outlen+1;
|
||||
out[0] = slot[slot[0]+1];
|
||||
out++;
|
||||
outlen--;
|
||||
inlen -= j;
|
||||
in += j;
|
||||
goto out;
|
||||
} else {
|
||||
slot += slot[0]+2;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Match not found - add the byte to the verbatim buffer */
|
||||
verb[verblen] = in[0];
|
||||
verblen++;
|
||||
inlen--;
|
||||
in++;
|
||||
out:
|
||||
/* Prepare a flush if we reached the flush length limit, and there
|
||||
* is not already a pending flush operation. */
|
||||
if (!flush && (verblen == 256 || (verblen > 0 && inlen == 0))) {
|
||||
needed = (verblen == 1) ? 2 : 2+verblen;
|
||||
flush = out;
|
||||
out += needed;
|
||||
outlen -= needed;
|
||||
if (outlen < 0) return _outlen+1;
|
||||
}
|
||||
/* Perform a verbatim flush if needed */
|
||||
if (flush) {
|
||||
if (verblen == 1) {
|
||||
flush[0] = (signed char)254;
|
||||
flush[1] = verb[0];
|
||||
} else {
|
||||
flush[0] = (signed char)255;
|
||||
flush[1] = (signed char)(verblen-1);
|
||||
memcpy(flush+2,verb,verblen);
|
||||
}
|
||||
flush = NULL;
|
||||
verblen = 0;
|
||||
}
|
||||
}
|
||||
return out-_out;
|
||||
}
|
||||
|
||||
static int smaz_decompress(const char *in, int inlen, char *out, int outlen) {
|
||||
unsigned char *c = (unsigned char*) in;
|
||||
char *_out = out;
|
||||
int _outlen = outlen;
|
||||
|
||||
while(inlen) {
|
||||
if (*c == 254) {
|
||||
/* Verbatim byte */
|
||||
if (outlen < 1) return _outlen+1;
|
||||
*out = *(c+1);
|
||||
out++;
|
||||
outlen--;
|
||||
c += 2;
|
||||
inlen -= 2;
|
||||
} else if (*c == 255) {
|
||||
/* Verbatim string */
|
||||
int len = (*(c+1))+1;
|
||||
if (outlen < len) return _outlen+1;
|
||||
memcpy(out,c+2,len);
|
||||
out += len;
|
||||
outlen -= len;
|
||||
c += 2+len;
|
||||
inlen -= 2+len;
|
||||
} else {
|
||||
/* Codebook entry */
|
||||
const char *s = Smaz_rcb[*c];
|
||||
int len = strlen(s);
|
||||
|
||||
if (outlen < len) return _outlen+1;
|
||||
memcpy(out,s,len);
|
||||
out += len;
|
||||
outlen -= len;
|
||||
c++;
|
||||
inlen--;
|
||||
}
|
||||
}
|
||||
return out-_out;
|
||||
}
|
||||
|
||||
|
||||
/////////// END OF SMAZ /////////////
|
||||
|
||||
struct _PHashTranslationCmp {
|
||||
|
||||
int orig_len;
|
||||
@ -48,246 +254,281 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
List<StringName> keys;
|
||||
p_from->get_message_list(&keys);
|
||||
|
||||
int size = Math::larger_prime(keys.size());
|
||||
int size=Math::larger_prime(keys.size());
|
||||
|
||||
Vector<Vector<Pair<int, CharString> > > buckets;
|
||||
Vector<Map<uint32_t, int> > table;
|
||||
Vector<uint32_t> hfunc_table;
|
||||
Vector<_PHashTranslationCmp> compressed;
|
||||
|
||||
print_line("compressing keys: "+itos(keys.size()));
|
||||
Vector< Vector< Pair<int,CharString> > > buckets;
|
||||
Vector< Map< uint32_t, int > > table;
|
||||
Vector< uint32_t > hfunc_table;
|
||||
Vector< _PHashTranslationCmp > compressed;
|
||||
|
||||
table.resize(size);
|
||||
hfunc_table.resize(size);
|
||||
buckets.resize(size);
|
||||
compressed.resize(keys.size());
|
||||
|
||||
int idx = 0;
|
||||
int total_compression_size = 0;
|
||||
int total_string_size = 0;
|
||||
int idx=0;
|
||||
int total_compression_size=0;
|
||||
int total_string_size=0;
|
||||
|
||||
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
|
||||
for(List<StringName>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
//hash string
|
||||
CharString cs = E->get().operator String().utf8();
|
||||
uint32_t h = hash(0, cs.get_data());
|
||||
Pair<int, CharString> p;
|
||||
p.first = idx;
|
||||
p.second = cs;
|
||||
buckets.write[h % size].push_back(p);
|
||||
uint32_t h = hash(0,cs.get_data());
|
||||
Pair<int,CharString> p;
|
||||
p.first=idx;
|
||||
p.second=cs;
|
||||
buckets[h % size].push_back(p);
|
||||
|
||||
//compress string
|
||||
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
|
||||
_PHashTranslationCmp ps;
|
||||
ps.orig_len = src_s.size();
|
||||
ps.offset = total_compression_size;
|
||||
ps.orig_len=src_s.size();
|
||||
ps.offset=total_compression_size;
|
||||
|
||||
if (ps.orig_len != 0) {
|
||||
if (ps.orig_len!=0) {
|
||||
CharString dst_s;
|
||||
dst_s.resize(src_s.size());
|
||||
int ret = smaz_compress(src_s.get_data(), src_s.size(), dst_s.ptrw(), src_s.size());
|
||||
if (ret >= src_s.size()) {
|
||||
int ret = smaz_compress(src_s.get_data(),src_s.size(),&dst_s[0],src_s.size());
|
||||
if (ret>=src_s.size()) {
|
||||
//if compressed is larger than original, just use original
|
||||
ps.orig_len = src_s.size();
|
||||
ps.compressed = src_s;
|
||||
ps.orig_len=src_s.size();
|
||||
ps.compressed=src_s;
|
||||
} else {
|
||||
dst_s.resize(ret);
|
||||
//ps.orig_len=;
|
||||
ps.compressed = dst_s;
|
||||
ps.compressed=dst_s;
|
||||
}
|
||||
} else {
|
||||
ps.orig_len = 1;
|
||||
ps.orig_len=1;
|
||||
ps.compressed.resize(1);
|
||||
ps.compressed[0] = 0;
|
||||
ps.compressed[0]=0;
|
||||
}
|
||||
|
||||
compressed.write[idx] = ps;
|
||||
total_compression_size += ps.compressed.size();
|
||||
total_string_size += src_s.size();
|
||||
|
||||
compressed[idx]=ps;
|
||||
total_compression_size+=ps.compressed.size();
|
||||
total_string_size+=src_s.size();
|
||||
idx++;
|
||||
}
|
||||
|
||||
int bucket_table_size = 0;
|
||||
int bucket_table_size=0;
|
||||
print_line("total compressed string size: "+itos(total_compression_size)+" ("+itos(total_string_size)+" uncompressed).");
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
for(int i=0;i<size;i++) {
|
||||
|
||||
const Vector<Pair<int, CharString> > &b = buckets[i];
|
||||
Map<uint32_t, int> &t = table.write[i];
|
||||
Vector< Pair<int,CharString> > &b = buckets[i];
|
||||
Map< uint32_t, int > &t=table[i];
|
||||
|
||||
if (b.size() == 0)
|
||||
if (b.size()==0)
|
||||
continue;
|
||||
|
||||
//print_line("bucket: "+itos(i)+" - elements: "+itos(b.size()));
|
||||
|
||||
int d = 1;
|
||||
int item = 0;
|
||||
int item =0;
|
||||
|
||||
while (item < b.size()) {
|
||||
while(item < b.size()) {
|
||||
|
||||
uint32_t slot = hash(d, b[item].second.get_data());
|
||||
uint32_t slot = hash(d,b[item].second.get_data());
|
||||
if (t.has(slot)) {
|
||||
|
||||
item = 0;
|
||||
item=0;
|
||||
d++;
|
||||
t.clear();
|
||||
} else {
|
||||
t[slot] = b[item].first;
|
||||
t[slot]=b[item].first;
|
||||
item++;
|
||||
}
|
||||
}
|
||||
|
||||
hfunc_table.write[i] = d;
|
||||
bucket_table_size += 2 + b.size() * 4;
|
||||
hfunc_table[i]=d;
|
||||
bucket_table_size+=2+b.size()*4;
|
||||
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(bucket_table_size == 0);
|
||||
|
||||
print_line("bucket table size: "+itos(bucket_table_size*4));
|
||||
print_line("hash table size: "+itos(size*4));
|
||||
|
||||
hash_table.resize(size);
|
||||
bucket_table.resize(bucket_table_size);
|
||||
|
||||
PoolVector<int>::Write htwb = hash_table.write();
|
||||
PoolVector<int>::Write btwb = bucket_table.write();
|
||||
DVector<int>::Write htwb = hash_table.write();
|
||||
DVector<int>::Write btwb = bucket_table.write();
|
||||
|
||||
uint32_t *htw = (uint32_t *)&htwb[0];
|
||||
uint32_t *btw = (uint32_t *)&btwb[0];
|
||||
uint32_t *htw = (uint32_t*)&htwb[0];
|
||||
uint32_t *btw = (uint32_t*)&btwb[0];
|
||||
|
||||
int btindex = 0;
|
||||
int collisions = 0;
|
||||
int btindex=0;
|
||||
int collisions=0;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
for(int i=0;i<size;i++) {
|
||||
|
||||
const Map<uint32_t, int> &t = table[i];
|
||||
if (t.size() == 0) {
|
||||
htw[i] = 0xFFFFFFFF; //nothing
|
||||
Map< uint32_t, int > &t=table[i];
|
||||
if (t.size()==0) {
|
||||
htw[i]=0xFFFFFFFF; //nothing
|
||||
continue;
|
||||
} else if (t.size() > 1) {
|
||||
collisions += t.size() - 1;
|
||||
} else if (t.size()>1) {
|
||||
collisions+=t.size()-1;
|
||||
}
|
||||
|
||||
htw[i] = btindex;
|
||||
btw[btindex++] = t.size();
|
||||
btw[btindex++] = hfunc_table[i];
|
||||
htw[i]=btindex;
|
||||
btw[btindex++]=t.size();
|
||||
btw[btindex++]=hfunc_table[i];
|
||||
|
||||
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
|
||||
for( Map< uint32_t, int >::Element *E=t.front();E;E=E->next()) {
|
||||
|
||||
btw[btindex++] = E->key();
|
||||
btw[btindex++] = compressed[E->get()].offset;
|
||||
btw[btindex++] = compressed[E->get()].compressed.size();
|
||||
btw[btindex++] = compressed[E->get()].orig_len;
|
||||
btw[btindex++]=E->key();
|
||||
btw[btindex++]=compressed[E->get()].offset;
|
||||
btw[btindex++]=compressed[E->get()].compressed.size();
|
||||
btw[btindex++]=compressed[E->get()].orig_len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print_line("total collisions: "+itos(collisions));
|
||||
|
||||
strings.resize(total_compression_size);
|
||||
PoolVector<uint8_t>::Write cw = strings.write();
|
||||
DVector<uint8_t>::Write cw = strings.write();
|
||||
|
||||
for (int i = 0; i < compressed.size(); i++) {
|
||||
memcpy(&cw[compressed[i].offset], compressed[i].compressed.get_data(), compressed[i].compressed.size());
|
||||
for(int i=0;i<compressed.size();i++) {
|
||||
memcpy(&cw[compressed[i].offset],compressed[i].compressed.get_data(),compressed[i].compressed.size());
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(btindex != bucket_table_size);
|
||||
|
||||
ERR_FAIL_COND(btindex!=bucket_table_size);
|
||||
set_locale(p_from->get_locale());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
|
||||
bool PHashTranslation::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
String name = p_name.operator String();
|
||||
if (name == "hash_table") {
|
||||
hash_table = p_value;
|
||||
} else if (name == "bucket_table") {
|
||||
bucket_table = p_value;
|
||||
} else if (name == "strings") {
|
||||
strings = p_value;
|
||||
} else if (name == "load_from") {
|
||||
if (name=="hash_table") {
|
||||
hash_table=p_value;
|
||||
//print_line("translation: loaded hash table of size: "+itos(hash_table.size()));
|
||||
} else if (name=="bucket_table") {
|
||||
bucket_table=p_value;
|
||||
//print_line("translation: loaded bucket table of size: "+itos(bucket_table.size()));
|
||||
} else if (name=="strings") {
|
||||
strings=p_value;
|
||||
//print_line("translation: loaded string table of size: "+itos(strings.size()));
|
||||
} else if (name=="load_from") {
|
||||
//print_line("generating");
|
||||
generate(p_value);
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
bool PHashTranslation::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
String name = p_name.operator String();
|
||||
if (name == "hash_table")
|
||||
r_ret = hash_table;
|
||||
else if (name == "bucket_table")
|
||||
r_ret = bucket_table;
|
||||
else if (name == "strings")
|
||||
r_ret = strings;
|
||||
if (name=="hash_table")
|
||||
r_ret=hash_table;
|
||||
else if (name=="bucket_table")
|
||||
r_ret=bucket_table;
|
||||
else if (name=="strings")
|
||||
r_ret=strings;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
|
||||
StringName PHashTranslation::get_message(const StringName& p_src_text) const {
|
||||
|
||||
int htsize = hash_table.size();
|
||||
|
||||
if (htsize == 0)
|
||||
if (htsize==0)
|
||||
return StringName();
|
||||
|
||||
CharString str = p_src_text.operator String().utf8();
|
||||
uint32_t h = hash(0, str.get_data());
|
||||
uint32_t h = hash(0,str.get_data());
|
||||
|
||||
PoolVector<int>::Read htr = hash_table.read();
|
||||
const uint32_t *htptr = (const uint32_t *)&htr[0];
|
||||
PoolVector<int>::Read btr = bucket_table.read();
|
||||
const uint32_t *btptr = (const uint32_t *)&btr[0];
|
||||
PoolVector<uint8_t>::Read sr = strings.read();
|
||||
const char *sptr = (const char *)&sr[0];
|
||||
|
||||
uint32_t p = htptr[h % htsize];
|
||||
DVector<int>::Read htr = hash_table.read();
|
||||
const uint32_t *htptr = (const uint32_t*)&htr[0];
|
||||
DVector<int>::Read btr = bucket_table.read();
|
||||
const uint32_t *btptr = (const uint32_t*)&btr[0];
|
||||
DVector<uint8_t>::Read sr = strings.read();
|
||||
const char *sptr= (const char*)&sr[0];
|
||||
|
||||
if (p == 0xFFFFFFFF) {
|
||||
uint32_t p = htptr[ h % htsize];
|
||||
|
||||
//print_line("String: "+p_src_text.operator String());
|
||||
//print_line("Hash: "+itos(p));
|
||||
|
||||
if (p==0xFFFFFFFF) {
|
||||
// print_line("GETMSG: Nothing!");
|
||||
return StringName(); //nothing
|
||||
}
|
||||
|
||||
const Bucket &bucket = *(const Bucket *)&btptr[p];
|
||||
const Bucket &bucket = *(const Bucket*)&btptr[p];
|
||||
|
||||
h = hash(bucket.func, str.get_data());
|
||||
h = hash(bucket.func,str.get_data());
|
||||
|
||||
int idx = -1;
|
||||
int idx=-1;
|
||||
|
||||
for (int i = 0; i < bucket.size; i++) {
|
||||
for(int i=0;i<bucket.size;i++) {
|
||||
|
||||
if (bucket.elem[i].key == h) {
|
||||
if (bucket.elem[i].key==h) {
|
||||
|
||||
idx = i;
|
||||
idx=i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
//print_line("bucket pos: "+itos(idx));
|
||||
if (idx==-1) {
|
||||
// print_line("GETMSG: Not in Bucket!");
|
||||
return StringName();
|
||||
}
|
||||
|
||||
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
|
||||
|
||||
String rstr;
|
||||
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
|
||||
rstr.parse_utf8(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].uncomp_size );
|
||||
// print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
|
||||
// print_line("Return: "+rstr);
|
||||
|
||||
return rstr;
|
||||
} else {
|
||||
|
||||
CharString uncomp;
|
||||
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
|
||||
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
|
||||
uncomp.resize( bucket.elem[idx].uncomp_size+1 );
|
||||
smaz_decompress(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].comp_size,uncomp.ptr(),bucket.elem[idx].uncomp_size );
|
||||
String rstr;
|
||||
rstr.parse_utf8(uncomp.get_data());
|
||||
// print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size));
|
||||
// print_line("Return: "+rstr);
|
||||
return rstr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "hash_table"));
|
||||
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "bucket_table"));
|
||||
p_list->push_back(PropertyInfo(Variant::POOL_BYTE_ARRAY, "strings"));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
|
||||
void PHashTranslation::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "hash_table"));
|
||||
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "bucket_table"));
|
||||
p_list->push_back( PropertyInfo(Variant::RAW_ARRAY, "strings"));
|
||||
p_list->push_back( PropertyInfo(Variant::OBJECT, "load_from",PROPERTY_HINT_RESOURCE_TYPE,"Translation",PROPERTY_USAGE_EDITOR));
|
||||
|
||||
}
|
||||
void PHashTranslation::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("generate", "from"), &PHashTranslation::generate);
|
||||
ObjectTypeDB::bind_method(_MD("generate","from:Translation"),&PHashTranslation::generate);
|
||||
}
|
||||
|
||||
PHashTranslation::PHashTranslation() {
|
||||
PHashTranslation::PHashTranslation()
|
||||
{
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,25 +26,26 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef COMPRESSED_TRANSLATION_H
|
||||
#define COMPRESSED_TRANSLATION_H
|
||||
|
||||
#include "core/translation.h"
|
||||
#include "translation.h"
|
||||
|
||||
class PHashTranslation : public Translation {
|
||||
|
||||
GDCLASS(PHashTranslation, Translation);
|
||||
OBJ_TYPE(PHashTranslation,Translation);
|
||||
|
||||
|
||||
//this translation uses a sort of modified perfect hash algorithm
|
||||
//it requires hashing strings twice and then does a binary search,
|
||||
//it requieres hashing strings twice and then does a binary search,
|
||||
//so it's slower, but at the same time it has an extreemly high chance
|
||||
//of catching untranslated strings
|
||||
|
||||
//load/store friendly types
|
||||
PoolVector<int> hash_table;
|
||||
PoolVector<int> bucket_table;
|
||||
PoolVector<uint8_t> strings;
|
||||
DVector<int> hash_table;
|
||||
DVector<int> bucket_table;
|
||||
DVector<uint8_t> strings;
|
||||
|
||||
|
||||
struct Bucket {
|
||||
|
||||
@ -63,11 +63,11 @@ class PHashTranslation : public Translation {
|
||||
Elem elem[1];
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
|
||||
_FORCE_INLINE_ uint32_t hash( uint32_t d, const char *p_str ) const {
|
||||
|
||||
if (d == 0)
|
||||
d = 0x1000193;
|
||||
while (*p_str) {
|
||||
if (d==0)
|
||||
d=0x1000193;
|
||||
while(*p_str) {
|
||||
|
||||
d = (d * 0x1000193) ^ uint32_t(*p_str);
|
||||
p_str++;
|
||||
@ -75,15 +75,16 @@ class PHashTranslation : public Translation {
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual StringName get_message(const StringName &p_src_text) const; //overridable for other implementations
|
||||
|
||||
virtual StringName get_message(const StringName& p_src_text) const; //overridable for other implementations
|
||||
void generate(const Ref<Translation> &p_from);
|
||||
|
||||
PHashTranslation();
|
||||
|
||||
@ -1,269 +0,0 @@
|
||||
"""Functions used to generate source files during build time
|
||||
|
||||
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
|
||||
|
||||
"""
|
||||
from platform_methods import subprocess_main
|
||||
from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
|
||||
|
||||
|
||||
def make_certs_header(target, source, env):
|
||||
|
||||
src = source[0]
|
||||
dst = target[0]
|
||||
f = open(src, "rb")
|
||||
g = open_utf8(dst, "w")
|
||||
buf = f.read()
|
||||
decomp_size = len(buf)
|
||||
import zlib
|
||||
buf = zlib.compress(buf)
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("#ifndef _CERTS_RAW_H\n")
|
||||
g.write("#define _CERTS_RAW_H\n")
|
||||
|
||||
# System certs path. Editor will use them if defined. (for package maintainers)
|
||||
path = env['system_certs_path']
|
||||
g.write("#define _SYSTEM_CERTS_PATH \"%s\"\n" % str(path))
|
||||
if env['builtin_certs']:
|
||||
# Defined here and not in env so changing it does not trigger a full rebuild.
|
||||
g.write("#define BUILTIN_CERTS_ENABLED\n")
|
||||
g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
|
||||
g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
|
||||
g.write("static const unsigned char _certs_compressed[] = {\n")
|
||||
for i in range(len(buf)):
|
||||
g.write("\t" + byte_to_str(buf[i]) + ",\n")
|
||||
g.write("};\n")
|
||||
g.write("#endif")
|
||||
|
||||
g.close()
|
||||
f.close()
|
||||
|
||||
|
||||
def make_authors_header(target, source, env):
|
||||
sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
|
||||
sections_id = ["AUTHORS_FOUNDERS", "AUTHORS_LEAD_DEVELOPERS", "AUTHORS_PROJECT_MANAGERS", "AUTHORS_DEVELOPERS"]
|
||||
|
||||
src = source[0]
|
||||
dst = target[0]
|
||||
f = open_utf8(src, "r")
|
||||
g = open_utf8(dst, "w")
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("#ifndef _EDITOR_AUTHORS_H\n")
|
||||
g.write("#define _EDITOR_AUTHORS_H\n")
|
||||
|
||||
reading = False
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
|
||||
for line in f:
|
||||
if reading:
|
||||
if line.startswith(" "):
|
||||
g.write("\t\"" + escape_string(line.strip()) + "\",\n")
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
if reading:
|
||||
close_section()
|
||||
reading = False
|
||||
for section, section_id in zip(sections, sections_id):
|
||||
if line.strip().endswith(section):
|
||||
current_section = escape_string(section_id)
|
||||
reading = True
|
||||
g.write("const char *const " + current_section + "[] = {\n")
|
||||
break
|
||||
|
||||
if reading:
|
||||
close_section()
|
||||
|
||||
g.write("#endif\n")
|
||||
|
||||
g.close()
|
||||
f.close()
|
||||
|
||||
|
||||
def make_donors_header(target, source, env):
|
||||
sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors",
|
||||
"Gold donors", "Silver donors", "Bronze donors"]
|
||||
sections_id = ["DONORS_SPONSOR_PLAT", "DONORS_SPONSOR_GOLD", "DONORS_SPONSOR_MINI",
|
||||
"DONORS_GOLD", "DONORS_SILVER", "DONORS_BRONZE"]
|
||||
|
||||
src = source[0]
|
||||
dst = target[0]
|
||||
f = open_utf8(src, "r")
|
||||
g = open_utf8(dst, "w")
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("#ifndef _EDITOR_DONORS_H\n")
|
||||
g.write("#define _EDITOR_DONORS_H\n")
|
||||
|
||||
reading = False
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
|
||||
for line in f:
|
||||
if reading >= 0:
|
||||
if line.startswith(" "):
|
||||
g.write("\t\"" + escape_string(line.strip()) + "\",\n")
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
if reading:
|
||||
close_section()
|
||||
reading = False
|
||||
for section, section_id in zip(sections, sections_id):
|
||||
if line.strip().endswith(section):
|
||||
current_section = escape_string(section_id)
|
||||
reading = True
|
||||
g.write("const char *const " + current_section + "[] = {\n")
|
||||
break
|
||||
|
||||
if reading:
|
||||
close_section()
|
||||
|
||||
g.write("#endif\n")
|
||||
|
||||
g.close()
|
||||
f.close()
|
||||
|
||||
|
||||
def make_license_header(target, source, env):
|
||||
src_copyright = source[0]
|
||||
src_license = source[1]
|
||||
dst = target[0]
|
||||
|
||||
class LicenseReader:
|
||||
def __init__(self, license_file):
|
||||
self._license_file = license_file
|
||||
self.line_num = 0
|
||||
self.current = self.next_line()
|
||||
|
||||
def next_line(self):
|
||||
line = self._license_file.readline()
|
||||
self.line_num += 1
|
||||
while line.startswith("#"):
|
||||
line = self._license_file.readline()
|
||||
self.line_num += 1
|
||||
self.current = line
|
||||
return line
|
||||
|
||||
def next_tag(self):
|
||||
if not ':' in self.current:
|
||||
return ('', [])
|
||||
tag, line = self.current.split(":", 1)
|
||||
lines = [line.strip()]
|
||||
while self.next_line() and self.current.startswith(" "):
|
||||
lines.append(self.current.strip())
|
||||
return (tag, lines)
|
||||
|
||||
from collections import OrderedDict
|
||||
projects = OrderedDict()
|
||||
license_list = []
|
||||
|
||||
with open_utf8(src_copyright, "r") as copyright_file:
|
||||
reader = LicenseReader(copyright_file)
|
||||
part = {}
|
||||
while reader.current:
|
||||
tag, content = reader.next_tag()
|
||||
if tag in ("Files", "Copyright", "License"):
|
||||
part[tag] = content[:]
|
||||
elif tag == "Comment":
|
||||
# attach part to named project
|
||||
projects[content[0]] = projects.get(content[0], []) + [part]
|
||||
|
||||
if not tag or not reader.current:
|
||||
# end of a paragraph start a new part
|
||||
if "License" in part and not "Files" in part:
|
||||
# no Files tag in this one, so assume standalone license
|
||||
license_list.append(part["License"])
|
||||
part = {}
|
||||
reader.next_line()
|
||||
|
||||
data_list = []
|
||||
for project in itervalues(projects):
|
||||
for part in project:
|
||||
part["file_index"] = len(data_list)
|
||||
data_list += part["Files"]
|
||||
part["copyright_index"] = len(data_list)
|
||||
data_list += part["Copyright"]
|
||||
|
||||
with open_utf8(dst, "w") as f:
|
||||
|
||||
f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
f.write("#ifndef _EDITOR_LICENSE_H\n")
|
||||
f.write("#define _EDITOR_LICENSE_H\n")
|
||||
f.write("const char *const GODOT_LICENSE_TEXT =")
|
||||
|
||||
with open_utf8(src_license, "r") as license_file:
|
||||
for line in license_file:
|
||||
escaped_string = escape_string(line.strip())
|
||||
f.write("\n\t\t\"" + escaped_string + "\\n\"")
|
||||
f.write(";\n\n")
|
||||
|
||||
f.write("struct ComponentCopyrightPart {\n"
|
||||
"\tconst char *license;\n"
|
||||
"\tconst char *const *files;\n"
|
||||
"\tconst char *const *copyright_statements;\n"
|
||||
"\tint file_count;\n"
|
||||
"\tint copyright_count;\n"
|
||||
"};\n\n")
|
||||
|
||||
f.write("struct ComponentCopyright {\n"
|
||||
"\tconst char *name;\n"
|
||||
"\tconst ComponentCopyrightPart *parts;\n"
|
||||
"\tint part_count;\n"
|
||||
"};\n\n")
|
||||
|
||||
f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
|
||||
for line in data_list:
|
||||
f.write("\t\"" + escape_string(line) + "\",\n")
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
|
||||
part_index = 0
|
||||
part_indexes = {}
|
||||
for project_name, project in iteritems(projects):
|
||||
part_indexes[project_name] = part_index
|
||||
for part in project:
|
||||
f.write("\t{ \"" + escape_string(part["License"][0]) + "\", "
|
||||
+ "©RIGHT_INFO_DATA[" + str(part["file_index"]) + "], "
|
||||
+ "©RIGHT_INFO_DATA[" + str(part["copyright_index"]) + "], "
|
||||
+ str(len(part["Files"])) + ", "
|
||||
+ str(len(part["Copyright"])) + " },\n")
|
||||
part_index += 1
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
|
||||
|
||||
f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
|
||||
for project_name, project in iteritems(projects):
|
||||
f.write("\t{ \"" + escape_string(project_name) + "\", "
|
||||
+ "©RIGHT_PROJECT_PARTS[" + str(part_indexes[project_name]) + "], "
|
||||
+ str(len(project)) + " },\n")
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
|
||||
|
||||
f.write("const char *const LICENSE_NAMES[] = {\n")
|
||||
for l in license_list:
|
||||
f.write("\t\"" + escape_string(l[0]) + "\",\n")
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("const char *const LICENSE_BODIES[] = {\n\n")
|
||||
for l in license_list:
|
||||
for line in l[1:]:
|
||||
if line == ".":
|
||||
f.write("\t\"\\n\"\n")
|
||||
else:
|
||||
f.write("\t\"" + escape_string(line) + "\\n\"\n")
|
||||
f.write("\t\"\",\n\n")
|
||||
f.write("};\n\n")
|
||||
|
||||
f.write("#endif\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
subprocess_main(globals())
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,48 +26,23 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core_string_names.h"
|
||||
|
||||
CoreStringNames *CoreStringNames::singleton = NULL;
|
||||
CoreStringNames* CoreStringNames::singleton=NULL;
|
||||
|
||||
CoreStringNames::CoreStringNames() {
|
||||
|
||||
_free=StaticCString::create("free");
|
||||
changed=StaticCString::create("changed");
|
||||
_meta=StaticCString::create("__meta__");
|
||||
_script=StaticCString::create("script/script");
|
||||
script_changed=StaticCString::create("script_changed");
|
||||
___pdcdata=StaticCString::create("___pdcdata");
|
||||
__getvar=StaticCString::create("__getvar");
|
||||
_iter_init=StaticCString::create("_iter_init");
|
||||
_iter_next=StaticCString::create("_iter_next");
|
||||
_iter_get=StaticCString::create("_iter_get");
|
||||
get_rid=StaticCString::create("get_rid");
|
||||
|
||||
|
||||
CoreStringNames::CoreStringNames() :
|
||||
_free(StaticCString::create("free")),
|
||||
changed(StaticCString::create("changed")),
|
||||
_meta(StaticCString::create("__meta__")),
|
||||
_script(StaticCString::create("script")),
|
||||
script_changed(StaticCString::create("script_changed")),
|
||||
___pdcdata(StaticCString::create("___pdcdata")),
|
||||
__getvar(StaticCString::create("__getvar")),
|
||||
_iter_init(StaticCString::create("_iter_init")),
|
||||
_iter_next(StaticCString::create("_iter_next")),
|
||||
_iter_get(StaticCString::create("_iter_get")),
|
||||
get_rid(StaticCString::create("get_rid")),
|
||||
_to_string(StaticCString::create("_to_string")),
|
||||
#ifdef TOOLS_ENABLED
|
||||
_sections_unfolded(StaticCString::create("_sections_unfolded")),
|
||||
#endif
|
||||
_custom_features(StaticCString::create("_custom_features")),
|
||||
x(StaticCString::create("x")),
|
||||
y(StaticCString::create("y")),
|
||||
z(StaticCString::create("z")),
|
||||
w(StaticCString::create("w")),
|
||||
r(StaticCString::create("r")),
|
||||
g(StaticCString::create("g")),
|
||||
b(StaticCString::create("b")),
|
||||
a(StaticCString::create("a")),
|
||||
position(StaticCString::create("position")),
|
||||
size(StaticCString::create("size")),
|
||||
end(StaticCString::create("end")),
|
||||
basis(StaticCString::create("basis")),
|
||||
origin(StaticCString::create("origin")),
|
||||
normal(StaticCString::create("normal")),
|
||||
d(StaticCString::create("d")),
|
||||
h(StaticCString::create("h")),
|
||||
s(StaticCString::create("s")),
|
||||
v(StaticCString::create("v")),
|
||||
r8(StaticCString::create("r8")),
|
||||
g8(StaticCString::create("g8")),
|
||||
b8(StaticCString::create("b8")),
|
||||
a8(StaticCString::create("a8")) {
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,29 +26,25 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef CORE_STRING_NAMES_H
|
||||
#define CORE_STRING_NAMES_H
|
||||
|
||||
#include "core/string_name.h"
|
||||
#include "string_db.h"
|
||||
|
||||
class CoreStringNames {
|
||||
|
||||
friend void register_core_types();
|
||||
friend void unregister_core_types();
|
||||
friend void register_core_types();
|
||||
friend void unregister_core_types();
|
||||
|
||||
static CoreStringNames* singleton;
|
||||
|
||||
static void create() { singleton = memnew(CoreStringNames); }
|
||||
static void free() {
|
||||
memdelete(singleton);
|
||||
singleton = NULL;
|
||||
}
|
||||
static void free() { memdelete( singleton); singleton=NULL; }
|
||||
|
||||
CoreStringNames();
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; }
|
||||
_FORCE_INLINE_ static CoreStringNames* get_singleton() { return singleton; }
|
||||
|
||||
static CoreStringNames *singleton;
|
||||
|
||||
StringName _free;
|
||||
StringName changed;
|
||||
@ -62,34 +57,7 @@ public:
|
||||
StringName _iter_next;
|
||||
StringName _iter_get;
|
||||
StringName get_rid;
|
||||
StringName _to_string;
|
||||
#ifdef TOOLS_ENABLED
|
||||
StringName _sections_unfolded;
|
||||
#endif
|
||||
StringName _custom_features;
|
||||
|
||||
StringName x;
|
||||
StringName y;
|
||||
StringName z;
|
||||
StringName w;
|
||||
StringName r;
|
||||
StringName g;
|
||||
StringName b;
|
||||
StringName a;
|
||||
StringName position;
|
||||
StringName size;
|
||||
StringName end;
|
||||
StringName basis;
|
||||
StringName origin;
|
||||
StringName normal;
|
||||
StringName d;
|
||||
StringName h;
|
||||
StringName s;
|
||||
StringName v;
|
||||
StringName r8;
|
||||
StringName g8;
|
||||
StringName b8;
|
||||
StringName a8;
|
||||
};
|
||||
|
||||
#endif // SCENE_STRING_NAMES_H
|
||||
|
||||
373
core/cowdata.h
373
core/cowdata.h
@ -1,373 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* cowdata.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef COWDATA_H_
|
||||
#define COWDATA_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "core/error_macros.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/safe_refcount.h"
|
||||
|
||||
template <class T>
|
||||
class Vector;
|
||||
class String;
|
||||
class CharString;
|
||||
template <class T, class V>
|
||||
class VMap;
|
||||
|
||||
template <class T>
|
||||
class CowData {
|
||||
template <class TV>
|
||||
friend class Vector;
|
||||
friend class String;
|
||||
friend class CharString;
|
||||
template <class TV, class VV>
|
||||
friend class VMap;
|
||||
|
||||
private:
|
||||
mutable T *_ptr;
|
||||
|
||||
// internal helpers
|
||||
|
||||
_FORCE_INLINE_ uint32_t *_get_refcount() const {
|
||||
|
||||
if (!_ptr)
|
||||
return NULL;
|
||||
|
||||
return reinterpret_cast<uint32_t *>(_ptr) - 2;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t *_get_size() const {
|
||||
|
||||
if (!_ptr)
|
||||
return NULL;
|
||||
|
||||
return reinterpret_cast<uint32_t *>(_ptr) - 1;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ T *_get_data() const {
|
||||
|
||||
if (!_ptr)
|
||||
return NULL;
|
||||
return reinterpret_cast<T *>(_ptr);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
|
||||
//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
|
||||
return next_power_of_2(p_elements * sizeof(T));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
||||
#if defined(_add_overflow) && defined(_mul_overflow)
|
||||
size_t o;
|
||||
size_t p;
|
||||
if (_mul_overflow(p_elements, sizeof(T), &o)) {
|
||||
*out = 0;
|
||||
return false;
|
||||
}
|
||||
*out = next_power_of_2(o);
|
||||
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
|
||||
return true;
|
||||
#else
|
||||
// Speed is more important than correctness here, do the operations unchecked
|
||||
// and hope the best
|
||||
*out = _get_alloc_size(p_elements);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _unref(void *p_data);
|
||||
void _ref(const CowData *p_from);
|
||||
void _ref(const CowData &p_from);
|
||||
void _copy_on_write();
|
||||
|
||||
public:
|
||||
void operator=(const CowData<T> &p_from) { _ref(p_from); }
|
||||
|
||||
_FORCE_INLINE_ T *ptrw() {
|
||||
_copy_on_write();
|
||||
return (T *)_get_data();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const T *ptr() const {
|
||||
return _get_data();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int size() const {
|
||||
uint32_t *size = (uint32_t *)_get_size();
|
||||
if (size)
|
||||
return *size;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void clear() { resize(0); }
|
||||
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
|
||||
|
||||
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
_copy_on_write();
|
||||
_get_data()[p_index] = p_elem;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ T &get_m(int p_index) {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
_copy_on_write();
|
||||
return _get_data()[p_index];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const T &get(int p_index) const {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
return _get_data()[p_index];
|
||||
}
|
||||
|
||||
Error resize(int p_size);
|
||||
|
||||
_FORCE_INLINE_ void remove(int p_index) {
|
||||
|
||||
ERR_FAIL_INDEX(p_index, size());
|
||||
T *p = ptrw();
|
||||
int len = size();
|
||||
for (int i = p_index; i < len - 1; i++) {
|
||||
|
||||
p[i] = p[i + 1];
|
||||
};
|
||||
|
||||
resize(len - 1);
|
||||
};
|
||||
|
||||
Error insert(int p_pos, const T &p_val) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
|
||||
resize(size() + 1);
|
||||
for (int i = (size() - 1); i > p_pos; i--)
|
||||
set(i, get(i - 1));
|
||||
set(p_pos, p_val);
|
||||
|
||||
return OK;
|
||||
};
|
||||
|
||||
int find(const T &p_val, int p_from = 0) const;
|
||||
|
||||
_FORCE_INLINE_ CowData();
|
||||
_FORCE_INLINE_ ~CowData();
|
||||
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_unref(void *p_data) {
|
||||
|
||||
if (!p_data)
|
||||
return;
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
if (atomic_decrement(refc) > 0)
|
||||
return; // still in use
|
||||
// clean up
|
||||
|
||||
if (!__has_trivial_destructor(T)) {
|
||||
uint32_t *count = _get_size();
|
||||
T *data = (T *)(count + 1);
|
||||
|
||||
for (uint32_t i = 0; i < *count; ++i) {
|
||||
// call destructors
|
||||
data[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
// free mem
|
||||
Memory::free_static((uint8_t *)p_data, true);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_copy_on_write() {
|
||||
|
||||
if (!_ptr)
|
||||
return;
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
if (unlikely(*refc > 1)) {
|
||||
/* in use by more than me */
|
||||
uint32_t current_size = *_get_size();
|
||||
|
||||
uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
|
||||
|
||||
*(mem_new - 2) = 1; //refcount
|
||||
*(mem_new - 1) = current_size; //size
|
||||
|
||||
T *_data = (T *)(mem_new);
|
||||
|
||||
// initialize new elements
|
||||
if (__has_trivial_copy(T)) {
|
||||
memcpy(mem_new, _ptr, current_size * sizeof(T));
|
||||
|
||||
} else {
|
||||
for (uint32_t i = 0; i < current_size; i++) {
|
||||
memnew_placement(&_data[i], T(_get_data()[i]));
|
||||
}
|
||||
}
|
||||
|
||||
_unref(_ptr);
|
||||
_ptr = _data;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Error CowData<T>::resize(int p_size) {
|
||||
|
||||
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
|
||||
|
||||
if (p_size == size())
|
||||
return OK;
|
||||
|
||||
if (p_size == 0) {
|
||||
// wants to clean up
|
||||
_unref(_ptr);
|
||||
_ptr = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
// possibly changing size, copy on write
|
||||
_copy_on_write();
|
||||
|
||||
size_t alloc_size;
|
||||
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
|
||||
|
||||
if (p_size > size()) {
|
||||
|
||||
if (size() == 0) {
|
||||
// alloc from scratch
|
||||
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
||||
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
|
||||
*(ptr - 1) = 0; //size, currently none
|
||||
*(ptr - 2) = 1; //refcount
|
||||
|
||||
_ptr = (T *)ptr;
|
||||
|
||||
} else {
|
||||
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||
_ptr = (T *)(_ptrnew);
|
||||
}
|
||||
|
||||
// construct the newly created elements
|
||||
|
||||
if (!__has_trivial_constructor(T)) {
|
||||
T *elems = _get_data();
|
||||
|
||||
for (int i = *_get_size(); i < p_size; i++) {
|
||||
memnew_placement(&elems[i], T);
|
||||
}
|
||||
}
|
||||
|
||||
*_get_size() = p_size;
|
||||
|
||||
} else if (p_size < size()) {
|
||||
|
||||
if (!__has_trivial_destructor(T)) {
|
||||
// deinitialize no longer needed elements
|
||||
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
||||
T *t = &_get_data()[i];
|
||||
t->~T();
|
||||
}
|
||||
}
|
||||
|
||||
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||
|
||||
_ptr = (T *)(_ptrnew);
|
||||
|
||||
*_get_size() = p_size;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int CowData<T>::find(const T &p_val, int p_from) const {
|
||||
int ret = -1;
|
||||
|
||||
if (p_from < 0 || size() == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int i = p_from; i < size(); i++) {
|
||||
if (get(i) == p_val) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_ref(const CowData *p_from) {
|
||||
_ref(*p_from);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_ref(const CowData &p_from) {
|
||||
|
||||
if (_ptr == p_from._ptr)
|
||||
return; // self assign, do nothing.
|
||||
|
||||
_unref(_ptr);
|
||||
_ptr = NULL;
|
||||
|
||||
if (!p_from._ptr)
|
||||
return; //nothing to do
|
||||
|
||||
if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
|
||||
_ptr = p_from._ptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CowData<T>::CowData() {
|
||||
|
||||
_ptr = NULL;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CowData<T>::~CowData() {
|
||||
|
||||
_unref(_ptr);
|
||||
}
|
||||
|
||||
#endif /* COW_H_ */
|
||||
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
env_crypto = env.Clone()
|
||||
|
||||
is_builtin = env["builtin_mbedtls"]
|
||||
has_module = env["module_mbedtls_enabled"]
|
||||
|
||||
if is_builtin or not has_module:
|
||||
# Use our headers for builtin or if the module is not going to be compiled.
|
||||
# We decided not to depend on system mbedtls just for these few files that can
|
||||
# be easily extracted.
|
||||
env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
|
||||
|
||||
# MbedTLS core functions (for CryptoCore).
|
||||
# If the mbedtls module is compiled we don't need to add the .c files with our
|
||||
# custom config since they will be built by the module itself.
|
||||
# Only if the module is not enabled, we must compile here the required sources
|
||||
# to make a "light" build with only the necessary mbedtls files.
|
||||
if not has_module:
|
||||
env_thirdparty = env_crypto.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
# Custom config file
|
||||
env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')])
|
||||
thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
|
||||
thirdparty_mbedtls_sources = [
|
||||
"aes.c",
|
||||
"base64.c",
|
||||
"md5.c",
|
||||
"sha1.c",
|
||||
"sha256.c",
|
||||
"godot_core_mbedtls_platform.c"
|
||||
]
|
||||
thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
|
||||
env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources)
|
||||
|
||||
env_crypto.add_source_files(env.core_sources, "*.cpp")
|
||||
@ -1,170 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* crypto.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
#include "core/engine.h"
|
||||
#include "core/io/certs_compressed.gen.h"
|
||||
#include "core/io/compression.h"
|
||||
|
||||
/// Resources
|
||||
|
||||
CryptoKey *(*CryptoKey::_create)() = NULL;
|
||||
CryptoKey *CryptoKey::create() {
|
||||
if (_create)
|
||||
return _create();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CryptoKey::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
|
||||
ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
|
||||
}
|
||||
|
||||
X509Certificate *(*X509Certificate::_create)() = NULL;
|
||||
X509Certificate *X509Certificate::create() {
|
||||
if (_create)
|
||||
return _create();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void X509Certificate::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
|
||||
ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
|
||||
}
|
||||
|
||||
/// Crypto
|
||||
|
||||
void (*Crypto::_load_default_certificates)(String p_path) = NULL;
|
||||
Crypto *(*Crypto::_create)() = NULL;
|
||||
Crypto *Crypto::create() {
|
||||
if (_create)
|
||||
return _create();
|
||||
return memnew(Crypto);
|
||||
}
|
||||
|
||||
void Crypto::load_default_certificates(String p_path) {
|
||||
|
||||
if (_load_default_certificates)
|
||||
_load_default_certificates(p_path);
|
||||
}
|
||||
|
||||
void Crypto::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
|
||||
ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa);
|
||||
ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
|
||||
}
|
||||
|
||||
PoolByteArray Crypto::generate_random_bytes(int p_bytes) {
|
||||
ERR_FAIL_V_MSG(PoolByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
|
||||
}
|
||||
|
||||
Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) {
|
||||
ERR_FAIL_V_MSG(NULL, "generate_rsa is not available when mbedtls module is disabled.");
|
||||
}
|
||||
|
||||
Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
|
||||
ERR_FAIL_V_MSG(NULL, "generate_self_signed_certificate is not available when mbedtls module is disabled.");
|
||||
}
|
||||
|
||||
Crypto::Crypto() {
|
||||
}
|
||||
|
||||
/// Resource loader/saver
|
||||
|
||||
RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "crt") {
|
||||
X509Certificate *cert = X509Certificate::create();
|
||||
if (cert)
|
||||
cert->load(p_path);
|
||||
return cert;
|
||||
} else if (el == "key") {
|
||||
CryptoKey *key = CryptoKey::create();
|
||||
if (key)
|
||||
key->load(p_path);
|
||||
return key;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("crt");
|
||||
p_extensions->push_back("key");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
|
||||
|
||||
return p_type == "X509Certificate" || p_type == "CryptoKey";
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "crt")
|
||||
return "X509Certificate";
|
||||
else if (el == "key")
|
||||
return "CryptoKey";
|
||||
return "";
|
||||
}
|
||||
|
||||
Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
|
||||
|
||||
Error err;
|
||||
Ref<X509Certificate> cert = p_resource;
|
||||
Ref<CryptoKey> key = p_resource;
|
||||
if (cert.is_valid()) {
|
||||
err = cert->save(p_path);
|
||||
} else if (key.is_valid()) {
|
||||
err = key->save(p_path);
|
||||
} else {
|
||||
ERR_FAIL_V(ERR_INVALID_PARAMETER);
|
||||
}
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Crypto resource to file '" + p_path + "'.");
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
|
||||
|
||||
const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
|
||||
const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
|
||||
if (cert) {
|
||||
p_extensions->push_back("crt");
|
||||
}
|
||||
if (key) {
|
||||
p_extensions->push_back("key");
|
||||
}
|
||||
}
|
||||
bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
|
||||
|
||||
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* crypto.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#include "core/reference.h"
|
||||
#include "core/resource.h"
|
||||
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
|
||||
class CryptoKey : public Resource {
|
||||
GDCLASS(CryptoKey, Resource);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
static CryptoKey *(*_create)();
|
||||
|
||||
public:
|
||||
static CryptoKey *create();
|
||||
virtual Error load(String p_path) = 0;
|
||||
virtual Error save(String p_path) = 0;
|
||||
};
|
||||
|
||||
class X509Certificate : public Resource {
|
||||
GDCLASS(X509Certificate, Resource);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
static X509Certificate *(*_create)();
|
||||
|
||||
public:
|
||||
static X509Certificate *create();
|
||||
virtual Error load(String p_path) = 0;
|
||||
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
|
||||
virtual Error save(String p_path) = 0;
|
||||
};
|
||||
|
||||
class Crypto : public Reference {
|
||||
GDCLASS(Crypto, Reference);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
static Crypto *(*_create)();
|
||||
static void (*_load_default_certificates)(String p_path);
|
||||
|
||||
public:
|
||||
static Crypto *create();
|
||||
static void load_default_certificates(String p_path);
|
||||
|
||||
virtual PoolByteArray generate_random_bytes(int p_bytes);
|
||||
virtual Ref<CryptoKey> generate_rsa(int p_bytes);
|
||||
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
|
||||
|
||||
Crypto();
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
|
||||
GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
|
||||
|
||||
public:
|
||||
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String &p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
};
|
||||
|
||||
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
|
||||
GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
|
||||
|
||||
public:
|
||||
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
|
||||
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
|
||||
virtual bool recognize(const RES &p_resource) const;
|
||||
};
|
||||
|
||||
#endif // CRYPTO_H
|
||||
@ -1,183 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* crypto_core.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "crypto_core.h"
|
||||
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/md5.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
// MD5
|
||||
CryptoCore::MD5Context::MD5Context() {
|
||||
ctx = memalloc(sizeof(mbedtls_md5_context));
|
||||
mbedtls_md5_init((mbedtls_md5_context *)ctx);
|
||||
}
|
||||
|
||||
CryptoCore::MD5Context::~MD5Context() {
|
||||
mbedtls_md5_free((mbedtls_md5_context *)ctx);
|
||||
memfree((mbedtls_md5_context *)ctx);
|
||||
}
|
||||
|
||||
Error CryptoCore::MD5Context::start() {
|
||||
int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::MD5Context::update(const uint8_t *p_src, size_t p_len) {
|
||||
int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
|
||||
int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
// SHA1
|
||||
CryptoCore::SHA1Context::SHA1Context() {
|
||||
ctx = memalloc(sizeof(mbedtls_sha1_context));
|
||||
mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
|
||||
}
|
||||
|
||||
CryptoCore::SHA1Context::~SHA1Context() {
|
||||
mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
|
||||
memfree((mbedtls_sha1_context *)ctx);
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA1Context::start() {
|
||||
int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
|
||||
int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
|
||||
int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
// SHA256
|
||||
CryptoCore::SHA256Context::SHA256Context() {
|
||||
ctx = memalloc(sizeof(mbedtls_sha256_context));
|
||||
mbedtls_sha256_init((mbedtls_sha256_context *)ctx);
|
||||
}
|
||||
|
||||
CryptoCore::SHA256Context::~SHA256Context() {
|
||||
mbedtls_sha256_free((mbedtls_sha256_context *)ctx);
|
||||
memfree((mbedtls_sha256_context *)ctx);
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA256Context::start() {
|
||||
int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA256Context::update(const uint8_t *p_src, size_t p_len) {
|
||||
int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
|
||||
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
// AES256
|
||||
CryptoCore::AESContext::AESContext() {
|
||||
ctx = memalloc(sizeof(mbedtls_aes_context));
|
||||
mbedtls_aes_init((mbedtls_aes_context *)ctx);
|
||||
}
|
||||
|
||||
CryptoCore::AESContext::~AESContext() {
|
||||
mbedtls_aes_free((mbedtls_aes_context *)ctx);
|
||||
memfree((mbedtls_aes_context *)ctx);
|
||||
}
|
||||
|
||||
Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) {
|
||||
int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) {
|
||||
int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
|
||||
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
|
||||
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
// CryptoCore
|
||||
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
|
||||
int b64len = p_src_len / 3 * 4 + 4 + 1;
|
||||
PoolVector<uint8_t> b64buff;
|
||||
b64buff.resize(b64len);
|
||||
PoolVector<uint8_t>::Write w64 = b64buff.write();
|
||||
size_t strlen = 0;
|
||||
int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len);
|
||||
w64[strlen] = 0;
|
||||
return ret ? String() : (const char *)&w64[0];
|
||||
}
|
||||
|
||||
Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
|
||||
int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
|
||||
int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) {
|
||||
int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) {
|
||||
int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
|
||||
Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) {
|
||||
int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0);
|
||||
return ret ? FAILED : OK;
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* crypto_core.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef CRYPTO_CORE_H
|
||||
#define CRYPTO_CORE_H
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
class CryptoCore {
|
||||
|
||||
public:
|
||||
class MD5Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
public:
|
||||
MD5Context();
|
||||
~MD5Context();
|
||||
|
||||
Error start();
|
||||
Error update(const uint8_t *p_src, size_t p_len);
|
||||
Error finish(unsigned char r_hash[16]);
|
||||
};
|
||||
|
||||
class SHA1Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
public:
|
||||
SHA1Context();
|
||||
~SHA1Context();
|
||||
|
||||
Error start();
|
||||
Error update(const uint8_t *p_src, size_t p_len);
|
||||
Error finish(unsigned char r_hash[20]);
|
||||
};
|
||||
|
||||
class SHA256Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
public:
|
||||
SHA256Context();
|
||||
~SHA256Context();
|
||||
|
||||
Error start();
|
||||
Error update(const uint8_t *p_src, size_t p_len);
|
||||
Error finish(unsigned char r_hash[32]);
|
||||
};
|
||||
|
||||
class AESContext {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
public:
|
||||
AESContext();
|
||||
~AESContext();
|
||||
|
||||
Error set_encode_key(const uint8_t *p_key, size_t p_bits);
|
||||
Error set_decode_key(const uint8_t *p_key, size_t p_bits);
|
||||
Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
|
||||
Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
|
||||
};
|
||||
|
||||
static String b64_encode_str(const uint8_t *p_src, int p_src_len);
|
||||
static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
|
||||
static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
|
||||
|
||||
static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]);
|
||||
static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]);
|
||||
static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]);
|
||||
};
|
||||
#endif // CRYPTO_CORE_H
|
||||
@ -1,138 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* hashing_context.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "hashing_context.h"
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
|
||||
Error HashingContext::start(HashType p_type) {
|
||||
ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
|
||||
_create_ctx(p_type);
|
||||
ERR_FAIL_COND_V(ctx == NULL, ERR_UNAVAILABLE);
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
return ((CryptoCore::MD5Context *)ctx)->start();
|
||||
case HASH_SHA1:
|
||||
return ((CryptoCore::SHA1Context *)ctx)->start();
|
||||
case HASH_SHA256:
|
||||
return ((CryptoCore::SHA256Context *)ctx)->start();
|
||||
}
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
Error HashingContext::update(PoolByteArray p_chunk) {
|
||||
ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
|
||||
size_t len = p_chunk.size();
|
||||
ERR_FAIL_COND_V(len == 0, FAILED);
|
||||
PoolByteArray::Read r = p_chunk.read();
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
|
||||
case HASH_SHA1:
|
||||
return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
|
||||
case HASH_SHA256:
|
||||
return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
|
||||
}
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
PoolByteArray HashingContext::finish() {
|
||||
ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
|
||||
PoolByteArray out;
|
||||
Error err = FAILED;
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
out.resize(16);
|
||||
err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
|
||||
break;
|
||||
case HASH_SHA1:
|
||||
out.resize(20);
|
||||
err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
out.resize(32);
|
||||
err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
|
||||
break;
|
||||
}
|
||||
_delete_ctx();
|
||||
ERR_FAIL_COND_V(err != OK, PoolByteArray());
|
||||
return out;
|
||||
}
|
||||
|
||||
void HashingContext::_create_ctx(HashType p_type) {
|
||||
type = p_type;
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
ctx = memnew(CryptoCore::MD5Context);
|
||||
break;
|
||||
case HASH_SHA1:
|
||||
ctx = memnew(CryptoCore::SHA1Context);
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
ctx = memnew(CryptoCore::SHA256Context);
|
||||
break;
|
||||
default:
|
||||
ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void HashingContext::_delete_ctx() {
|
||||
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
memdelete((CryptoCore::MD5Context *)ctx);
|
||||
break;
|
||||
case HASH_SHA1:
|
||||
memdelete((CryptoCore::SHA1Context *)ctx);
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
memdelete((CryptoCore::SHA256Context *)ctx);
|
||||
break;
|
||||
}
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
void HashingContext::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
|
||||
ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
|
||||
ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
|
||||
BIND_ENUM_CONSTANT(HASH_MD5);
|
||||
BIND_ENUM_CONSTANT(HASH_SHA1);
|
||||
BIND_ENUM_CONSTANT(HASH_SHA256);
|
||||
}
|
||||
|
||||
HashingContext::HashingContext() {
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
HashingContext::~HashingContext() {
|
||||
if (ctx != NULL)
|
||||
_delete_ctx();
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* hashing_context.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef HASHING_CONTEXT_H
|
||||
#define HASHING_CONTEXT_H
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
class HashingContext : public Reference {
|
||||
GDCLASS(HashingContext, Reference);
|
||||
|
||||
public:
|
||||
enum HashType {
|
||||
HASH_MD5,
|
||||
HASH_SHA1,
|
||||
HASH_SHA256
|
||||
};
|
||||
|
||||
private:
|
||||
void *ctx;
|
||||
HashType type;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _create_ctx(HashType p_type);
|
||||
void _delete_ctx();
|
||||
|
||||
public:
|
||||
Error start(HashType p_type);
|
||||
Error update(PoolByteArray p_chunk);
|
||||
PoolByteArray finish();
|
||||
|
||||
HashingContext();
|
||||
~HashingContext();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(HashingContext::HashType);
|
||||
|
||||
#endif // HASHING_CONTEXT_H
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,259 +26,219 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "dictionary.h"
|
||||
#include "safe_refcount.h"
|
||||
#include "variant.h"
|
||||
#include "io/json.h"
|
||||
|
||||
struct _DictionaryVariantHash {
|
||||
|
||||
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
|
||||
};
|
||||
|
||||
#include "core/ordered_hash_map.h"
|
||||
#include "core/safe_refcount.h"
|
||||
#include "core/variant.h"
|
||||
|
||||
struct DictionaryPrivate {
|
||||
|
||||
SafeRefCount refcount;
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map;
|
||||
HashMap<Variant,Variant,_DictionaryVariantHash> variant_map;
|
||||
bool shared;
|
||||
|
||||
};
|
||||
|
||||
void Dictionary::get_key_list(List<Variant> *p_keys) const {
|
||||
|
||||
if (_p->variant_map.empty())
|
||||
void Dictionary::get_key_list( List<Variant> *p_keys) const {
|
||||
|
||||
_p->variant_map.get_key_list(p_keys);
|
||||
}
|
||||
|
||||
void Dictionary::_copy_on_write() const {
|
||||
|
||||
//make a copy of what we have
|
||||
if (_p->shared)
|
||||
return;
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
p_keys->push_back(E.key());
|
||||
}
|
||||
DictionaryPrivate *p = memnew(DictionaryPrivate);
|
||||
p->shared=_p->shared;
|
||||
p->variant_map=_p->variant_map;
|
||||
p->refcount.init();
|
||||
_unref();
|
||||
_p=p;
|
||||
}
|
||||
|
||||
Variant Dictionary::get_key_at_index(int p_index) const {
|
||||
Variant& Dictionary::operator[](const Variant& p_key) {
|
||||
|
||||
int index = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
if (index == p_index) {
|
||||
return E.key();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return Variant();
|
||||
}
|
||||
|
||||
Variant Dictionary::get_value_at_index(int p_index) const {
|
||||
|
||||
int index = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
if (index == p_index) {
|
||||
return E.value();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return Variant();
|
||||
}
|
||||
|
||||
Variant &Dictionary::operator[](const Variant &p_key) {
|
||||
_copy_on_write();
|
||||
|
||||
return _p->variant_map[p_key];
|
||||
}
|
||||
|
||||
const Variant &Dictionary::operator[](const Variant &p_key) const {
|
||||
const Variant& Dictionary::operator[](const Variant& p_key) const {
|
||||
|
||||
return _p->variant_map[p_key];
|
||||
|
||||
}
|
||||
const Variant *Dictionary::getptr(const Variant &p_key) const {
|
||||
const Variant* Dictionary::getptr(const Variant& p_key) const {
|
||||
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
|
||||
return _p->variant_map.getptr(p_key);
|
||||
}
|
||||
Variant* Dictionary::getptr(const Variant& p_key) {
|
||||
|
||||
if (!E)
|
||||
return NULL;
|
||||
return &E.get();
|
||||
_copy_on_write();
|
||||
return _p->variant_map.getptr(p_key);
|
||||
}
|
||||
|
||||
Variant *Dictionary::getptr(const Variant &p_key) {
|
||||
Variant Dictionary::get_valid(const Variant& p_key) const {
|
||||
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
|
||||
|
||||
if (!E)
|
||||
return NULL;
|
||||
return &E.get();
|
||||
}
|
||||
|
||||
Variant Dictionary::get_valid(const Variant &p_key) const {
|
||||
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
|
||||
|
||||
if (!E)
|
||||
const Variant *v = getptr(p_key);
|
||||
if (!v)
|
||||
return Variant();
|
||||
return E.get();
|
||||
return *v;
|
||||
}
|
||||
|
||||
Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
|
||||
const Variant *result = getptr(p_key);
|
||||
if (!result) {
|
||||
return p_default;
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
int Dictionary::size() const {
|
||||
|
||||
return _p->variant_map.size();
|
||||
|
||||
}
|
||||
bool Dictionary::empty() const {
|
||||
|
||||
return !_p->variant_map.size();
|
||||
}
|
||||
|
||||
bool Dictionary::has(const Variant &p_key) const {
|
||||
bool Dictionary::has(const Variant& p_key) const {
|
||||
|
||||
return _p->variant_map.has(p_key);
|
||||
}
|
||||
|
||||
bool Dictionary::has_all(const Array &p_keys) const {
|
||||
for (int i = 0; i < p_keys.size(); i++) {
|
||||
if (!has(p_keys[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
void Dictionary::erase(const Variant& p_key) {
|
||||
_copy_on_write();
|
||||
_p->variant_map.erase(p_key);
|
||||
}
|
||||
|
||||
bool Dictionary::erase(const Variant &p_key) {
|
||||
bool Dictionary::operator==(const Dictionary& p_dictionary) const {
|
||||
|
||||
return _p->variant_map.erase(p_key);
|
||||
return _p==p_dictionary._p;
|
||||
}
|
||||
|
||||
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
|
||||
|
||||
return _p == p_dictionary._p;
|
||||
}
|
||||
|
||||
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
|
||||
|
||||
return _p != p_dictionary._p;
|
||||
}
|
||||
|
||||
void Dictionary::_ref(const Dictionary &p_from) const {
|
||||
void Dictionary::_ref(const Dictionary& p_from) const {
|
||||
|
||||
//make a copy first (thread safe)
|
||||
if (!p_from._p->refcount.ref())
|
||||
return; // couldn't copy
|
||||
|
||||
//if this is the same, unreference the other one
|
||||
if (p_from._p == _p) {
|
||||
if (p_from._p==_p) {
|
||||
_p->refcount.unref();
|
||||
return;
|
||||
}
|
||||
if (_p)
|
||||
_unref();
|
||||
_p = p_from._p;
|
||||
_p=p_from._p;
|
||||
|
||||
}
|
||||
|
||||
void Dictionary::clear() {
|
||||
|
||||
_copy_on_write();
|
||||
_p->variant_map.clear();
|
||||
}
|
||||
|
||||
bool Dictionary::is_shared() const {
|
||||
|
||||
return _p->shared;
|
||||
}
|
||||
|
||||
|
||||
void Dictionary::_unref() const {
|
||||
|
||||
ERR_FAIL_COND(!_p);
|
||||
if (_p->refcount.unref()) {
|
||||
memdelete(_p);
|
||||
}
|
||||
_p = NULL;
|
||||
_p=NULL;
|
||||
|
||||
}
|
||||
uint32_t Dictionary::hash() const {
|
||||
|
||||
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
|
||||
uint32_t h=hash_djb2_one_32(Variant::DICTIONARY);
|
||||
|
||||
List<Variant> keys;
|
||||
get_key_list(&keys);
|
||||
|
||||
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
h = hash_djb2_one_32( E->get().hash(), h);
|
||||
h = hash_djb2_one_32( operator[](E->get()).hash(), h);
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
h = hash_djb2_one_32(E.key().hash(), h);
|
||||
h = hash_djb2_one_32(E.value().hash(), h);
|
||||
}
|
||||
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
Array Dictionary::keys() const {
|
||||
|
||||
Array varr;
|
||||
if (_p->variant_map.empty())
|
||||
return varr;
|
||||
|
||||
varr.resize(size());
|
||||
|
||||
int i = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
varr[i] = E.key();
|
||||
i++;
|
||||
Array karr;
|
||||
karr.resize(size());
|
||||
const Variant *K=NULL;
|
||||
int idx=0;
|
||||
while((K=next(K))) {
|
||||
karr[idx++]=(*K);
|
||||
}
|
||||
return karr;
|
||||
|
||||
return varr;
|
||||
}
|
||||
|
||||
Array Dictionary::values() const {
|
||||
const Variant* Dictionary::next(const Variant* p_key) const {
|
||||
|
||||
Array varr;
|
||||
if (_p->variant_map.empty())
|
||||
return varr;
|
||||
|
||||
varr.resize(size());
|
||||
|
||||
int i = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
varr[i] = E.get();
|
||||
i++;
|
||||
}
|
||||
|
||||
return varr;
|
||||
return _p->variant_map.next(p_key);
|
||||
}
|
||||
|
||||
const Variant *Dictionary::next(const Variant *p_key) const {
|
||||
|
||||
if (p_key == NULL) {
|
||||
// caller wants to get the first element
|
||||
if (_p->variant_map.front())
|
||||
return &_p->variant_map.front().key();
|
||||
return NULL;
|
||||
Error Dictionary::parse_json(const String& p_json) {
|
||||
|
||||
String errstr;
|
||||
int errline=0;
|
||||
if (p_json != ""){
|
||||
Error err = JSON::parse(p_json,*this,errstr,errline);
|
||||
if (err!=OK) {
|
||||
ERR_EXPLAIN("Error parsing JSON: "+errstr+" at line: "+itos(errline));
|
||||
ERR_FAIL_COND_V(err!=OK,err);
|
||||
}
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key);
|
||||
|
||||
if (E && E.next())
|
||||
return &E.next().key();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
|
||||
Dictionary n;
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
n[E.key()] = p_deep ? E.value().duplicate(true) : E.value();
|
||||
}
|
||||
|
||||
return n;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void Dictionary::operator=(const Dictionary &p_dictionary) {
|
||||
String Dictionary::to_json() const {
|
||||
|
||||
return JSON::print(*this);
|
||||
}
|
||||
|
||||
|
||||
void Dictionary::operator=(const Dictionary& p_dictionary) {
|
||||
|
||||
_ref(p_dictionary);
|
||||
}
|
||||
|
||||
const void *Dictionary::id() const {
|
||||
return _p->variant_map.id();
|
||||
}
|
||||
|
||||
Dictionary::Dictionary(const Dictionary &p_from) {
|
||||
_p = NULL;
|
||||
|
||||
Dictionary::Dictionary(const Dictionary& p_from) {
|
||||
_p=NULL;
|
||||
_ref(p_from);
|
||||
}
|
||||
|
||||
Dictionary::Dictionary() {
|
||||
|
||||
_p = memnew(DictionaryPrivate);
|
||||
Dictionary::Dictionary(bool p_shared) {
|
||||
|
||||
_p=memnew( DictionaryPrivate );
|
||||
_p->refcount.init();
|
||||
_p->shared=p_shared;
|
||||
|
||||
}
|
||||
Dictionary::~Dictionary() {
|
||||
|
||||
_unref();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,65 +26,62 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef DICTIONARY_H
|
||||
#define DICTIONARY_H
|
||||
|
||||
#include "core/array.h"
|
||||
#include "core/list.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#include "list.h"
|
||||
#include "array.h"
|
||||
#include "ustring.h"
|
||||
class Variant;
|
||||
|
||||
|
||||
struct DictionaryPrivate;
|
||||
|
||||
|
||||
class Dictionary {
|
||||
|
||||
mutable DictionaryPrivate *_p;
|
||||
|
||||
void _ref(const Dictionary &p_from) const;
|
||||
void _copy_on_write() const;
|
||||
void _ref(const Dictionary& p_from) const;
|
||||
void _unref() const;
|
||||
|
||||
public:
|
||||
void get_key_list(List<Variant> *p_keys) const;
|
||||
Variant get_key_at_index(int p_index) const;
|
||||
Variant get_value_at_index(int p_index) const;
|
||||
|
||||
Variant &operator[](const Variant &p_key);
|
||||
const Variant &operator[](const Variant &p_key) const;
|
||||
void get_key_list( List<Variant> *p_keys) const;
|
||||
|
||||
const Variant *getptr(const Variant &p_key) const;
|
||||
Variant *getptr(const Variant &p_key);
|
||||
Variant& operator[](const Variant& p_key);
|
||||
const Variant& operator[](const Variant& p_key) const;
|
||||
|
||||
Variant get_valid(const Variant &p_key) const;
|
||||
Variant get(const Variant &p_key, const Variant &p_default) const;
|
||||
const Variant* getptr(const Variant& p_key) const;
|
||||
Variant* getptr(const Variant& p_key);
|
||||
|
||||
Variant get_valid(const Variant& p_key) const;
|
||||
|
||||
int size() const;
|
||||
bool empty() const;
|
||||
void clear();
|
||||
|
||||
bool has(const Variant &p_key) const;
|
||||
bool has_all(const Array &p_keys) const;
|
||||
|
||||
bool erase(const Variant &p_key);
|
||||
Error parse_json(const String& p_json);
|
||||
String to_json() const;
|
||||
|
||||
bool operator==(const Dictionary &p_dictionary) const;
|
||||
bool operator!=(const Dictionary &p_dictionary) const;
|
||||
bool is_shared() const;
|
||||
|
||||
bool has(const Variant& p_key) const;
|
||||
void erase(const Variant& p_key);
|
||||
|
||||
bool operator==(const Dictionary& p_dictionary) const;
|
||||
|
||||
uint32_t hash() const;
|
||||
void operator=(const Dictionary &p_dictionary);
|
||||
void operator=(const Dictionary& p_dictionary);
|
||||
|
||||
const Variant *next(const Variant *p_key = NULL) const;
|
||||
const Variant* next(const Variant* p_key=NULL) const;
|
||||
|
||||
Array keys() const;
|
||||
Array values() const;
|
||||
|
||||
Dictionary duplicate(bool p_deep = false) const;
|
||||
|
||||
const void *id() const;
|
||||
|
||||
Dictionary(const Dictionary &p_from);
|
||||
Dictionary();
|
||||
Dictionary(const Dictionary& p_from);
|
||||
Dictionary(bool p_shared=false);
|
||||
~Dictionary();
|
||||
};
|
||||
|
||||
|
||||
32
core/dvector.cpp
Normal file
32
core/dvector.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*************************************************************************/
|
||||
/* dvector.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "dvector.h"
|
||||
|
||||
Mutex* dvector_lock=NULL;
|
||||
|
||||
429
core/dvector.h
Normal file
429
core/dvector.h
Normal file
@ -0,0 +1,429 @@
|
||||
/*************************************************************************/
|
||||
/* dvector.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef DVECTOR_H
|
||||
#define DVECTOR_H
|
||||
|
||||
#include "os/memory.h"
|
||||
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
extern Mutex* dvector_lock;
|
||||
|
||||
template<class T>
|
||||
class DVector {
|
||||
|
||||
mutable MID mem;
|
||||
|
||||
|
||||
void copy_on_write() {
|
||||
|
||||
if (!mem.is_valid())
|
||||
return;
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
MID_Lock lock( mem );
|
||||
|
||||
|
||||
if ( *(int*)lock.data() == 1 ) {
|
||||
// one reference, means no refcount changes
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
MID new_mem= dynalloc( mem.get_size() );
|
||||
|
||||
if (!new_mem.is_valid()) {
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
|
||||
}
|
||||
|
||||
MID_Lock dst_lock( new_mem );
|
||||
|
||||
int *rc = (int*)dst_lock.data();
|
||||
|
||||
*rc=1;
|
||||
|
||||
T * dst = (T*)(rc + 1 );
|
||||
|
||||
T * src =(T*) ((int*)lock.data() + 1 );
|
||||
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
memnew_placement( &dst[i], T(src[i]) );
|
||||
}
|
||||
|
||||
(*(int*)lock.data())--;
|
||||
|
||||
// unlock all
|
||||
dst_lock=MID_Lock();
|
||||
lock=MID_Lock();
|
||||
|
||||
mem=new_mem;
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
}
|
||||
|
||||
void reference( const DVector& p_dvector ) {
|
||||
|
||||
unreference();
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
if (!p_dvector.mem.is_valid()) {
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
MID_Lock lock(p_dvector.mem);
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)++;
|
||||
|
||||
lock = MID_Lock();
|
||||
mem=p_dvector.mem;
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void unreference() {
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
if (!mem.is_valid()) {
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)--;
|
||||
|
||||
if (*rc==0) {
|
||||
// no one else using it, destruct
|
||||
|
||||
T * t= (T*)(rc+1);
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
lock = MID_Lock();
|
||||
|
||||
mem = MID ();
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class Read {
|
||||
friend class DVector;
|
||||
MID_Lock lock;
|
||||
const T * mem;
|
||||
public:
|
||||
|
||||
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
|
||||
_FORCE_INLINE_ const T *ptr() const { return mem; }
|
||||
|
||||
Read() { mem=NULL; }
|
||||
};
|
||||
|
||||
class Write {
|
||||
friend class DVector;
|
||||
MID_Lock lock;
|
||||
T * mem;
|
||||
public:
|
||||
|
||||
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
|
||||
_FORCE_INLINE_ T *ptr() { return mem; }
|
||||
|
||||
Write() { mem=NULL; }
|
||||
};
|
||||
|
||||
|
||||
Read read() const {
|
||||
|
||||
Read r;
|
||||
if (mem.is_valid()) {
|
||||
r.lock = MID_Lock( mem );
|
||||
r.mem = (const T*)((int*)r.lock.data()+1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
Write write() {
|
||||
|
||||
Write w;
|
||||
if (mem.is_valid()) {
|
||||
copy_on_write();
|
||||
w.lock = MID_Lock( mem );
|
||||
w.mem = (T*)((int*)w.lock.data()+1);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
template<class MC>
|
||||
void fill_with(const MC& p_mc) {
|
||||
|
||||
|
||||
int c=p_mc.size();
|
||||
resize(c);
|
||||
Write w=write();
|
||||
int idx=0;
|
||||
for(const typename MC::Element *E=p_mc.front();E;E=E->next()) {
|
||||
|
||||
w[idx++]=E->get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove(int p_index) {
|
||||
|
||||
int s = size();
|
||||
ERR_FAIL_INDEX(p_index, s);
|
||||
Write w = write();
|
||||
for (int i=p_index; i<s-1; i++) {
|
||||
|
||||
w[i]=w[i+1];
|
||||
};
|
||||
w = Write();
|
||||
resize(s-1);
|
||||
}
|
||||
|
||||
inline int size() const;
|
||||
T get(int p_index) const;
|
||||
void set(int p_index, const T& p_val);
|
||||
void push_back(const T& p_val);
|
||||
void append(const T& p_val) { push_back(p_val); }
|
||||
void append_array(const DVector<T>& p_arr) {
|
||||
int ds = p_arr.size();
|
||||
if (ds==0)
|
||||
return;
|
||||
int bs = size();
|
||||
resize( bs + ds);
|
||||
Write w = write();
|
||||
Read r = p_arr.read();
|
||||
for(int i=0;i<ds;i++)
|
||||
w[bs+i]=r[i];
|
||||
}
|
||||
|
||||
|
||||
Error insert(int p_pos,const T& p_val) {
|
||||
|
||||
int s=size();
|
||||
ERR_FAIL_INDEX_V(p_pos,s+1,ERR_INVALID_PARAMETER);
|
||||
resize(s+1);
|
||||
{
|
||||
Write w = write();
|
||||
for (int i=s;i>p_pos;i--)
|
||||
w[i]=w[i-1];
|
||||
w[p_pos]=p_val;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
bool is_locked() const { return mem.is_locked(); }
|
||||
|
||||
inline const T operator[](int p_index) const;
|
||||
|
||||
Error resize(int p_size);
|
||||
|
||||
|
||||
void operator=(const DVector& p_dvector) { reference(p_dvector); }
|
||||
DVector() {}
|
||||
DVector(const DVector& p_dvector) { reference(p_dvector); }
|
||||
~DVector() { unreference(); }
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
int DVector<T>::size() const {
|
||||
|
||||
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T) ) : 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T DVector<T>::get(int p_index) const {
|
||||
|
||||
return operator[](p_index);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DVector<T>::set(int p_index, const T& p_val) {
|
||||
|
||||
if (p_index<0 || p_index>=size()) {
|
||||
ERR_FAIL_COND(p_index<0 || p_index>=size());
|
||||
}
|
||||
|
||||
Write w = write();
|
||||
w[p_index]=p_val;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DVector<T>::push_back(const T& p_val) {
|
||||
|
||||
resize( size() + 1 );
|
||||
set( size() -1, p_val );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T DVector<T>::operator[](int p_index) const {
|
||||
|
||||
if (p_index<0 || p_index>=size()) {
|
||||
T& aux=*((T*)0); //nullreturn
|
||||
ERR_FAIL_COND_V(p_index<0 || p_index>=size(),aux);
|
||||
}
|
||||
|
||||
Read r = read();
|
||||
|
||||
return r[p_index];
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Error DVector<T>::resize(int p_size) {
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
bool same = p_size==size();
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
|
||||
|
||||
if (same)
|
||||
return OK;
|
||||
|
||||
if (p_size == 0 ) {
|
||||
|
||||
unreference();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
copy_on_write(); // make it unique
|
||||
|
||||
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
|
||||
|
||||
if (p_size > size() ) {
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
MID_Lock lock;
|
||||
|
||||
if (oldsize==0) {
|
||||
|
||||
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
|
||||
lock=MID_Lock(mem);
|
||||
int *rc = ((int*)lock.data());
|
||||
*rc=1;
|
||||
|
||||
} else {
|
||||
|
||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
|
||||
}
|
||||
|
||||
lock=MID_Lock(mem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
T *t = (T*)((int*)lock.data() + 1);
|
||||
|
||||
for (int i=oldsize;i<p_size;i++) {
|
||||
|
||||
memnew_placement(&t[i], T );
|
||||
}
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
} else {
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
|
||||
T *t = (T*)((int*)lock.data() + 1);
|
||||
|
||||
for (int i=p_size;i<oldsize;i++) {
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
|
||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
235
core/engine.cpp
235
core/engine.cpp
@ -1,235 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* engine.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
#include "core/authors.gen.h"
|
||||
#include "core/donors.gen.h"
|
||||
#include "core/license.gen.h"
|
||||
#include "core/version.h"
|
||||
#include "core/version_hash.gen.h"
|
||||
|
||||
void Engine::set_iterations_per_second(int p_ips) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
|
||||
ips = p_ips;
|
||||
}
|
||||
int Engine::get_iterations_per_second() const {
|
||||
|
||||
return ips;
|
||||
}
|
||||
|
||||
void Engine::set_physics_jitter_fix(float p_threshold) {
|
||||
if (p_threshold < 0)
|
||||
p_threshold = 0;
|
||||
physics_jitter_fix = p_threshold;
|
||||
}
|
||||
|
||||
float Engine::get_physics_jitter_fix() const {
|
||||
return physics_jitter_fix;
|
||||
}
|
||||
|
||||
void Engine::set_target_fps(int p_fps) {
|
||||
_target_fps = p_fps > 0 ? p_fps : 0;
|
||||
}
|
||||
|
||||
float Engine::get_target_fps() const {
|
||||
return _target_fps;
|
||||
}
|
||||
|
||||
uint64_t Engine::get_frames_drawn() {
|
||||
|
||||
return frames_drawn;
|
||||
}
|
||||
|
||||
void Engine::set_frame_delay(uint32_t p_msec) {
|
||||
|
||||
_frame_delay = p_msec;
|
||||
}
|
||||
|
||||
uint32_t Engine::get_frame_delay() const {
|
||||
|
||||
return _frame_delay;
|
||||
}
|
||||
|
||||
void Engine::set_time_scale(float p_scale) {
|
||||
|
||||
_time_scale = p_scale;
|
||||
}
|
||||
|
||||
float Engine::get_time_scale() const {
|
||||
|
||||
return _time_scale;
|
||||
}
|
||||
|
||||
Dictionary Engine::get_version_info() const {
|
||||
|
||||
Dictionary dict;
|
||||
dict["major"] = VERSION_MAJOR;
|
||||
dict["minor"] = VERSION_MINOR;
|
||||
dict["patch"] = VERSION_PATCH;
|
||||
dict["hex"] = VERSION_HEX;
|
||||
dict["status"] = VERSION_STATUS;
|
||||
dict["build"] = VERSION_BUILD;
|
||||
dict["year"] = VERSION_YEAR;
|
||||
|
||||
String hash = VERSION_HASH;
|
||||
dict["hash"] = hash.length() == 0 ? String("unknown") : hash;
|
||||
|
||||
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
|
||||
if ((int)dict["patch"] != 0)
|
||||
stringver += "." + String(dict["patch"]);
|
||||
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
|
||||
dict["string"] = stringver;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
static Array array_from_info(const char *const *info_list) {
|
||||
Array arr;
|
||||
for (int i = 0; info_list[i] != NULL; i++) {
|
||||
arr.push_back(info_list[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
static Array array_from_info_count(const char *const *info_list, int info_count) {
|
||||
Array arr;
|
||||
for (int i = 0; i < info_count; i++) {
|
||||
arr.push_back(info_list[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
Dictionary Engine::get_author_info() const {
|
||||
Dictionary dict;
|
||||
|
||||
dict["lead_developers"] = array_from_info(AUTHORS_LEAD_DEVELOPERS);
|
||||
dict["project_managers"] = array_from_info(AUTHORS_PROJECT_MANAGERS);
|
||||
dict["founders"] = array_from_info(AUTHORS_FOUNDERS);
|
||||
dict["developers"] = array_from_info(AUTHORS_DEVELOPERS);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
Array Engine::get_copyright_info() const {
|
||||
Array components;
|
||||
for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) {
|
||||
const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index];
|
||||
Dictionary component_dict;
|
||||
component_dict["name"] = cp_info.name;
|
||||
Array parts;
|
||||
for (int i = 0; i < cp_info.part_count; i++) {
|
||||
const ComponentCopyrightPart &cp_part = cp_info.parts[i];
|
||||
Dictionary part_dict;
|
||||
part_dict["files"] = array_from_info_count(cp_part.files, cp_part.file_count);
|
||||
part_dict["copyright"] = array_from_info_count(cp_part.copyright_statements, cp_part.copyright_count);
|
||||
part_dict["license"] = cp_part.license;
|
||||
parts.push_back(part_dict);
|
||||
}
|
||||
component_dict["parts"] = parts;
|
||||
|
||||
components.push_back(component_dict);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
Dictionary Engine::get_donor_info() const {
|
||||
Dictionary donors;
|
||||
donors["platinum_sponsors"] = array_from_info(DONORS_SPONSOR_PLAT);
|
||||
donors["gold_sponsors"] = array_from_info(DONORS_SPONSOR_GOLD);
|
||||
donors["mini_sponsors"] = array_from_info(DONORS_SPONSOR_MINI);
|
||||
donors["gold_donors"] = array_from_info(DONORS_GOLD);
|
||||
donors["silver_donors"] = array_from_info(DONORS_SILVER);
|
||||
donors["bronze_donors"] = array_from_info(DONORS_BRONZE);
|
||||
return donors;
|
||||
}
|
||||
|
||||
Dictionary Engine::get_license_info() const {
|
||||
Dictionary licenses;
|
||||
for (int i = 0; i < LICENSE_COUNT; i++) {
|
||||
licenses[LICENSE_NAMES[i]] = LICENSE_BODIES[i];
|
||||
}
|
||||
return licenses;
|
||||
}
|
||||
|
||||
String Engine::get_license_text() const {
|
||||
return String(GODOT_LICENSE_TEXT);
|
||||
}
|
||||
|
||||
void Engine::add_singleton(const Singleton &p_singleton) {
|
||||
|
||||
singletons.push_back(p_singleton);
|
||||
singleton_ptrs[p_singleton.name] = p_singleton.ptr;
|
||||
}
|
||||
|
||||
Object *Engine::get_singleton_object(const String &p_name) const {
|
||||
|
||||
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
|
||||
ERR_FAIL_COND_V_MSG(!E, NULL, "Failed to retrieve non-existent singleton '" + p_name + "'.");
|
||||
return E->get();
|
||||
};
|
||||
|
||||
bool Engine::has_singleton(const String &p_name) const {
|
||||
|
||||
return singleton_ptrs.has(p_name);
|
||||
};
|
||||
|
||||
void Engine::get_singletons(List<Singleton> *p_singletons) {
|
||||
|
||||
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next())
|
||||
p_singletons->push_back(E->get());
|
||||
}
|
||||
|
||||
Engine *Engine::singleton = NULL;
|
||||
|
||||
Engine *Engine::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
Engine::Engine() {
|
||||
|
||||
singleton = this;
|
||||
frames_drawn = 0;
|
||||
ips = 60;
|
||||
physics_jitter_fix = 0.5;
|
||||
_physics_interpolation_fraction = 0.0f;
|
||||
_frame_delay = 0;
|
||||
_fps = 1;
|
||||
_target_fps = 0;
|
||||
_time_scale = 1.0;
|
||||
_pixel_snap = false;
|
||||
_physics_frames = 0;
|
||||
_idle_frames = 0;
|
||||
_in_physics = false;
|
||||
_frame_ticks = 0;
|
||||
_frame_step = 0;
|
||||
editor_hint = false;
|
||||
}
|
||||
133
core/engine.h
133
core/engine.h
@ -1,133 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* engine.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include "core/list.h"
|
||||
#include "core/os/main_loop.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/vector.h"
|
||||
|
||||
class Engine {
|
||||
|
||||
public:
|
||||
struct Singleton {
|
||||
StringName name;
|
||||
Object *ptr;
|
||||
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) :
|
||||
name(p_name),
|
||||
ptr(p_ptr) {
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
friend class Main;
|
||||
|
||||
uint64_t frames_drawn;
|
||||
uint32_t _frame_delay;
|
||||
uint64_t _frame_ticks;
|
||||
float _frame_step;
|
||||
|
||||
int ips;
|
||||
float physics_jitter_fix;
|
||||
float _fps;
|
||||
int _target_fps;
|
||||
float _time_scale;
|
||||
bool _pixel_snap;
|
||||
uint64_t _physics_frames;
|
||||
float _physics_interpolation_fraction;
|
||||
|
||||
uint64_t _idle_frames;
|
||||
bool _in_physics;
|
||||
|
||||
List<Singleton> singletons;
|
||||
Map<StringName, Object *> singleton_ptrs;
|
||||
|
||||
bool editor_hint;
|
||||
|
||||
static Engine *singleton;
|
||||
|
||||
public:
|
||||
static Engine *get_singleton();
|
||||
|
||||
virtual void set_iterations_per_second(int p_ips);
|
||||
virtual int get_iterations_per_second() const;
|
||||
|
||||
void set_physics_jitter_fix(float p_threshold);
|
||||
float get_physics_jitter_fix() const;
|
||||
|
||||
virtual void set_target_fps(int p_fps);
|
||||
virtual float get_target_fps() const;
|
||||
|
||||
virtual float get_frames_per_second() const { return _fps; }
|
||||
|
||||
uint64_t get_frames_drawn();
|
||||
|
||||
uint64_t get_physics_frames() const { return _physics_frames; }
|
||||
uint64_t get_idle_frames() const { return _idle_frames; }
|
||||
bool is_in_physics_frame() const { return _in_physics; }
|
||||
uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
|
||||
float get_idle_frame_step() const { return _frame_step; }
|
||||
float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
|
||||
|
||||
void set_time_scale(float p_scale);
|
||||
float get_time_scale() const;
|
||||
|
||||
void set_frame_delay(uint32_t p_msec);
|
||||
uint32_t get_frame_delay() const;
|
||||
|
||||
void add_singleton(const Singleton &p_singleton);
|
||||
void get_singletons(List<Singleton> *p_singletons);
|
||||
bool has_singleton(const String &p_name) const;
|
||||
Object *get_singleton_object(const String &p_name) const;
|
||||
|
||||
_FORCE_INLINE_ bool get_use_pixel_snap() const { return _pixel_snap; }
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; }
|
||||
_FORCE_INLINE_ bool is_editor_hint() const { return editor_hint; }
|
||||
#else
|
||||
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) {}
|
||||
_FORCE_INLINE_ bool is_editor_hint() const { return false; }
|
||||
#endif
|
||||
|
||||
Dictionary get_version_info() const;
|
||||
Dictionary get_author_info() const;
|
||||
Array get_copyright_info() const;
|
||||
Dictionary get_donor_info() const;
|
||||
Dictionary get_license_info() const;
|
||||
String get_license_text() const;
|
||||
|
||||
Engine();
|
||||
virtual ~Engine() {}
|
||||
};
|
||||
|
||||
#endif // ENGINE_H
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,7 +26,6 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef ERROR_LIST_H
|
||||
#define ERROR_LIST_H
|
||||
|
||||
@ -39,10 +37,10 @@
|
||||
*/
|
||||
|
||||
enum Error {
|
||||
OK, // (0)
|
||||
OK,
|
||||
FAILED, ///< Generic fail error
|
||||
ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable
|
||||
ERR_UNCONFIGURED, ///< The object being used hasn't been properly set up yet
|
||||
ERR_UNCONFIGURED, ///< The object being used hasnt been properly set up yet
|
||||
ERR_UNAUTHORIZED, ///< Missing credentials for requested resource
|
||||
ERR_PARAMETER_RANGE_ERROR, ///< Parameter given out of range (5)
|
||||
ERR_OUT_OF_MEMORY, ///< Out of memory
|
||||
@ -59,35 +57,40 @@ enum Error {
|
||||
ERR_FILE_MISSING_DEPENDENCIES,
|
||||
ERR_FILE_EOF,
|
||||
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
|
||||
ERR_CANT_CREATE, // (20)
|
||||
ERR_QUERY_FAILED,
|
||||
ERR_CANT_CREATE,
|
||||
ERROR_QUERY_FAILED, // (20)
|
||||
ERR_ALREADY_IN_USE,
|
||||
ERR_LOCKED, ///< resource is locked
|
||||
ERR_TIMEOUT,
|
||||
ERR_CANT_CONNECT, // (25)
|
||||
ERR_CANT_RESOLVE,
|
||||
ERR_CANT_CONNECT,
|
||||
ERR_CANT_RESOLVE, // (25)
|
||||
ERR_CONNECTION_ERROR,
|
||||
ERR_CANT_ACQUIRE_RESOURCE,
|
||||
ERR_CANT_AQUIRE_RESOURCE,
|
||||
ERR_CANT_FORK,
|
||||
ERR_INVALID_DATA, ///< Data passed is invalid (30)
|
||||
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
|
||||
ERR_INVALID_DATA, ///< Data passed is invalid
|
||||
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid (30)
|
||||
ERR_ALREADY_EXISTS, ///< When adding, item already exists
|
||||
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, if item does not exist
|
||||
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist
|
||||
ERR_DATABASE_CANT_READ, ///< database is full
|
||||
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
|
||||
ERR_COMPILATION_FAILED,
|
||||
ERR_DATABASE_CANT_WRITE, ///< database is full
|
||||
ERR_COMPILATION_FAILED, // (35)
|
||||
ERR_METHOD_NOT_FOUND,
|
||||
ERR_LINK_FAILED,
|
||||
ERR_SCRIPT_FAILED,
|
||||
ERR_CYCLIC_LINK, // (40)
|
||||
ERR_INVALID_DECLARATION,
|
||||
ERR_CYCLIC_LINK,
|
||||
ERR_INVALID_DECLARATION, // (40)
|
||||
ERR_DUPLICATE_SYMBOL,
|
||||
ERR_PARSE_ERROR,
|
||||
ERR_BUSY,
|
||||
ERR_SKIP, // (45)
|
||||
ERR_HELP, ///< user requested help!!
|
||||
ERR_SKIP,
|
||||
ERR_HELP, ///< user requested help!! (45)
|
||||
ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
|
||||
ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
|
||||
ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though
|
||||
ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,20 +26,29 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "error_macros.h"
|
||||
|
||||
#include "core/io/logger.h"
|
||||
#include "core/ustring.h"
|
||||
#include "os/os.h"
|
||||
|
||||
static ErrorHandlerList *error_handler_list = NULL;
|
||||
|
||||
bool _err_error_exists=false;
|
||||
|
||||
static ErrorHandlerList *error_handler_list=NULL;
|
||||
|
||||
void _err_set_last_error(const char* p_err) {
|
||||
|
||||
OS::get_singleton()->set_last_error(p_err);
|
||||
}
|
||||
|
||||
void _err_clear_last_error() {
|
||||
|
||||
OS::get_singleton()->clear_last_error();
|
||||
}
|
||||
|
||||
void add_error_handler(ErrorHandlerList *p_handler) {
|
||||
|
||||
_global_lock();
|
||||
p_handler->next = error_handler_list;
|
||||
error_handler_list = p_handler;
|
||||
p_handler->next=error_handler_list;
|
||||
error_handler_list=p_handler;
|
||||
_global_unlock();
|
||||
}
|
||||
|
||||
@ -51,65 +59,44 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
|
||||
ErrorHandlerList *prev = NULL;
|
||||
ErrorHandlerList *l = error_handler_list;
|
||||
|
||||
while (l) {
|
||||
while(l) {
|
||||
|
||||
if (l == p_handler) {
|
||||
if (l==p_handler) {
|
||||
|
||||
if (prev)
|
||||
prev->next = l->next;
|
||||
prev->next=l->next;
|
||||
else
|
||||
error_handler_list = l->next;
|
||||
error_handler_list=l->next;
|
||||
break;
|
||||
}
|
||||
prev = l;
|
||||
l = l->next;
|
||||
prev=l;
|
||||
l=l->next;
|
||||
|
||||
}
|
||||
|
||||
_global_unlock();
|
||||
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
|
||||
_err_print_error(p_function, p_file, p_line, p_error, "", p_type);
|
||||
}
|
||||
void _err_print_error(const char* p_function, const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type) {
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type) {
|
||||
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_type);
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) {
|
||||
|
||||
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
|
||||
OS::get_singleton()->print_error(p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",(OS::ErrorType)p_type);
|
||||
|
||||
_global_lock();
|
||||
ErrorHandlerList *l = error_handler_list;
|
||||
while (l) {
|
||||
while(l) {
|
||||
|
||||
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type);
|
||||
l = l->next;
|
||||
l->errfunc(l->userdata,p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",p_type);
|
||||
l=l->next;
|
||||
}
|
||||
|
||||
_global_unlock();
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type) {
|
||||
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_type);
|
||||
}
|
||||
if (_err_error_exists) {
|
||||
OS::get_singleton()->clear_last_error();
|
||||
_err_error_exists=false;
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type) {
|
||||
_err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_type);
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type) {
|
||||
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_type);
|
||||
}
|
||||
|
||||
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) {
|
||||
|
||||
String fstr(fatal ? "FATAL: " : "");
|
||||
String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
|
||||
_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
|
||||
}
|
||||
|
||||
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal) {
|
||||
_err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), fatal);
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
@ -27,21 +26,20 @@
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef ERROR_MACROS_H
|
||||
#define ERROR_MACROS_H
|
||||
|
||||
#include "core/typedefs.h"
|
||||
|
||||
/**
|
||||
* Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability
|
||||
* inside the code. It is recommended to always return processable data, so in case of an error,
|
||||
* the engine can keep working well.
|
||||
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
|
||||
* inside the code. It is recommended to always return processable data, so in case of an error, the
|
||||
* engine can stay working well.
|
||||
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
|
||||
* to fail or crash.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pointer to the error macro printing function. Reassign to any function to have errors printed
|
||||
* Pointer to the error macro priting function. Reassign to any function to have errors printed
|
||||
*/
|
||||
|
||||
/** Function used by the error macros */
|
||||
@ -51,47 +49,51 @@
|
||||
enum ErrorHandlerType {
|
||||
ERR_HANDLER_ERROR,
|
||||
ERR_HANDLER_WARNING,
|
||||
ERR_HANDLER_SCRIPT,
|
||||
ERR_HANDLER_SHADER,
|
||||
ERR_HANDLER_SCRIPT
|
||||
};
|
||||
|
||||
class String;
|
||||
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
|
||||
typedef void (*ErrorHandlerFunc)(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
|
||||
void _err_set_last_error(const char* p_err);
|
||||
void _err_clear_last_error();
|
||||
|
||||
struct ErrorHandlerList {
|
||||
|
||||
ErrorHandlerFunc errfunc;
|
||||
void *userdata;
|
||||
|
||||
ErrorHandlerList *next;
|
||||
ErrorHandlerList*next;
|
||||
|
||||
ErrorHandlerList() {
|
||||
errfunc = 0;
|
||||
next = 0;
|
||||
userdata = 0;
|
||||
}
|
||||
ErrorHandlerList() { errfunc=0; next=0; userdata=0; }
|
||||
};
|
||||
|
||||
void add_error_handler(ErrorHandlerList *p_handler);
|
||||
void remove_error_handler(ErrorHandlerList *p_handler);
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
|
||||
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false);
|
||||
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
|
||||
void _err_print_error(const char* p_function,const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type=ERR_HANDLER_ERROR);
|
||||
|
||||
#ifndef _STR
|
||||
#define _STR(m_x) #m_x
|
||||
#define _MKSTR(m_x) _STR(m_x)
|
||||
#endif
|
||||
|
||||
#define _FNL __FILE__ ":"
|
||||
#define _FNL __FILE__":"
|
||||
|
||||
/** An index has failed if m_index<0 or m_index >=m_size, the function exits */
|
||||
/** An index has failed if m_index<0 or m_index >=m_size, the function exists */
|
||||
|
||||
extern bool _err_error_exists;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
/** Print a warning string.
|
||||
*/
|
||||
#define ERR_EXPLAINC(m_reason) {_err_set_last_error(m_reason); _err_error_exists=true;}
|
||||
#define ERR_EXPLAIN(m_string) {_err_set_last_error(String(m_string).utf8().get_data()); _err_error_exists=true;}
|
||||
|
||||
#else
|
||||
|
||||
#define ERR_EXPLAIN( m_text )
|
||||
#define ERR_EXPLAINC( m_text )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
//#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying
|
||||
@ -100,429 +102,126 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
|
||||
#define FUNCTION_STR __FUNCTION__
|
||||
#endif
|
||||
|
||||
// Don't use this directly; instead, use any of the CRASH_* macros
|
||||
#ifdef _MSC_VER
|
||||
#define GENERATE_TRAP \
|
||||
__debugbreak(); \
|
||||
/* Avoid warning about control paths */ \
|
||||
for (;;) { \
|
||||
}
|
||||
#else
|
||||
#define GENERATE_TRAP __builtin_trap();
|
||||
#endif
|
||||
|
||||
// Used to strip debug messages in release mode
|
||||
#ifdef DEBUG_ENABLED
|
||||
#define DEBUG_STR(m_msg) m_msg
|
||||
#else
|
||||
#define DEBUG_STR(m_msg) ""
|
||||
#endif
|
||||
|
||||
// (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`, prints a generic
|
||||
* error message and returns from the function. This macro should be preferred to
|
||||
* `ERR_FAIL_COND` for bounds checking.
|
||||
*/
|
||||
#define ERR_FAIL_INDEX(m_index, m_size) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
|
||||
#define ERR_FAIL_INDEX(m_index,m_size) \
|
||||
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
|
||||
return; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
} else _err_error_exists=false; } while(0); \
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`, prints a custom
|
||||
* error message and returns from the function. This macro should be preferred to
|
||||
* `ERR_FAIL_COND_MSG` for bounds checking.
|
||||
/** An index has failed if m_index<0 or m_index >=m_size, the function exists.
|
||||
* This function returns an error value, if returning Error, please select the most
|
||||
* appropriate error condition from error_macros.h
|
||||
*/
|
||||
#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
|
||||
|
||||
#define ERR_FAIL_INDEX_V(m_index,m_size,m_retval) \
|
||||
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
|
||||
return m_retval; \
|
||||
} else _err_error_exists=false;} while (0);
|
||||
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the function will exit.
|
||||
*/
|
||||
|
||||
#define ERR_FAIL_NULL(m_param) \
|
||||
{ if ( !m_param ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
|
||||
return; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`,
|
||||
* prints a generic error message and returns the value specified in `m_retval`.
|
||||
* This macro should be preferred to `ERR_FAIL_COND_V` for bounds checking.
|
||||
*/
|
||||
#define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
|
||||
|
||||
#define ERR_FAIL_NULL_V(m_param,m_retval) \
|
||||
{ if ( !m_param ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
|
||||
return m_retval; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`,
|
||||
* prints a custom error message and returns the value specified in `m_retval`.
|
||||
* This macro should be preferred to `ERR_FAIL_COND_V_MSG` for bounds checking.
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the function will exit.
|
||||
*/
|
||||
#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
|
||||
/**
|
||||
* If `m_index` is greater than or equal to `m_size`,
|
||||
* prints a generic error message and returns the value specified in `m_retval`.
|
||||
* This macro should be preferred to `ERR_FAIL_COND_V` for unsigned bounds checking.
|
||||
*/
|
||||
#define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
|
||||
do { \
|
||||
if (unlikely((m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
|
||||
/**
|
||||
* If `m_index` is greater than or equal to `m_size`,
|
||||
* prints a custom error message and returns the value specified in `m_retval`.
|
||||
* This macro should be preferred to `ERR_FAIL_COND_V_MSG` for unsigned bounds checking.
|
||||
*/
|
||||
#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
|
||||
do { \
|
||||
if (unlikely((m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`,
|
||||
* crashes the engine immediately with a generic error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
* This macro should be preferred to `CRASH_COND` for bounds checking.
|
||||
*/
|
||||
#define CRASH_BAD_INDEX(m_index, m_size) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
|
||||
GENERATE_TRAP \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
|
||||
/**
|
||||
* If `m_index` is less than 0 or greater than or equal to `m_size`,
|
||||
* crashes the engine immediately with a custom error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
* This macro should be preferred to `CRASH_COND` for bounds checking.
|
||||
*/
|
||||
#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
|
||||
do { \
|
||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
|
||||
GENERATE_TRAP \
|
||||
} \
|
||||
} while (0); // (*)
|
||||
|
||||
/**
|
||||
* If `m_param` is `null`, prints a generic error message and returns from the function.
|
||||
*/
|
||||
#define ERR_FAIL_NULL(m_param) \
|
||||
{ \
|
||||
if (unlikely(!m_param)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_param` is `null`, prints a custom error message and returns from the function.
|
||||
*/
|
||||
#define ERR_FAIL_NULL_MSG(m_param, m_msg) \
|
||||
{ \
|
||||
if (unlikely(!m_param)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_param` is `null`, prints a generic error message and returns the value specified in `m_retval`.
|
||||
*/
|
||||
#define ERR_FAIL_NULL_V(m_param, m_retval) \
|
||||
{ \
|
||||
if (unlikely(!m_param)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
|
||||
return m_retval; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_param` is `null`, prints a custom error message and returns the value specified in `m_retval`.
|
||||
*/
|
||||
#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
|
||||
{ \
|
||||
if (unlikely(!m_param)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a generic error message and returns from the function.
|
||||
*/
|
||||
#define ERR_FAIL_COND(m_cond) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true."); \
|
||||
{ if ( m_cond ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true."); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a custom error message and returns from the function.
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the function will exit.
|
||||
* This function returns an error value, if returning Error, please select the most
|
||||
* appropriate error condition from error_macros.h
|
||||
*/
|
||||
#define ERR_FAIL_COND_MSG(m_cond, m_msg) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, crashes the engine immediately with a generic error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
*/
|
||||
#define CRASH_COND(m_cond) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
|
||||
GENERATE_TRAP \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, crashes the engine immediately with a custom error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
*/
|
||||
#define CRASH_COND_MSG(m_cond, m_msg) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
|
||||
GENERATE_TRAP \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a generic error message and returns the value specified in `m_retval`.
|
||||
*/
|
||||
#define ERR_FAIL_COND_V(m_cond, m_retval) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval)); \
|
||||
#define ERR_FAIL_COND_V(m_cond,m_retval) \
|
||||
{ if ( m_cond ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. returned: " _STR(m_retval)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
}
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a custom error message and returns the value specified in `m_retval`.
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the loop will skip to the next iteration.
|
||||
*/
|
||||
#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval), DEBUG_STR(m_msg)); \
|
||||
return m_retval; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
|
||||
*/
|
||||
#define ERR_CONTINUE(m_cond) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing."); \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
{ if ( m_cond ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Continuing..:"); \
|
||||
continue;\
|
||||
} else _err_error_exists=false;} \
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the loop will break
|
||||
*/
|
||||
#define ERR_CONTINUE_MSG(m_cond, m_msg) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", DEBUG_STR(m_msg)); \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a generic error message and breaks from the loop the macro is located in.
|
||||
*/
|
||||
#define ERR_BREAK(m_cond) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking."); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
{ if ( m_cond ) { \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Breaking..:"); \
|
||||
break;\
|
||||
} else _err_error_exists=false;} \
|
||||
|
||||
/**
|
||||
* If `m_cond` evaluates to `true`, prints a custom error message and breaks from the loop the macro is located in.
|
||||
/** Print an error string and return
|
||||
*/
|
||||
#define ERR_BREAK_MSG(m_cond, m_msg) \
|
||||
{ \
|
||||
if (unlikely(m_cond)) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", DEBUG_STR(m_msg)); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a generic error message and returns from the function.
|
||||
*/
|
||||
#define ERR_FAIL() \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed."); \
|
||||
return; \
|
||||
}
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed."); \
|
||||
_err_error_exists=false;\
|
||||
return;\
|
||||
} \
|
||||
|
||||
/**
|
||||
* Prints a custom error message and returns from the function.
|
||||
/** Print an error string and return with value
|
||||
*/
|
||||
#define ERR_FAIL_MSG(m_msg) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed.", DEBUG_STR(m_msg)); \
|
||||
return; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a generic error message and returns the value specified in `m_retval`.
|
||||
*/
|
||||
#define ERR_FAIL_V(m_retval) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval)); \
|
||||
return m_retval; \
|
||||
}
|
||||
#define ERR_FAIL_V(m_value) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: " __STR(m_value)); \
|
||||
_err_error_exists=false; \
|
||||
return m_value;\
|
||||
} \
|
||||
|
||||
/**
|
||||
* Prints a custom error message and returns the value specified in `m_retval`.
|
||||
/** Print an error string.
|
||||
*/
|
||||
#define ERR_FAIL_V_MSG(m_retval, m_msg) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval), DEBUG_STR(m_msg)); \
|
||||
return m_retval; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Crashes the engine immediately with a generic error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
*/
|
||||
#define CRASH_NOW() \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed."); \
|
||||
GENERATE_TRAP \
|
||||
}
|
||||
|
||||
/**
|
||||
* Crashes the engine immediately with a custom error message.
|
||||
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
|
||||
*/
|
||||
#define CRASH_NOW_MSG(m_msg) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed.", DEBUG_STR(m_msg)); \
|
||||
GENERATE_TRAP \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an error message without returning.
|
||||
*/
|
||||
#define ERR_PRINT(m_string) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
|
||||
}
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string); \
|
||||
_err_error_exists=false;\
|
||||
} \
|
||||
|
||||
/**
|
||||
* Prints an error message without returning.
|
||||
* FIXME: Remove this macro and replace all uses with `ERR_PRINT` as it's identical.
|
||||
*/
|
||||
#define ERR_PRINTS(m_string) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an error message without returning, but only do so once in the application lifecycle.
|
||||
* This can be used to avoid spamming the console with error messages.
|
||||
*/
|
||||
#define ERR_PRINT_ONCE(m_string) \
|
||||
{ \
|
||||
static bool first_print = true; \
|
||||
if (first_print) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
|
||||
first_print = false; \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \
|
||||
_err_error_exists=false;\
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a warning message without returning. To warn about deprecated usage,
|
||||
* use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
|
||||
/** Print a warning string.
|
||||
*/
|
||||
|
||||
#define WARN_PRINT(m_string) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a warning message without returning.
|
||||
* FIXME: Remove this macro and replace all uses with `WARN_PRINT` as it's identical.
|
||||
*/
|
||||
#define WARN_PRINTS(m_string) \
|
||||
{ \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a warning message without returning, but only do so once in the application lifecycle.
|
||||
* This can be used to avoid spamming the console with warning messages.
|
||||
*/
|
||||
#define WARN_PRINT_ONCE(m_string) \
|
||||
{ \
|
||||
static bool first_print = true; \
|
||||
if (first_print) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
|
||||
first_print = false; \
|
||||
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string,ERR_HANDLER_WARNING); \
|
||||
_err_error_exists=false;\
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a generic deprecation warning message without returning.
|
||||
* This should be preferred to `WARN_PRINT` for deprecation warnings.
|
||||
*/
|
||||
#define WARN_DEPRECATED \
|
||||
{ \
|
||||
static volatile bool warning_shown = false; \
|
||||
if (!warning_shown) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \
|
||||
warning_shown = true; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a custom deprecation warning message without returning.
|
||||
* This should be preferred to `WARN_PRINT` for deprecation warnings.
|
||||
*/
|
||||
#define WARN_DEPRECATED_MSG(m_msg) \
|
||||
{ \
|
||||
static volatile bool warning_shown = false; \
|
||||
if (!warning_shown) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \
|
||||
warning_shown = true; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
161
core/event_queue.cpp
Normal file
161
core/event_queue.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/*************************************************************************/
|
||||
/* event_queue.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "event_queue.h"
|
||||
|
||||
|
||||
Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_DECLARE) {
|
||||
|
||||
uint8_t room_needed=sizeof(Event);
|
||||
int args=0;
|
||||
if (p_arg5.get_type()!=Variant::NIL)
|
||||
args=5;
|
||||
else if (p_arg4.get_type()!=Variant::NIL)
|
||||
args=4;
|
||||
else if (p_arg3.get_type()!=Variant::NIL)
|
||||
args=3;
|
||||
else if (p_arg2.get_type()!=Variant::NIL)
|
||||
args=2;
|
||||
else if (p_arg1.get_type()!=Variant::NIL)
|
||||
args=1;
|
||||
else
|
||||
args=0;
|
||||
|
||||
room_needed+=sizeof(Variant)*args;
|
||||
|
||||
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
||||
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
|
||||
ev->args=args;
|
||||
ev->instance_ID=p_instance_ID;
|
||||
ev->method=p_method;
|
||||
|
||||
buffer_end+=sizeof(Event);
|
||||
|
||||
if (args>=1) {
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg1;
|
||||
}
|
||||
|
||||
if (args>=2) {
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg2;
|
||||
}
|
||||
|
||||
if (args>=3) {
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg3;
|
||||
|
||||
}
|
||||
|
||||
if (args>=4) {
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg4;
|
||||
}
|
||||
|
||||
if (args>=5) {
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg5;
|
||||
}
|
||||
|
||||
if (buffer_max_used>buffer_end);
|
||||
buffer_max_used=buffer_end;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void EventQueue::flush_events() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
Object *obj = ObjectDB::get_instance(event->instance_ID);
|
||||
|
||||
if (obj) {
|
||||
// events don't expect a return value
|
||||
obj->call( event->method,
|
||||
(event->args>=1) ? args[0] : Variant(),
|
||||
(event->args>=2) ? args[1] : Variant(),
|
||||
(event->args>=3) ? args[2] : Variant(),
|
||||
(event->args>=4) ? args[3] : Variant(),
|
||||
(event->args>=5) ? args[4] : Variant() );
|
||||
}
|
||||
|
||||
if (event->args>=1) args[0].~Variant();
|
||||
if (event->args>=2) args[1].~Variant();
|
||||
if (event->args>=3) args[2].~Variant();
|
||||
if (event->args>=4) args[3].~Variant();
|
||||
if (event->args>=5) args[4].~Variant();
|
||||
event->~Event();
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
buffer_end=0; // reset buffer
|
||||
}
|
||||
|
||||
EventQueue::EventQueue(uint32_t p_buffer_size) {
|
||||
|
||||
|
||||
buffer_end=0;
|
||||
buffer_max_used=0;
|
||||
buffer_size=p_buffer_size;
|
||||
event_buffer = memnew_arr( uint8_t, buffer_size );
|
||||
|
||||
}
|
||||
EventQueue::~EventQueue() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
for (int i=0;i<event->args;i++)
|
||||
args[i].~Variant();
|
||||
event->~Event();
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
memdelete_arr(event_buffer);
|
||||
event_buffer=NULL;
|
||||
}
|
||||
|
||||
66
core/event_queue.h
Normal file
66
core/event_queue.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*************************************************************************/
|
||||
/* event_queue.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef EVENT_QUEUE_H
|
||||
#define EVENT_QUEUE_H
|
||||
|
||||
#include "object.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class EventQueue {
|
||||
|
||||
enum {
|
||||
|
||||
DEFAULT_EVENT_QUEUE_SIZE_KB=256
|
||||
};
|
||||
|
||||
struct Event {
|
||||
|
||||
uint32_t instance_ID;
|
||||
StringName method;
|
||||
int args;
|
||||
};
|
||||
|
||||
|
||||
uint8_t *event_buffer;
|
||||
uint32_t buffer_end;
|
||||
uint32_t buffer_max_used;
|
||||
uint32_t buffer_size;
|
||||
public:
|
||||
|
||||
|
||||
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
|
||||
void flush_events();
|
||||
|
||||
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
|
||||
~EventQueue();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
28
core/fpstr.cpp
Normal file
28
core/fpstr.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*************************************************************************/
|
||||
/* fpstr.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user