├── .clang-format
├── .clang-tidy
├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.yml
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── android_builds.yml
│ ├── get_version.yml
│ ├── ios_builds.yml
│ ├── linux_builds.yml
│ ├── macos_builds.yml
│ ├── release_builds.yml
│ ├── runner.yml
│ ├── static_checks.yml
│ ├── web_builds.yml
│ └── windows_builds.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SCsub
├── clang_format.sh
├── config.py
├── doc
└── class.xsd
├── doc_classes
├── JavaScript.xml
└── JavaScriptModule.xml
├── docs
├── JavaScript.svg.licence
├── header-mobile.svg
└── header.svg
├── editor
├── editor_tools.cpp
├── editor_tools.h
└── workarounds
│ ├── ignore-methods.cpp
│ ├── missing-constructors.cpp
│ └── missing-enums.cpp
├── generate_builtin_api.py
├── icons
├── JavaScript.svg
└── JavaScriptModule.svg
├── javascript.cpp
├── javascript.h
├── javascript_binder.h
├── javascript_callable.h
├── javascript_gc_handler.h
├── javascript_instance.cpp
├── javascript_instance.h
├── misc
├── binding_script.js
├── generate
│ ├── bindings.py
│ ├── editor_tools.py
│ ├── generate_files.py
│ ├── templates.py
│ └── test_manager.py
├── template-contents
│ ├── default.js
│ └── empty.js
└── typescript
│ ├── decorators.ts
│ └── godot.d.ts
├── register_types.cpp
├── register_types.h
├── src
├── language
│ ├── README.md
│ ├── javascript_instance_binding_callbacks.cpp
│ ├── javascript_language.cpp
│ ├── javascript_language.h
│ ├── javascript_language_definitions.cpp
│ ├── javascript_templates.cpp
│ ├── javascript_todo_debugger.cpp
│ ├── javascript_todo_doctools.cpp
│ ├── javascript_todo_multithread.cpp
│ ├── javascript_todo_profiling.cpp
│ ├── javascript_todo_texteditor.cpp
│ └── templates
│ │ ├── javascript_template_manager.cpp
│ │ └── javascript_template_manager.h
└── tests
│ ├── UnitTest.js
│ └── test_manager.h
├── tests
└── test_javascript.h
└── thirdparty
└── quickjs
├── README.md
├── builtin_binding_generator.py
├── quickjs
├── VERSION.txt
├── cutils.c
├── cutils.h
├── libbf.c
├── libbf.h
├── libregexp-opcode.h
├── libregexp.c
├── libregexp.h
├── libunicode-table.h
├── libunicode.c
├── libunicode.h
├── list.h
├── quickjs-atom.h
├── quickjs-debugger.c
├── quickjs-debugger.h
├── quickjs-opcode.h
├── quickjs.c
└── quickjs.h
├── quickjs_binder.cpp
├── quickjs_binder.h
├── quickjs_builtin_binder.cpp
├── quickjs_builtin_binder.h
├── quickjs_callable.cpp
├── quickjs_callable.h
├── quickjs_debugger.cpp
├── quickjs_debugger.h
├── quickjs_worker.cpp
└── quickjs_worker.h
/.clang-format:
--------------------------------------------------------------------------------
1 | # Commented out parameters are those with the same value as base LLVM style.
2 | # We can uncomment them if we want to change their value, or enforce the
3 | # chosen value in case the base style changes (last sync: Clang 14.0).
4 | ---
5 | ### General config, applies to all languages ###
6 | BasedOnStyle: LLVM
7 | AccessModifierOffset: -4
8 | AlignAfterOpenBracket: DontAlign
9 | # AlignArrayOfStructures: None
10 | # AlignConsecutiveMacros: None
11 | # AlignConsecutiveAssignments: None
12 | # AlignConsecutiveBitFields: None
13 | # AlignConsecutiveDeclarations: None
14 | # AlignEscapedNewlines: Right
15 | AlignOperands: DontAlign
16 | AlignTrailingComments: false
17 | # AllowAllArgumentsOnNextLine: true
18 | AllowAllParametersOfDeclarationOnNextLine: false
19 | # AllowShortEnumsOnASingleLine: true
20 | # AllowShortBlocksOnASingleLine: Never
21 | # AllowShortCaseLabelsOnASingleLine: false
22 | # AllowShortFunctionsOnASingleLine: All
23 | # AllowShortLambdasOnASingleLine: All
24 | # AllowShortIfStatementsOnASingleLine: Never
25 | # AllowShortLoopsOnASingleLine: false
26 | # AlwaysBreakAfterDefinitionReturnType: None
27 | # AlwaysBreakAfterReturnType: None
28 | # AlwaysBreakBeforeMultilineStrings: false
29 | # AlwaysBreakTemplateDeclarations: MultiLine
30 | # AttributeMacros:
31 | # - __capability
32 | # BinPackArguments: true
33 | # BinPackParameters: true
34 | # BraceWrapping:
35 | # AfterCaseLabel: false
36 | # AfterClass: false
37 | # AfterControlStatement: Never
38 | # AfterEnum: false
39 | # AfterFunction: false
40 | # AfterNamespace: false
41 | # AfterObjCDeclaration: false
42 | # AfterStruct: false
43 | # AfterUnion: false
44 | # AfterExternBlock: false
45 | # BeforeCatch: false
46 | # BeforeElse: false
47 | # BeforeLambdaBody: false
48 | # BeforeWhile: false
49 | # IndentBraces: false
50 | # SplitEmptyFunction: true
51 | # SplitEmptyRecord: true
52 | # SplitEmptyNamespace: true
53 | # BreakBeforeBinaryOperators: None
54 | # BreakBeforeConceptDeclarations: true
55 | # BreakBeforeBraces: Attach
56 | # BreakBeforeInheritanceComma: false
57 | # BreakInheritanceList: BeforeColon
58 | # BreakBeforeTernaryOperators: true
59 | # BreakConstructorInitializersBeforeComma: false
60 | BreakConstructorInitializers: AfterColon
61 | # BreakStringLiterals: true
62 | ColumnLimit: 0
63 | # CommentPragmas: '^ IWYU pragma:'
64 | # QualifierAlignment: Leave
65 | # CompactNamespaces: false
66 | ConstructorInitializerIndentWidth: 8
67 | ContinuationIndentWidth: 8
68 | Cpp11BracedListStyle: false
69 | # DeriveLineEnding: true
70 | # DerivePointerAlignment: false
71 | # DisableFormat: false
72 | # EmptyLineAfterAccessModifier: Never
73 | # EmptyLineBeforeAccessModifier: LogicalBlock
74 | # ExperimentalAutoDetectBinPacking: false
75 | # PackConstructorInitializers: BinPack
76 | ConstructorInitializerAllOnOneLineOrOnePerLine: true
77 | # AllowAllConstructorInitializersOnNextLine: true
78 | # FixNamespaceComments: true
79 | # ForEachMacros:
80 | # - foreach
81 | # - Q_FOREACH
82 | # - BOOST_FOREACH
83 | # IfMacros:
84 | # - KJ_IF_MAYBE
85 | # IncludeBlocks: Preserve
86 | IncludeCategories:
87 | - Regex: '".*"'
88 | Priority: 1
89 | - Regex: '^<.*\.h>'
90 | Priority: 2
91 | - Regex: '^<.*'
92 | Priority: 3
93 | # IncludeIsMainRegex: '(Test)?$'
94 | # IncludeIsMainSourceRegex: ''
95 | # IndentAccessModifiers: false
96 | IndentCaseLabels: true
97 | # IndentCaseBlocks: false
98 | # IndentGotoLabels: true
99 | # IndentPPDirectives: None
100 | # IndentExternBlock: AfterExternBlock
101 | # IndentRequires: false
102 | IndentWidth: 4
103 | # IndentWrappedFunctionNames: false
104 | # InsertTrailingCommas: None
105 | # JavaScriptQuotes: Leave
106 | # JavaScriptWrapImports: true
107 | KeepEmptyLinesAtTheStartOfBlocks: false
108 | # LambdaBodyIndentation: Signature
109 | # MacroBlockBegin: ''
110 | # MacroBlockEnd: ''
111 | # MaxEmptyLinesToKeep: 1
112 | # NamespaceIndentation: None
113 | # PenaltyBreakAssignment: 2
114 | # PenaltyBreakBeforeFirstCallParameter: 19
115 | # PenaltyBreakComment: 300
116 | # PenaltyBreakFirstLessLess: 120
117 | # PenaltyBreakOpenParenthesis: 0
118 | # PenaltyBreakString: 1000
119 | # PenaltyBreakTemplateDeclaration: 10
120 | # PenaltyExcessCharacter: 1000000
121 | # PenaltyReturnTypeOnItsOwnLine: 60
122 | # PenaltyIndentedWhitespace: 0
123 | # PointerAlignment: Right
124 | # PPIndentWidth: -1
125 | # ReferenceAlignment: Pointer
126 | # ReflowComments: true
127 | # RemoveBracesLLVM: false
128 | # SeparateDefinitionBlocks: Leave
129 | # ShortNamespaceLines: 1
130 | # SortIncludes: CaseSensitive
131 | # SortJavaStaticImport: Before
132 | # SortUsingDeclarations: true
133 | # SpaceAfterCStyleCast: false
134 | # SpaceAfterLogicalNot: false
135 | # SpaceAfterTemplateKeyword: true
136 | # SpaceBeforeAssignmentOperators: true
137 | # SpaceBeforeCaseColon: false
138 | # SpaceBeforeCpp11BracedList: false
139 | # SpaceBeforeCtorInitializerColon: true
140 | # SpaceBeforeInheritanceColon: true
141 | # SpaceBeforeParens: ControlStatements
142 | # SpaceBeforeParensOptions:
143 | # AfterControlStatements: true
144 | # AfterForeachMacros: true
145 | # AfterFunctionDefinitionName: false
146 | # AfterFunctionDeclarationName: false
147 | # AfterIfMacros: true
148 | # AfterOverloadedOperator: false
149 | # BeforeNonEmptyParentheses: false
150 | # SpaceAroundPointerQualifiers: Default
151 | # SpaceBeforeRangeBasedForLoopColon: true
152 | # SpaceInEmptyBlock: false
153 | # SpaceInEmptyParentheses: false
154 | # SpacesBeforeTrailingComments: 1
155 | # SpacesInAngles: Never
156 | # SpacesInConditionalStatement: false
157 | # SpacesInContainerLiterals: true
158 | # SpacesInCStyleCastParentheses: false
159 | ## Godot TODO: We'll want to use a min of 1, but we need to see how to fix
160 | ## our comment capitalization at the same time.
161 | SpacesInLineCommentPrefix:
162 | Minimum: 0
163 | Maximum: -1
164 | # SpacesInParentheses: false
165 | # SpacesInSquareBrackets: false
166 | # SpaceBeforeSquareBrackets: false
167 | # BitFieldColonSpacing: Both
168 | # StatementAttributeLikeMacros:
169 | # - Q_EMIT
170 | # StatementMacros:
171 | # - Q_UNUSED
172 | # - QT_REQUIRE_VERSION
173 | TabWidth: 4
174 | # UseCRLF: false
175 | UseTab: Always
176 | # WhitespaceSensitiveMacros:
177 | # - STRINGIZE
178 | # - PP_STRINGIZE
179 | # - BOOST_PP_STRINGIZE
180 | # - NS_SWIFT_NAME
181 | # - CF_SWIFT_NAME
182 | ---
183 | ### C++ specific config ###
184 | Language: Cpp
185 | Standard: c++17
186 | ---
187 | ### ObjC specific config ###
188 | Language: ObjC
189 | # ObjCBinPackProtocolList: Auto
190 | ObjCBlockIndentWidth: 4
191 | # ObjCBreakBeforeNestedBlockParam: true
192 | # ObjCSpaceAfterProperty: false
193 | # ObjCSpaceBeforeProtocolList: true
194 | ---
195 | ### Java specific config ###
196 | Language: Java
197 | # BreakAfterJavaFieldAnnotations: false
198 | JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
199 | ...
200 |
--------------------------------------------------------------------------------
/.clang-tidy:
--------------------------------------------------------------------------------
1 | ---
2 | Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,cppcoreguidelines-pro-type-member-init,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements,readability-redundant-member-init'
3 | WarningsAsErrors: ''
4 | HeaderFilterRegex: ''
5 | AnalyzeTemporaryDtors: false
6 | FormatStyle: none
7 | CheckOptions:
8 | - key: cert-dcl16-c.NewSuffixes
9 | value: 'L;LL;LU;LLU'
10 | - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
11 | value: '0'
12 | - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
13 | value: '1'
14 | - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
15 | value: '1'
16 | - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays
17 | value: '1'
18 | - key: cppcoreguidelines-pro-type-member-init.UseAssignment
19 | value: '1'
20 | - key: google-readability-function-size.StatementThreshold
21 | value: '800'
22 | - key: google-readability-namespace-comments.ShortNamespaceLines
23 | value: '10'
24 | - key: google-readability-namespace-comments.SpacesBeforeComments
25 | value: '2'
26 | - key: modernize-loop-convert.MaxCopySize
27 | value: '16'
28 | - key: modernize-loop-convert.MinConfidence
29 | value: reasonable
30 | - key: modernize-loop-convert.NamingStyle
31 | value: CamelCase
32 | - key: modernize-pass-by-value.IncludeStyle
33 | value: llvm
34 | - key: modernize-replace-auto-ptr.IncludeStyle
35 | value: llvm
36 | - key: modernize-use-bool-literals.IgnoreMacros
37 | value: '0'
38 | - key: modernize-use-default-member-init.IgnoreMacros
39 | value: '0'
40 | - key: modernize-use-default-member-init.UseAssignment
41 | value: '1'
42 | - key: modernize-use-nullptr.NullMacros
43 | value: 'NULL'
44 | - key: readability-braces-around-statements.ShortStatementLines
45 | value: '0'
46 | ...
47 |
48 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug report
2 | description: Report a bug in GodotJS
3 | body:
4 |
5 | - type: markdown
6 | attributes:
7 | value: |
8 | When reporting bugs, please follow the guidelines in this template. This helps identify the problem precisely and thus enables contributors to fix it faster.
9 | - Write a descriptive issue title above.
10 | - 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.
11 | - Search [open](https://github.com/godotengine/godot/issues) and [closed](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
12 | - Verify that you are using a [supported Godot version](https://github.com/godotjs/javascript/releases). Please always check if your issue is reproducible in the latest version – it may already have been fixed!
13 |
14 | - type: input
15 | attributes:
16 | label: Version
17 | description: >
18 | Specify the Godot version, including the Git commit hash if using a development or non-official build. The exact Godot version (including the commit hash) can be copied by clicking the version shown in the editor (bottom bar) or in the project manager (top bar).
19 | placeholder: 4.1-v0.0.17-alpha-20231003
20 | validations:
21 | required: true
22 |
23 | - type: input
24 | attributes:
25 | label: System information
26 | description: |
27 | - Specify the OS version, and when relevant hardware information.
28 | - For issues that are likely OS-specific and/or graphics-related, please specify the CPU model and architecture.
29 | - For graphics-related issues, specify the GPU model, driver version, and the rendering backend (GLES2, GLES3, Vulkan).
30 | - **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information.
31 | - **Starting from Godot 4.1, you can copy this information to your clipboard by using *Help > Copy System Info* at the top of the editor window.**
32 | placeholder: Windows 10 - Godot v4.0.3.stable - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 970 (nvidia, 510.85.02) - Intel Core i7-10700KF CPU @ 3.80GHz (16 Threads)
33 | validations:
34 | required: true
35 |
36 | - type: textarea
37 | attributes:
38 | label: Issue description
39 | description: |
40 | Describe your issue briefly. What doesn't work, and how do you expect it to work instead?
41 | You can include images or videos with drag and drop, and format code blocks or logs with \`\`\`
tags, on separate lines before and after the text. (Use \`\`\`gdscript
to add GDScript syntax highlighting.)
42 | Please do not add code examples or error messages as screenshots, but as text, this helps searching for issues and testing the code. If you are reporting a bug in the editor interface, like the script editor, please provide both a screenshot *and* the text of the code to help with testing.
43 | validations:
44 | required: true
45 |
46 | - type: textarea
47 | attributes:
48 | label: Steps to reproduce
49 | description: |
50 | List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them.
51 | If you include a minimal reproduction project below, you can detail how to use it here.
52 | validations:
53 | required: true
54 |
55 | - type: textarea
56 | attributes:
57 | label: Minimal reproduction project (MRP)
58 | description: |
59 | - A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the `.godot` folder in the archive (but keep `project.godot`).
60 | - Having an MRP is very important for contributors to be able to reproduce the bug in the same way that you are experiencing it. When testing a potential fix for the issue, contributors will use the MRP to validate that the fix is working as intended.
61 | - If the reproduction steps are not project dependent (e.g. the bug is visible in a brand new project), you can write "N/A" in the field.
62 | - Drag and drop a ZIP archive to upload it (max 10 MB). **Do not select another field until the project is done uploading.**
63 | validations:
64 | required: true
65 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 |
4 |
5 | Make sure to follow the PR preparation steps in [CONTRIBUTING.md](https://github.com/godotjs/javascript/blob/master/CONTRIBUTING.md#preparing-your-pr) before submitting your PR:
6 |
7 | - [ ] format C++: from the root, run `bash ./misc/formatting/clang_format.sh`.
8 |
--------------------------------------------------------------------------------
/.github/workflows/android_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🤖 Android Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 | # Global Settings
10 | env:
11 | SCONSFLAGS: warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
12 |
13 | concurrency:
14 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-android
15 | cancel-in-progress: true
16 |
17 | jobs:
18 | android-template:
19 | runs-on: "ubuntu-20.04"
20 | name: Template (target=template_release)
21 |
22 | steps:
23 | - name: Checkout Godot
24 | uses: actions/checkout@v4
25 | with:
26 | repository: godotengine/godot
27 | ref: ${{ inputs.version }}
28 |
29 | - name: Checkout ECMAScript
30 | uses: actions/checkout@v4
31 | with:
32 | path: ${{github.workspace}}/modules/javascript/
33 |
34 | - name: Set up Java 11
35 | uses: actions/setup-java@v3
36 | with:
37 | distribution: temurin
38 | java-version: 11
39 |
40 | - name: Setup Godot build cache
41 | uses: ./.github/actions/godot-cache
42 | continue-on-error: true
43 |
44 | - name: Setup python and scons
45 | uses: ./.github/actions/godot-deps
46 |
47 | - name: Compilation (arm32)
48 | uses: ./.github/actions/godot-build
49 | with:
50 | sconsflags: ${{ env.SCONSFLAGS }} arch=arm32
51 | platform: android
52 | target: template_release
53 | tests: false
54 |
55 | - name: Compilation (arm64)
56 | uses: ./.github/actions/godot-build
57 | with:
58 | sconsflags: ${{ env.SCONSFLAGS }} arch=arm64
59 | platform: android
60 | target: template_release
61 | tests: false
62 |
63 | - name: Generate Godot templates
64 | run: |
65 | cd platform/android/java
66 | ./gradlew generateGodotTemplates
67 | cd ../../..
68 | ls -l bin/
69 |
70 | - name: Upload artifact
71 | uses: ./.github/actions/upload-artifact
72 |
--------------------------------------------------------------------------------
/.github/workflows/get_version.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🆚 Get godot version
3 |
4 | on:
5 | workflow_call:
6 | outputs:
7 | version:
8 | description: "Which version we should use based on target branch"
9 | value: ${{ jobs.version.outputs.version }}
10 |
11 | # We use a godot tag(rc version) as default version for master
12 | # because the api is changing often and this would lead to a lot of struggle
13 | env:
14 | MASTER_VERSION: 4.1
15 |
16 | jobs:
17 | version:
18 | name: Get godot version
19 | runs-on: ubuntu-latest
20 | outputs:
21 | version: ${{ steps.version.outputs.version }}
22 | steps:
23 | - name: 🏷 Get and set godot version
24 | id: version
25 | run: |
26 | VERSION="${{ github.event.pull_request.base.ref || github.event.release.target_commitish || github.ref_name }}"
27 | if [[ $VERSION == "master" ]]; then
28 | VERSION="$MASTER_VERSION"
29 | echo "We are overwrite master to latest rc version: $VERSION"
30 | fi
31 | echo "version=$VERSION" >> $GITHUB_OUTPUT
32 |
33 | - name: 🌳 Log Valid Version
34 | env:
35 | VERSION: ${{ steps.version.outputs.version }}
36 | run: echo "$VERSION"
37 |
--------------------------------------------------------------------------------
/.github/workflows/ios_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🍏 iOS Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 | # Global Settings
10 | env:
11 | SCONSFLAGS: warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
12 |
13 | concurrency:
14 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-ios
15 | cancel-in-progress: true
16 |
17 | jobs:
18 | ios-template:
19 | runs-on: "macos-latest"
20 | name: Template (target=template_release)
21 |
22 | steps:
23 | - name: Checkout Godot
24 | uses: actions/checkout@v4
25 | with:
26 | repository: godotengine/godot
27 | ref: ${{ inputs.version }}
28 |
29 | - name: Checkout ECMAScript
30 | uses: actions/checkout@v4
31 | with:
32 | path: ${{github.workspace}}/modules/javascript/
33 |
34 | - name: Setup Godot build cache
35 | uses: ./.github/actions/godot-cache
36 | continue-on-error: true
37 |
38 | - name: Setup python and scons
39 | uses: ./.github/actions/godot-deps
40 |
41 | - name: Compilation (arm64)
42 | uses: ./.github/actions/godot-build
43 | with:
44 | sconsflags: ${{ env.SCONSFLAGS }}
45 | platform: ios
46 | target: template_release
47 | tests: false
48 |
49 | - name: Upload artifact
50 | uses: ./.github/actions/upload-artifact
51 |
--------------------------------------------------------------------------------
/.github/workflows/linux_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🐧 Linux Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 |
10 | # Global Settings
11 | env:
12 | # We need to remove 'werror=yes' because of thirdparty/quickjs/quickjs/quickjs.h:975
13 | # Look at https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type for more information
14 | SCONSFLAGS: warnings=extra module_text_server_fb_enabled=yes
15 | DOTNET_NOLOGO: true
16 | DOTNET_CLI_TELEMETRY_OPTOUT: true
17 |
18 | concurrency:
19 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-linux
20 | cancel-in-progress: true
21 |
22 | jobs:
23 | build-linux:
24 | runs-on: "ubuntu-20.04"
25 | name: ${{ matrix.name }}
26 | strategy:
27 | fail-fast: false
28 | matrix:
29 | include:
30 | - name: Editor w/ Mono (target=editor)
31 | cache-name: linux-editor-mono
32 | target: editor
33 | tests: false # Disabled due freeze caused by mix Mono build and CI
34 | sconsflags: module_mono_enabled=yes
35 | doc-test: true
36 | bin: "./bin/godot.linuxbsd.editor.x86_64.mono"
37 | build-mono: true
38 | proj-conv: true
39 | artifact: true
40 |
41 | # Removed dev-builds (https://github.com/godotengine/godot/blob/master/.github/workflows/linux_builds.yml#L38)
42 | # TODO: There was an issue with quickjs debugger, maybe this can be enabled again after fixing the debugger
43 |
44 | - name: Template w/ Mono (target=template_release)
45 | cache-name: linux-template-mono
46 | target: template_release
47 | tests: false
48 | sconsflags: module_mono_enabled=yes
49 | build-mono: false
50 | artifact: true
51 |
52 | - name: Minimal template (target=template_release, everything disabled)
53 | cache-name: linux-template-minimal
54 | target: template_release
55 | tests: false
56 | sconsflags: modules_enabled_by_default=no disable_3d=yes disable_advanced_gui=yes deprecated=no minizip=no
57 | artifact: true
58 |
59 | steps:
60 | - name: Checkout Godot
61 | uses: actions/checkout@v4
62 | with:
63 | repository: godotengine/godot
64 | ref: ${{ inputs.version }}
65 |
66 | - name: Checkout ECMAScript
67 | uses: actions/checkout@v4
68 | with:
69 | path: ${{github.workspace}}/modules/javascript/
70 |
71 | # Need newer mesa for lavapipe to work properly.
72 | - name: Linux dependencies for tests
73 | if: ${{ matrix.proj-test }}
74 | run: |
75 | sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
76 | sudo add-apt-repository ppa:kisak/kisak-mesa
77 | sudo apt-get install -qq mesa-vulkan-drivers
78 |
79 | - name: Setup Godot build cache
80 | uses: ./.github/actions/godot-cache
81 | with:
82 | cache-name: ${{ matrix.cache-name }}
83 | continue-on-error: true
84 |
85 | - name: Setup python and scons
86 | uses: ./.github/actions/godot-deps
87 |
88 | - name: Set up .NET Sdk
89 | uses: actions/setup-dotnet@v2
90 | if: ${{ matrix.build-mono }}
91 | with:
92 | dotnet-version: '6.0.x'
93 |
94 | - name: Setup GCC problem matcher
95 | uses: ammaraskar/gcc-problem-matcher@master
96 |
97 | - name: Compilation
98 | uses: ./.github/actions/godot-build
99 | with:
100 | sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
101 | platform: linuxbsd
102 | target: ${{ matrix.target }}
103 | tests: ${{ matrix.tests }}
104 |
105 | - name: Generate C# glue
106 | if: ${{ matrix.build-mono }}
107 | run: |
108 | ${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue || true
109 |
110 | - name: Build .NET solutions
111 | if: ${{ matrix.build-mono }}
112 | run: |
113 | ./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd
114 |
115 | # Execute unit tests for the editor
116 | - name: Unit tests
117 | if: ${{ matrix.tests }}
118 | run: |
119 | ${{ matrix.bin }} --version
120 | ${{ matrix.bin }} --help
121 | ${{ matrix.bin }} --test --headless
122 |
123 | # Check class reference
124 | - name: Check for class reference updates
125 | if: ${{ matrix.doc-test }}
126 | run: |
127 | echo "Running --doctool to see if this changes the public API without updating the documentation."
128 | echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
129 | ${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true
130 | git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$'
131 |
132 | # Test 3.x -> 4.x project converter
133 | - name: Test project converter
134 | if: ${{ matrix.proj-conv }}
135 | run: |
136 | mkdir converter_test
137 | cd converter_test
138 | touch project.godot
139 | ../${{ matrix.bin }} --headless --validate-conversion-3to4
140 | cd ..
141 | rm converter_test -rf
142 |
143 | # Download and extract zip archive with project, folder is renamed to be able to easy change used project
144 | - name: Download test project
145 | if: ${{ matrix.proj-test }}
146 | run: |
147 | wget https://github.com/godotengine/regression-test-project/archive/4.0.zip
148 | unzip 4.0.zip
149 | mv "regression-test-project-4.0" "test_project"
150 |
151 | # Editor is quite complicated piece of software, so it is easy to introduce bug here
152 | - name: Open and close editor (Vulkan)
153 | if: ${{ matrix.proj-test }}
154 | run: |
155 | xvfb-run ${{ matrix.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
156 | misc/scripts/check_ci_log.py sanitizers_log.txt
157 |
158 | - name: Open and close editor (GLES3)
159 | if: ${{ matrix.proj-test }}
160 | run: |
161 | DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
162 | misc/scripts/check_ci_log.py sanitizers_log.txt
163 |
164 | # Run test project
165 | - name: Run project
166 | if: ${{ matrix.proj-test }}
167 | run: |
168 | xvfb-run ${{ matrix.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
169 | misc/scripts/check_ci_log.py sanitizers_log.txt
170 |
171 | # Checkout godot-cpp
172 | - name: Checkout godot-cpp
173 | if: ${{ matrix.godot-cpp-test }}
174 | uses: actions/checkout@v3
175 | with:
176 | repository: godotengine/godot-cpp
177 | ref: ${{ inputs.version }}
178 | submodules: 'recursive'
179 | path: 'godot-cpp'
180 |
181 | # Dump GDExtension interface and API
182 | - name: Dump GDExtension interface and API for godot-cpp build
183 | if: ${{ matrix.godot-cpp-test }}
184 | run: |
185 | ${{ matrix.bin }} --headless --dump-gdextension-interface --dump-extension-api
186 | cp -f gdextension_interface.h godot-cpp/gdextension/
187 | cp -f extension_api.json godot-cpp/gdextension/
188 |
189 | # Build godot-cpp test extension
190 | - name: Build godot-cpp test extension
191 | if: ${{ matrix.godot-cpp-test }}
192 | run: |
193 | cd godot-cpp/test
194 | scons target=template_debug dev_build=yes
195 | cd ../..
196 |
197 | - name: Prepare artifact
198 | if: ${{ matrix.artifact }}
199 | run: |
200 | strip bin/godot.*
201 | chmod +x bin/godot.*
202 |
203 | - name: Upload artifact
204 | uses: ./.github/actions/upload-artifact
205 | if: ${{ matrix.artifact }}
206 | with:
207 | name: ${{ matrix.cache-name }}
208 |
--------------------------------------------------------------------------------
/.github/workflows/macos_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🍎 macOS Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 |
10 | # Global Settings
11 | env:
12 | SCONSFLAGS: warnings=extra werror=yes module_text_server_fb_enabled=yes
13 |
14 | concurrency:
15 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos
16 | cancel-in-progress: true
17 |
18 | jobs:
19 | build-macos:
20 | runs-on: "macos-latest"
21 | name: ${{ matrix.name }}
22 | strategy:
23 | fail-fast: false
24 | matrix:
25 | include:
26 | - name: Editor (target=editor, tests=yes)
27 | cache-name: macos-editor
28 | target: editor
29 | tests: true
30 | bin: "./bin/godot.macos.editor.universal"
31 |
32 | - name: Template (target=template_release)
33 | cache-name: macos-template
34 | target: template_release
35 | tests: false
36 | sconsflags: debug_symbols=no
37 |
38 | steps:
39 | - name: Checkout Godot
40 | uses: actions/checkout@v4
41 | with:
42 | repository: godotengine/godot
43 | ref: ${{ inputs.version }}
44 |
45 | - name: Checkout ECMAScript
46 | uses: actions/checkout@v4
47 | with:
48 | path: ${{github.workspace}}/modules/javascript/
49 |
50 | - name: Setup Godot build cache
51 | uses: ./.github/actions/godot-cache
52 | with:
53 | cache-name: ${{ matrix.cache-name }}
54 | continue-on-error: true
55 |
56 | - name: Setup python and scons
57 | uses: ./.github/actions/godot-deps
58 |
59 | - name: Setup Vulkan SDK
60 | run: |
61 | sh misc/scripts/install_vulkan_sdk_macos.sh
62 |
63 | - name: Compilation (x86_64)
64 | uses: ./.github/actions/godot-build
65 | with:
66 | sconsflags: ${{ env.SCONSFLAGS }} arch=x86_64
67 | platform: macos
68 | target: ${{ matrix.target }}
69 | tests: ${{ matrix.tests }}
70 |
71 | - name: Compilation (arm64)
72 | uses: ./.github/actions/godot-build
73 | with:
74 | sconsflags: ${{ env.SCONSFLAGS }} arch=arm64
75 | platform: macos
76 | target: ${{ matrix.target }}
77 | tests: ${{ matrix.tests }}
78 |
79 | - name: Prepare artifact
80 | run: |
81 | lipo -create ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64 -output ./bin/godot.macos.${{ matrix.target }}.universal
82 | rm ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64
83 | strip bin/godot.*
84 | chmod +x bin/godot.*
85 |
86 | - name: Upload artifact
87 | uses: ./.github/actions/upload-artifact
88 | with:
89 | name: ${{ matrix.cache-name }}
90 |
91 | # Execute unit tests for the editor
92 | - name: Unit tests
93 | if: ${{ matrix.tests }}
94 | run: |
95 | ${{ matrix.bin }} --version
96 | ${{ matrix.bin }} --help
97 | ${{ matrix.bin }} --test --force-colors
98 |
--------------------------------------------------------------------------------
/.github/workflows/release_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🦅 Release Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 | concurrency:
10 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-android
11 | cancel-in-progress: true
12 |
13 | permissions:
14 | contents: write
15 |
16 | jobs:
17 | rename:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: ⏬ Checkout repo
21 | uses: actions/checkout@v4
22 |
23 | - name: 📛 Add version to release name
24 | uses: actions/github-script@v6
25 | with:
26 | result-encoding: json
27 | script: |
28 | const { repo, owner } = context.repo;
29 | const date = new Date();
30 | const year = date.getFullYear().toString();
31 | const month = (date.getMonth() + 1).toString().padStart(2,"0");
32 | const day = (date.getDay() + 1).toString().padStart(2,"0");
33 | await github.rest.repos.updateRelease({
34 | owner,
35 | repo,
36 | release_id: context.payload.release.id,
37 | name: '${{ inputs.version }}-' + context.payload.release.name + '-' + year + month + day,
38 | });
39 |
40 | release:
41 | runs-on: ubuntu-latest
42 | name: ${{ matrix.name }}
43 | strategy:
44 | fail-fast: false
45 | matrix:
46 | name:
47 | - android-template
48 | - ios-template
49 | - linux-editor-mono
50 | - linux-template-minimal
51 | - linux-template-mono
52 | - macos-editor
53 | - macos-template
54 | - web-template
55 | - windows-editor
56 | - windows-template
57 | steps:
58 | - name: ⏬ Checkout repo
59 | uses: actions/checkout@v4
60 |
61 | - name: ⏬ Download build
62 | uses: actions/download-artifact@v4
63 | with:
64 | name: ${{ matrix.name }}
65 | path: ${{ matrix.name }}
66 |
67 | - name: 📦 Pack build as zip
68 | run: zip -r ${{ matrix.name }}.zip ${{ matrix.name }}
69 | shell: bash
70 |
71 | - name: ⏫ Upload Release Asset
72 | id: upload-release-asset
73 | uses: actions/github-script@v6
74 | with:
75 | result-encoding: json
76 | script: |
77 | const FS = require('node:fs')
78 | const { repo, owner } = context.repo;
79 | return await github.rest.repos.uploadReleaseAsset({
80 | owner,
81 | repo,
82 | release_id: context.payload.release.id,
83 | name: '${{ matrix.name }}.zip',
84 | data: FS.readFileSync('${{ github.workspace }}/${{ matrix.name }}.zip')
85 | });
86 |
--------------------------------------------------------------------------------
/.github/workflows/runner.yml:
--------------------------------------------------------------------------------
1 | name: 🔗 GHA
2 |
3 | # Only run pipeline on open pull_requests and master + versions + releases
4 | # we don't need it on every push and some parameters are not available for push only
5 | on:
6 | pull_request:
7 | push:
8 | branches:
9 | - "master"
10 | - "3.4"
11 | - "4.1"
12 | release:
13 | types: [published]
14 |
15 | concurrency:
16 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-runner
17 | cancel-in-progress: true
18 |
19 | jobs:
20 | get-version:
21 | name: 🆚 Get godot version
22 | uses: ./.github/workflows/get_version.yml
23 |
24 | static-checks:
25 | name: 📊 Static checks
26 | uses: ./.github/workflows/static_checks.yml
27 | needs: get-version
28 | with:
29 | version: ${{ needs.get-version.outputs.version }}
30 |
31 | android-build:
32 | name: 🤖 Android
33 | needs: [static-checks, get-version]
34 | uses: ./.github/workflows/android_builds.yml
35 | with:
36 | version: ${{ needs.get-version.outputs.version }}
37 |
38 | ios-build:
39 | name: 🍏 iOS
40 | needs: [static-checks, get-version]
41 | uses: ./.github/workflows/ios_builds.yml
42 | with:
43 | version: ${{ needs.get-version.outputs.version }}
44 |
45 | linux-build:
46 | name: 🐧 Linux
47 | needs: [static-checks, get-version]
48 | uses: ./.github/workflows/linux_builds.yml
49 | with:
50 | version: ${{ needs.get-version.outputs.version }}
51 |
52 | macos-build:
53 | name: 🍎 macOS
54 | needs: [static-checks, get-version]
55 | uses: ./.github/workflows/macos_builds.yml
56 | with:
57 | version: ${{ needs.get-version.outputs.version }}
58 |
59 | windows-build:
60 | name: 🏁 Windows
61 | needs: [static-checks, get-version]
62 | uses: ./.github/workflows/windows_builds.yml
63 | with:
64 | version: ${{ needs.get-version.outputs.version }}
65 |
66 | web-build:
67 | name: 🌐 Web
68 | needs: [static-checks, get-version]
69 | uses: ./.github/workflows/web_builds.yml
70 | with:
71 | version: ${{ needs.get-version.outputs.version }}
72 |
73 | checks-done:
74 | if: ${{ always() }}
75 | name: ✅ Check builds
76 | runs-on: ubuntu-latest
77 | steps:
78 | - name: 🎉 Checks done
79 | run: |
80 | resultWebBuild="${{ needs.web-build.result }}"
81 | resultWindowsBuild="${{ needs.windows-build.result }}"
82 | resultMacosBuild="${{ needs.macos-build.result }}"
83 | resultLinuxBuild="${{ needs.linux-build.result }}"
84 | resultIosBuild="${{ needs.ios-build.result }}"
85 | resultAndroidBuild="${{ needs.android-build.result }}"
86 | if [[
87 | $resultWebBuild == "success" &&
88 | $resultWindowsBuild == "success" &&
89 | $resultMacosBuild == "success" &&
90 | $resultLinuxBuild == "success" &&
91 | $resultIosBuild == "success" &&
92 | $resultAndroidBuild == "success"
93 | ]];
94 | then
95 | echo "🎉 All builds were successful."
96 | exit 0
97 | else
98 | echo "😥 Some builds were failing."
99 | exit 1
100 | fi
101 | needs:
102 | [
103 | web-build,
104 | windows-build,
105 | macos-build,
106 | linux-build,
107 | ios-build,
108 | android-build
109 | ]
110 |
111 | release:
112 | name: 🦅 Release
113 | if: github.event_name == 'release' && github.event.action == 'published'
114 | needs: [checks-done, get-version]
115 | uses: ./.github/workflows/release_builds.yml
116 | secrets: inherit
117 | with:
118 | version: ${{ needs.get-version.outputs.version }}
119 |
--------------------------------------------------------------------------------
/.github/workflows/static_checks.yml:
--------------------------------------------------------------------------------
1 | name: 📊 Static Checks
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 | concurrency:
10 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | static-checks:
15 | name: Code style, file formatting, and docs
16 | runs-on: ubuntu-22.04
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Checkout Godot
22 | uses: actions/checkout@v4
23 | with:
24 | repository: godotengine/godot
25 | ref: ${{ inputs.version }}
26 | sparse-checkout: |
27 | misc/scripts
28 | sparse-checkout-cone-mode: false
29 | path: tmp
30 |
31 | - name: Checkout workaround
32 | run: |
33 | mv tmp/misc/scripts misc/scripts
34 | cp clang_format.sh misc/scripts/clang_format.sh
35 |
36 | - name: Install APT dependencies
37 | uses: awalsh128/cache-apt-pkgs-action@latest
38 | with:
39 | packages: dos2unix libxml2-utils moreutils
40 |
41 | - name: Install Python dependencies and general setup
42 | run: |
43 | pip3 install black==22.3.0 pytest==7.1.2 mypy==0.971
44 | git config diff.wsErrorHighlight all
45 |
46 | - name: Get changed files
47 | id: changed-files
48 | env:
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 | run: |
51 | if [ "${{ github.event_name }}" == "pull_request" ]; then
52 | files=$(gh pr diff ${{ github.event.pull_request.number }} --name-only)
53 | elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.forced }}" == "false" -a "${{ github.event.created }}" == "false" ]; then
54 | files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true)
55 | fi
56 | echo "$files" >> changed.txt
57 | cat changed.txt
58 | files=$(echo "$files" | grep -v 'thirdparty' | xargs -I {} sh -c 'echo "./{}"' | tr '\n' ' ')
59 | echo "CHANGED_FILES=$files" >> $GITHUB_ENV
60 |
61 | - name: File formatting checks (file_format.sh)
62 | run: |
63 | bash ./misc/scripts/file_format.sh changed.txt
64 |
65 | - name: Python scripts static analysis (mypy_check.sh)
66 | run: |
67 | if grep -qE '\.py$|SConstruct|SCsub' changed.txt || [ -z "$(cat changed.txt)" ]; then
68 | bash ./misc/scripts/mypy_check.sh
69 | else
70 | echo "Skipping Python static analysis as no Python files were changed."
71 | fi
72 |
73 | - name: Style checks via clang-format (clang_format.sh)
74 | run: |
75 | clang-format --version
76 | bash ./misc/scripts/clang_format.sh changed.txt
77 |
--------------------------------------------------------------------------------
/.github/workflows/web_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🌐 Web Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 |
10 | # Global Settings
11 | env:
12 | SCONSFLAGS: warnings=extra werror=yes debug_symbols=no
13 | EM_VERSION: 3.1.18
14 | EM_CACHE_FOLDER: "emsdk-cache"
15 |
16 | concurrency:
17 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-web
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | web-template:
22 | runs-on: "ubuntu-20.04"
23 | name: Template (target=template_release)
24 |
25 | steps:
26 | - name: Checkout Godot
27 | uses: actions/checkout@v4
28 | with:
29 | repository: godotengine/godot
30 | ref: ${{ inputs.version }}
31 |
32 | - name: Checkout ECMAScript
33 | uses: actions/checkout@v4
34 | with:
35 | path: ${{github.workspace}}/modules/javascript/
36 |
37 | - name: Set up Emscripten latest
38 | uses: mymindstorm/setup-emsdk@v12
39 | with:
40 | version: ${{env.EM_VERSION}}
41 | actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
42 |
43 | - name: Verify Emscripten setup
44 | run: |
45 | emcc -v
46 |
47 | - name: Setup Godot build cache
48 | uses: ./.github/actions/godot-cache
49 | continue-on-error: true
50 |
51 | - name: Setup python and scons
52 | uses: ./.github/actions/godot-deps
53 |
54 | - name: Compilation
55 | uses: ./.github/actions/godot-build
56 | with:
57 | sconsflags: ${{ env.SCONSFLAGS }}
58 | platform: web
59 | target: template_release
60 | tests: false
61 |
62 | - name: Upload artifact
63 | uses: ./.github/actions/upload-artifact
64 |
--------------------------------------------------------------------------------
/.github/workflows/windows_builds.yml:
--------------------------------------------------------------------------------
1 | name: 🏁 Windows Builds
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | required: true
7 | type: string
8 |
9 |
10 | # Global Settings
11 | # SCONS_CACHE for windows must be set in the build environment
12 | env:
13 | SCONSFLAGS: warnings=extra werror=yes module_text_server_fb_enabled=yes
14 | SCONS_CACHE_MSVC_CONFIG: true
15 |
16 | concurrency:
17 | group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-windows
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | build-windows:
22 | # Windows 10 with latest image
23 | runs-on: "windows-latest"
24 | name: ${{ matrix.name }}
25 | strategy:
26 | fail-fast: false
27 | matrix:
28 | include:
29 | - name: Editor (target=editor, tests=yes)
30 | cache-name: windows-editor
31 | target: editor
32 | tests: true
33 | # Skip debug symbols, they're way too big with MSVC.
34 | sconsflags: debug_symbols=no vsproj=yes
35 | bin: "./bin/godot.windows.editor.x86_64.exe"
36 |
37 | - name: Template (target=template_release)
38 | cache-name: windows-template
39 | target: template_release
40 | tests: false
41 | sconsflags: debug_symbols=no
42 |
43 | steps:
44 | - name: Checkout Godot
45 | uses: actions/checkout@v4
46 | with:
47 | repository: godotengine/godot
48 | ref: ${{ inputs.version }}
49 |
50 | - name: Checkout ECMAScript
51 | uses: actions/checkout@v4
52 | with:
53 | path: ${{github.workspace}}/modules/javascript/
54 |
55 | - name: Setup Godot build cache
56 | uses: ./.github/actions/godot-cache
57 | with:
58 | cache-name: ${{ matrix.cache-name }}
59 | continue-on-error: true
60 |
61 | - name: Setup python and scons
62 | uses: ./.github/actions/godot-deps
63 |
64 | - name: Setup MSVC problem matcher
65 | uses: ammaraskar/msvc-problem-matcher@master
66 |
67 | - name: Compilation
68 | uses: ./.github/actions/godot-build
69 | with:
70 | sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
71 | platform: windows
72 | target: ${{ matrix.target }}
73 | tests: ${{ matrix.tests }}
74 |
75 | # Execute unit tests for the editor
76 | - name: Unit tests
77 | if: ${{ matrix.tests }}
78 | run: |
79 | ${{ matrix.bin }} --version
80 | ${{ matrix.bin }} --help
81 | ${{ matrix.bin }} --test --force-colors
82 |
83 | - name: Prepare artifact
84 | run: |
85 | Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
86 |
87 | - name: Upload artifact
88 | uses: ./.github/actions/upload-artifact
89 | with:
90 | name: ${{ matrix.cache-name }}
91 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.obj
3 | *.lib
4 | *.d
5 | *.pyc
6 | *.bc
7 | *.os
8 | *.gen.cpp
9 | *.gen.json
10 | .vscode
11 | .idea
12 | /site
13 | venv
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Project Structure
4 |
5 | - [Clang](https://clang.llvm.org/): Code formatting
6 | - ``.clang-format``
7 | - ``.clang-tidy``
8 | - ``clang-format.sh``
9 | - [Custom Modules in C++](https://docs.godotengine.org/en/stable/contributing/development/core_and_modules/custom_modules_in_cpp.html#custom-modules-in-c)
10 | - ``config.py``: Configs for this module
11 | - ``doc``: For showing documentation in editor
12 | - ``doc_classes``: For showing documentation in editor
13 | - ``icons``: For showing icons in editor
14 | - ``SCsub``: Will be called from Godots `SConstruct` during build
15 | - ``editor``: Custom `.cpp` only bundled for `target=editor`
16 | - ``misc``: Scripts and other files, which aren't related to `c++`
17 | - ``tests``: Some testcases to run in CICD
18 | - ``thirdparty``: Dependencies or libraries which shouldn't be analysed by static checks
19 | - GodotJS custom data
20 | - ``.github``: Runs custom CI/CD in GitHub
21 | - ``docs``: Add some additional stuff for README.md
22 | - ``src``: Contains custom C++ code
23 | - [language](src/language/README.md)
24 |
25 |
26 | ## Preparing your PR
27 |
28 | The project is using [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) to format C++ files.
29 | You need to run `bash clang_format.sh` before your PR for a successful pipeline.
30 |
31 | Furthermore, there is an `utf-8` and `LF` checker to fix file formats. Additionally, some spellchecks run inside the [pipeline](.github/workflows/static_checks.yml).
32 |
33 | ## Release library
34 |
35 | As a maintainer you are able to create a new release.
36 | 1. Go to [create new release](https://github.com/godotjs/javascript/releases/new)
37 | 2. Next you should ``Choose a tag`` and create a new one in the format `v0.0.0`
38 | 3. Select target ``master``
39 | 4. Click ``Generate release notes``
40 | 5. (Optional) You can edit the generated release notes
41 | 6. Add a release title in the format `v0.0.0`
42 | 7. Press ``Publish release``
43 |
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019-2020 Geequlim
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | # **GodotJS**
7 |
8 | ***-- JavaScript and TypeScript language binding for Godot game engine --***
9 |
10 | This module implements JavaScript/TypeScript language support for the Godot game engine using [QuickJS](https://bellard.org/quickjs/) as the JavaScript engine.
11 |
12 |
13 | ## Getting started
14 |
15 | Read the [getting-started](https://godotjs.github.io/documentation/getting-started/).
16 |
17 | ## Features
18 |
19 | - Almost complete ES2020 support
20 | - All Godot API available
21 | - Operator overriding for built-in types (Vector3, Color, etc)
22 | - TypeScript support
23 | - [Using third-party libraries from npm](https://github.com/GodotExplorer/ECMAScriptDemos/tree/master/npm_module)
24 | - Multi-thread support with Worker API
25 | - Full code completion support for all Godot APIs including signals and enumerations
26 | - Debug in Visual Studio Code with the [plugin](https://marketplace.visualstudio.com/items?itemName=geequlim.godot-javascript-debug) - currently not available for 4.x
27 |
28 | ## Getting the engine
29 |
30 | No installation or setup necessary. The binaries for download are the complete, usable Godot editor and engine with JavaScript/TypeScript language support.
31 |
32 | ### Binary downloads
33 |
34 | Download the binaries from the [release page](https://github.com/GodotExplorer/ECMAScript/releases).
35 |
36 | ### Compiling from source
37 |
38 | - Clone the source code of [godot](https://github.com/godotengine/godot):
39 | - `git clone git@github.com:godotengine/godot.git` or
40 | - `git clone https://github.com/godotengine/godot.git`
41 | - This branch uses version `4.1` so checkout the version with: `git checkout 4.1`
42 | - Clone this module and put it into `godot/modules/javascript`:
43 | - `git clone git@github.com:godotjs/javascript.git godot/modules/javascript` or
44 | - `git clone https://github.com/godotjs/javascript.git godot/modules/javascript`
45 | - [Recompile the godot engine](https://docs.godotengine.org/en/4.1/development/compiling/index.html)
46 | - Use `scons` with those additional options `warnings=extra werror=yes module_text_server_fb_enabled=yes` to show all potential errors:
47 | - Windows: `scons platform=windows warnings=extra werror=yes module_text_server_fb_enabled=yes`
48 | - MacOS: `scons platform=macos arch=arm64 warnings=extra werror=yes module_text_server_fb_enabled=yes`
49 | - **Hint**: To enable unit tests you need to add ``tests=true`` to `scons` arguments
50 |
51 | ## Documentation, Tutorials & Demos
52 |
53 |
54 | Read this [documentation](https://godotjs.github.io/documentation/getting-started/) or look at the tutorials or demos:
55 |
56 | - [ECMAScriptDemos](https://github.com/godotjs/javascriptDemos) - Demos
57 | - [godot-ECMAScript-cookbook](https://github.com/why-try313/godot-ECMAScript-cookbook/wiki) - Tutorial
58 | - [godot-typescript-starter](https://github.com/citizenll/godot-typescript-starter) - Template
59 | - [godot-js-template](https://github.com/fukaraadam-workspace/godot-js-template) - Template
60 |
61 | ## Contributing
62 |
63 | If you like to contribute to this project check the [CONTRIBUTING.md](https://github.com/godotjs/javascript/blob/master/CONTRIBUTING.md) file.
64 |
--------------------------------------------------------------------------------
/SCsub:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 |
4 | from misc.generate.generate_files import generate
5 |
6 | Import("env")
7 | Import("env_modules")
8 |
9 | env_javascript = env_modules.Clone()
10 |
11 | # Default engine to use we might add some more in the future like node or v8
12 | JS_ENGINE = "quickjs"
13 | javascript_dir = os.path.join(GetLaunchDir(), "modules", os.path.basename(os.getcwd()))
14 |
15 | # Windows workaround
16 | if env["platform"] == "windows":
17 | if env["use_mingw"]:
18 | env.Append(LIBS=["pthread"])
19 |
20 | # Add required files for quickjs into godot
21 | if JS_ENGINE == "quickjs":
22 | import generate_builtin_api
23 |
24 | generate_builtin_api.generate_api_json(javascript_dir)
25 | import thirdparty.quickjs.builtin_binding_generator
26 |
27 | thirdparty.quickjs.builtin_binding_generator.generate_builtin_bindings()
28 | version = open("thirdparty/quickjs/quickjs/VERSION.txt", "r").read().split("\n")[0]
29 | quickjs_env = env_javascript.Clone()
30 | quickjs_env.Append(CPPDEFINES={"QUICKJS_CONFIG_VERSION": '"' + version + '"'})
31 | quickjs_env.Append(CPPDEFINES=["CONFIG_BIGNUM"])
32 | if "release" not in (quickjs_env["target"] or ""):
33 | quickjs_env.Append(CPPDEFINES={"DUMP_LEAKS": 1})
34 | # TODO: Fix debugger
35 | # quickjs_env.Append(CPPDEFINES={"QUICKJS_WITH_DEBUGGER": 1})
36 | quickjs_env.Append(CPPPATH=["thirdparty/quickjs/quickjs"])
37 | quickjs_env.Append(CPPPATH=["thirdparty/quickjs"])
38 | quickjs_env.disable_warnings()
39 | quickjs_env.add_source_files(env.modules_sources, "thirdparty/quickjs/quickjs_builtin_binder.gen.cpp")
40 | quickjs_env.add_source_files(env.modules_sources, "thirdparty/quickjs/*.cpp")
41 | quickjs_env.add_source_files(env.modules_sources, "thirdparty/quickjs/quickjs/*.c")
42 |
43 | # If target=editor is provided via scons
44 | if env.editor_build:
45 | env_javascript.add_source_files(env.modules_sources, "editor/workarounds/*.cpp")
46 | env_javascript.add_source_files(env.modules_sources, "editor/*.cpp")
47 |
48 | # --- Generate editor tool files ---
49 | from misc.generate.editor_tools import get_editor_tools_files
50 | from misc.generate.editor_tools import get_editor_tools_header
51 |
52 | files = get_editor_tools_files()
53 | generate(javascript_dir, get_editor_tools_header(), files)
54 | env_javascript.add_source_files(env.modules_sources, files.keys())
55 |
56 | # If tests=yes flag is provided via scons
57 | if env["tests"]:
58 | env_javascript.Append(CPPDEFINES=["TESTS_ENABLED"])
59 |
60 | # --- Generate test files ---
61 | from misc.generate.test_manager import get_test_files
62 | from misc.generate.test_manager import get_test_manager_header
63 |
64 | files = get_test_files()
65 | generate(javascript_dir, get_test_manager_header(), files)
66 | env_javascript.add_source_files(env.modules_sources, files.keys())
67 |
68 | # --- Files inside editor & targets ---
69 |
70 | sources = [
71 | "register_types.cpp",
72 | "javascript_instance.cpp",
73 | "javascript.cpp",
74 | ]
75 |
76 | # Add all required files for "Javascript" language into godot
77 | env_javascript.Append(CPPPATH=["#modules/javascript"])
78 | env_javascript.add_source_files(env.modules_sources, sources)
79 | env_javascript.add_source_files(env.modules_sources, "src/language/*.cpp")
80 | env_javascript.add_source_files(env.modules_sources, "src/language/templates/*.cpp")
81 |
82 | # --- Generate template files ---
83 | from misc.generate.templates import get_templates_header
84 | from misc.generate.templates import get_templates_files
85 | from misc.generate.generate_files import generate_templates
86 |
87 | files = get_templates_files()
88 | generate_templates(javascript_dir, get_templates_header(), files)
89 | env_javascript.add_source_files(env.modules_sources, files.keys())
90 |
91 | # --- Generate binding files ---
92 | # Binding script to run at engine initializing
93 | # The bindings add some functionality for `this.connect(...)`
94 | from misc.generate.bindings import get_bindings_header
95 | from misc.generate.bindings import get_binding_files
96 |
97 | files = get_binding_files()
98 | generate(javascript_dir, get_bindings_header(), files)
99 | env_javascript.add_source_files(env.modules_sources, files.keys())
100 |
--------------------------------------------------------------------------------
/clang_format.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script runs clang-format and fixes copyright headers on all relevant files in the repo.
4 | # This is the primary script responsible for fixing style violations.
5 |
6 | set -uo pipefail
7 |
8 | if [ $# -eq 0 ]; then
9 | # Loop through all code files tracked by Git.
10 | files=$(git ls-files -- '*.c' '*.h' '*.cpp' '*.hpp' '*.cc' '*.hh' '*.cxx' '*.m' '*.mm' '*.inc' '*.java' '*.glsl' \
11 | ':!:.git/*' ':!:thirdparty/*' ':!:*/thirdparty/*' ':!:platform/android/java/lib/src/com/google/*' \
12 | ':!:*-so_wrap.*' ':!:tests/python_build/*')
13 | else
14 | # $1 should be a file listing file paths to process. Used in CI.
15 | files=$(cat "$1" | grep -v "thirdparty/" | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$" | grep -v "platform/android/java/lib/src/com/google/" | grep -v "\-so_wrap\." | grep -v "tests/python_build/")
16 | fi
17 |
18 | if [ ! -z "$files" ]; then
19 | clang-format --Wno-error=unknown -i $files
20 | fi
21 |
22 | diff=$(git diff --color)
23 |
24 | # If no diff has been generated all is OK, clean up, and exit.
25 | if [ -z "$diff" ] ; then
26 | printf "\e[1;32m*** Files in this commit comply with the clang-format style rules.\e[0m\n"
27 | exit 0
28 | fi
29 |
30 | # A diff has been created, notify the user, clean up, and exit.
31 | printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
32 | # Perl commands replace trailing spaces with `·` and tabs with ``.
33 | printf "%s\n" "$diff" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="" x length($2); sprintf("$1$tabs$3")/ge'
34 |
35 | printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i '\e[0m\n"
36 | exit 1
37 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | def can_build(env, platform):
2 | return True
3 |
4 |
5 | def configure(env):
6 | pass
7 |
8 |
9 | def get_doc_classes():
10 | return [
11 | "JavaScript",
12 | "JavaScriptModule",
13 | ]
14 |
15 |
16 | def get_doc_path():
17 | return "doc_classes"
18 |
--------------------------------------------------------------------------------
/doc_classes/JavaScript.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A JavaScript script resource for creating and managing JavaScript scripts in Godot.
5 |
6 |
7 | The JavaScript class provides a way to create and manage JavaScript scripts within the Godot game engine. It inherits from the Script class and allows you to write game logic using JavaScript as the scripting language.
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/doc_classes/JavaScriptModule.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A JavaScript module resource for managing JavaScript source code and bytecode.
5 |
6 |
7 | The JavaScriptModule class provides methods to manage JavaScript source code and bytecode. It allows you to get and set both the source code and bytecode of a JavaScript module.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Returns the bytecode of the JavaScript module as a PackedByteArray.
16 |
17 |
18 |
19 |
20 |
21 | Returns the source code of the JavaScript module as a String.
22 |
23 |
24 |
25 |
26 |
27 |
28 | Sets the bytecode of the JavaScript module using a PackedByteArray.
29 |
30 |
31 |
32 |
33 |
34 |
35 | Sets the source code of the JavaScript module using a String.
36 |
37 |
38 |
39 |
40 |
41 | The path to the JavaScript script file.
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/docs/JavaScript.svg.licence:
--------------------------------------------------------------------------------
1 | ../icon/JavaScript.svg: https://commons.wikimedia.org/wiki/File:Unofficial_JavaScript_logo.svg
2 |
--------------------------------------------------------------------------------
/editor/editor_tools.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef EDITOR_TOOLS_H
3 | #define EDITOR_TOOLS_H
4 |
5 | #include "editor/editor_node.h"
6 | #include "editor/editor_plugin.h"
7 | #include "editor/gui/editor_file_dialog.h"
8 |
9 | class DocTools;
10 | class EditorFileDialog;
11 | class JavaScriptPlugin : public EditorPlugin {
12 | GDCLASS(JavaScriptPlugin, EditorPlugin);
13 |
14 | enum MenuItem {
15 | ITEM_GEN_DECLARE_FILE,
16 | ITEM_GEN_ENUM_BINDING_SCRIPT,
17 | };
18 |
19 | EditorFileDialog *declaration_file_dialog;
20 | EditorFileDialog *enumberation_file_dialog;
21 | const Dictionary *modified_api;
22 |
23 | protected:
24 | /* Strings will be generated by ./SCsub from misc directory */
25 | static String BUILTIN_DECLARATION_TEXT;
26 |
27 | /* Missing declarations, ignoring*/
28 | static Dictionary DECLARATION_CONSTRUCTORS;
29 | static Dictionary DECLARATION_ENUMS;
30 | static Array IGNORE_METHODS;
31 |
32 | static void _bind_methods();
33 |
34 | void _notification(int p_what);
35 | void _on_menu_item_pressed(int item);
36 | void _export_typescript_declare_file(const String &p_path);
37 | void _export_enumeration_binding_file(const String &p_path);
38 |
39 | public:
40 | virtual String get_name() const override { return "JavaScriptPlugin"; }
41 | JavaScriptPlugin(EditorNode *p_node);
42 | };
43 |
44 | #endif // EDITOR_TOOLS_H
45 |
--------------------------------------------------------------------------------
/editor/workarounds/ignore-methods.cpp:
--------------------------------------------------------------------------------
1 | /* All types are generated in editor_tools, but some getters and setters are obsolete we need to ignore them. */
2 |
3 | #include "../editor_tools.h"
4 |
5 | Array create_ignore_methods() {
6 | Array array = Array();
7 | array.push_back("get_flag");
8 | array.push_back("set_flag");
9 | array.push_back("set_play_area_mode");
10 | return array;
11 | }
12 |
13 | Array JavaScriptPlugin::IGNORE_METHODS = create_ignore_methods();
14 |
--------------------------------------------------------------------------------
/editor/workarounds/missing-constructors.cpp:
--------------------------------------------------------------------------------
1 | /* All types are generated in editor_tools, but constructors are missing we need to add them manually. */
2 |
3 | #include "../editor_tools.h"
4 |
5 | Dictionary create_missing_constructors() {
6 | Dictionary dict;
7 | dict["Vector2"] = "\t\tconstructor(x?: number, y?: number);\n"
8 | "\t\tconstructor(v: Vector2);\n";
9 | dict["Rect2"] = "\t\tconstructor(from: Rect2);\n"
10 | "\t\tconstructor(x?: number, y?: number, w?: number, h?: number);\n"
11 | "\t\tconstructor(pos: Vector2, size: Vector2)\n";
12 | dict["Vector3"] = "\t\tconstructor(x?: number, y?: number, z?: number);\n"
13 | "\t\tconstructor(v: Vector3);\n";
14 | dict["Basis"] = "\t\tconstructor();\n"
15 | "\t\tconstructor(from: Basis);\n"
16 | "\t\tconstructor(from: Quaternion);\n"
17 | "\t\tconstructor(from: Vector3);\n"
18 | "\t\tconstructor(axis: Vector3, phi: number);\n"
19 | "\t\tconstructor(x_axis: Vector3, y_axis: Vector3, z_axis: Vector3);\n";
20 | dict["Transform3D"] = "\t\tconstructor(from: Transform3D);\n"
21 | "\t\tconstructor(from: Basis);\n"
22 | "\t\tconstructor(from: Quaternion);\n"
23 | "\t\tconstructor(from: Transform2D);\n"
24 | "\t\tconstructor(basis: Basis, origin: Vector3);\n"
25 | "\t\tconstructor(x_axis?: Vector3, y_axis?: Vector3, z_axis?: Vector3, origin?: Vector3);\n";
26 | dict["Basis"] = "\t\tconstructor();\n"
27 | "\t\tconstructor(from: Transform2D);\n"
28 | "\t\tconstructor(from: Transform3D);\n"
29 | "\t\tconstructor(x_axis: Vector2, y_axis: Vector2, origin: Vector2);\n"
30 | "\t\tconstructor(rotation: number, position: Vector2);\n";
31 | dict["Color"] = "\t\tconstructor(from: Color);\n"
32 | "\t\tconstructor(from: string);\n"
33 | "\t\tconstructor(from: number);\n"
34 | "\t\tconstructor(r?: number, g?: number, b?: number, a?: number);\n";
35 | dict["Plane"] = "\t\tconstructor(from: Plane);\n"
36 | "\t\tconstructor(v1: Vector3, d: number);\n"
37 | "\t\tconstructor(v1: Vector3, v2: Vector3, v3: Vector3);\n"
38 | "\t\tconstructor(a?: number, b?: number, c?: number, d?: number);\n";
39 | dict["Quaternion"] =
40 | "\t\tconstructor(from: Quaternion);\n"
41 | "\t\tconstructor(from: Basis);\n"
42 | "\t\tconstructor(euler: Vector3);\n"
43 | "\t\tconstructor(axis: Vector3, angle: number);\n"
44 | "\t\tconstructor(x?: number, y?: number, z?: number, w?: number);\n";
45 | dict["AABB"] =
46 | "\t\tconstructor(from: AABB);\n"
47 | "\t\tconstructor(position?: Vector3, size?: Vector3);\n";
48 | dict["PackedByteArray"] =
49 | "\t\tconstructor(source?: number[]);\n"
50 | "\t\tconstructor(from: PackedByteArray);\n"
51 | "\t\tconstructor(from: ArrayBuffer);\n"
52 | "\t\tconstructor(from: DataView);\n"
53 | "\t\t[Symbol.iterator](): IterableIterator;\n";
54 | dict["PackedColorArray"] =
55 | "\t\tconstructor(source?: Color[]);\n"
56 | "\t\tconstructor(from: PackedColorArray);\n"
57 | "\t\tconstructor(from: ArrayBuffer);\n"
58 | "\t\tconstructor(from: DataView);\n"
59 | "\t\t[Symbol.iterator](): IterableIterator;\n";
60 | dict["PackedInt32Array"] =
61 | "\t\tconstructor(source?: number[]);\n"
62 | "\t\tconstructor(from: PackedInt32Array);\n"
63 | "\t\tconstructor(from: ArrayBuffer);\n"
64 | "\t\tconstructor(from: DataView);\n"
65 | "\t\t[Symbol.iterator](): IterableIterator;\n";
66 | dict["PackedFloat32Array"] =
67 | "\t\tconstructor(source?: number[]);\n"
68 | "\t\tconstructor(from: PackedFloat32Array);\n"
69 | "\t\tconstructor(from: ArrayBuffer);\n"
70 | "\t\tconstructor(from: DataView);\n"
71 | "\t\t[Symbol.iterator](): IterableIterator;\n";
72 | dict["PackedStringArray"] =
73 | "\t\tconstructor(source?: string[]);\n"
74 | "\t\tconstructor(from: PackedStringArray);\n"
75 | "\t\t[Symbol.iterator](): IterableIterator;\n";
76 | dict["PackedVector2Array"] =
77 | "\t\tconstructor(source?: Vector2[]);\n"
78 | "\t\tconstructor(from: PackedVector2Array);\n"
79 | "\t\tconstructor(from: ArrayBuffer);\n"
80 | "\t\tconstructor(from: DataView);\n"
81 | "\t\t[Symbol.iterator](): IterableIterator;\n";
82 | dict["PackedVector3Array"] =
83 | "\t\tconstructor(source?: Vector3[]);\n"
84 | "\t\tconstructor(from: PackedVector3Array);\n"
85 | "\t\tconstructor(from: ArrayBuffer);\n"
86 | "\t\tconstructor(from: DataView);\n"
87 | "\t\t[Symbol.iterator](): IterableIterator;\n";
88 | return dict;
89 | }
90 |
91 | Dictionary JavaScriptPlugin::DECLARATION_CONSTRUCTORS = create_missing_constructors();
92 |
--------------------------------------------------------------------------------
/editor/workarounds/missing-enums.cpp:
--------------------------------------------------------------------------------
1 | /* All types are generated in editor_tools, but some enums are missing we need to add them manually. */
2 |
3 | #include "../editor_tools.h"
4 |
5 | Dictionary create_missing_enums() {
6 | Dictionary dict;
7 | dict["Vector3"] = "\t\tenum Axis {\n"
8 | "\t\t\tAXIS_X = 0,\n"
9 | "\t\t\tAXIS_Y = 1,\n"
10 | "\t\t\tAXIS_Z = 2,\n"
11 | "\t\t}\n";
12 | return dict;
13 | }
14 |
15 | Dictionary JavaScriptPlugin::DECLARATION_ENUMS = create_missing_enums();
16 |
--------------------------------------------------------------------------------
/generate_builtin_api.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import json, os, sys
3 | import xml.etree.ElementTree as ET
4 |
5 | BUILTIN_CLASSES = [
6 | "Vector2",
7 | "Rect2",
8 | "Color",
9 | "Vector3",
10 | "Basis",
11 | "Quaternion",
12 | "RID",
13 | "Transform2D",
14 | "Plane",
15 | "AABB",
16 | "Transform3D",
17 | "PackedByteArray",
18 | "PackedInt32Array",
19 | "PackedInt64Array",
20 | "PackedFloat32Array",
21 | "PackedFloat64Array",
22 | "PackedStringArray",
23 | "PackedVector2Array",
24 | "PackedVector3Array",
25 | "PackedColorArray",
26 | ]
27 |
28 | MAX_CONSTRUCTOR_ARGC = {
29 | "Vector2": 2,
30 | "Rect2": 4,
31 | "Color": 4,
32 | "Vector3": 3,
33 | "Basis": 0,
34 | "Quaternion": 0,
35 | "RID": 0,
36 | "Transform2D": 0,
37 | "Plane": 0,
38 | "AABB": 0,
39 | "Transform3D": 0,
40 | "PackedByteArray": 0,
41 | "PackedInt32Array": 0,
42 | "PackedInt64Array": 0,
43 | "PackedFloat32Array": 0,
44 | "PackedFloat64Array": 0,
45 | "PackedStringArray": 0,
46 | "PackedVector2Array": 0,
47 | "PackedVector3Array": 0,
48 | "PackedColorArray": 0,
49 | }
50 |
51 | TYPE_MAP = {
52 | "int": "number",
53 | "float": "number",
54 | "bool": "boolean",
55 | "String": "string",
56 | "NodePath": "string",
57 | }
58 |
59 | METHOD_OP_EQUALS = {
60 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
61 | "name": "equals",
62 | "native_method": "operator==",
63 | "return": "boolean",
64 | }
65 |
66 | METHOD_OP_ADD = {
67 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
68 | "name": "add",
69 | "native_method": "operator+",
70 | "return": "${class_name}",
71 | }
72 |
73 | METHOD_OP_ADD_ASSIGN = {
74 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
75 | "name": "add_assign",
76 | "native_method": "operator+=",
77 | "return": "this",
78 | }
79 |
80 | METHOD_OP_SUB = {
81 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
82 | "name": "subtract",
83 | "native_method": "operator-",
84 | "return": "${class_name}",
85 | }
86 |
87 | METHOD_OP_SUB_ASSIGN = {
88 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
89 | "name": "subtract_assign",
90 | "native_method": "operator-=",
91 | "return": "this",
92 | }
93 |
94 | METHOD_OP_MUL = {
95 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
96 | "name": "multiply",
97 | "native_method": "operator*",
98 | "return": "${class_name}",
99 | }
100 |
101 | METHOD_OP_MUL_ASSIGN = {
102 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
103 | "name": "multiply_assign",
104 | "native_method": "operator*=",
105 | "return": "this",
106 | }
107 |
108 | METHOD_OP_DIV = {
109 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
110 | "name": "multiply",
111 | "native_method": "operator/",
112 | "return": "${class_name}",
113 | }
114 |
115 | METHOD_OP_DIV_ASSIGN = {
116 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
117 | "name": "multiply_assign",
118 | "native_method": "operator/=",
119 | "return": "this",
120 | }
121 |
122 | METHOD_OP_NEG = {
123 | "arguments": [],
124 | "name": "negate",
125 | "native_method": "operator-",
126 | "return": "${class_name}",
127 | }
128 |
129 | METHOD_OP_LESS = {
130 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
131 | "name": "less",
132 | "native_method": "operator<",
133 | "return": "boolean",
134 | }
135 |
136 |
137 | METHOD_OP_LESS_EQAUL = {
138 | "arguments": [{"default_value": None, "has_default_value": False, "type": "${class_name}"}],
139 | "name": "less_equal",
140 | "native_method": "operator<=",
141 | "return": "boolean",
142 | }
143 |
144 | METHOD_PACKED_ARRAY_GET = {
145 | "arguments": [{"default_value": None, "has_default_value": False, "type": "number"}],
146 | "name": "get",
147 | "native_method": "operator[]",
148 | "return": "Variant",
149 | }
150 |
151 | IGNORED_PROPS = {
152 | "Rect2": ["end", "grow_side"],
153 | "Color": ["h", "s", "v", "r8", "g8", "b8", "a8"],
154 | "Transform2D": ["xform", "xform_inv"],
155 | "Quaternion": ["get_euler"],
156 | "Basis": ["is_equal_approx", "get_euler", "from_euler"],
157 | "Plane": ["intersects_segment", "intersects_ray", "intersect_3"],
158 | "AABB": ["end"],
159 | "Transform3D": ["xform", "xform_inv"],
160 | "PackedByteArray": [
161 | "compress",
162 | "decompress",
163 | "decompress_dynamic",
164 | "get_string_from_ascii",
165 | "get_string_from_utf8",
166 | "get_string_from_utf16",
167 | "get_string_from_utf32",
168 | "hex_encode",
169 | "to_float32_array",
170 | "to_float64_array",
171 | "to_int32_array",
172 | "to_int64_array",
173 | "has_encoded_var",
174 | ],
175 | }
176 |
177 | PROPERTY_REMAP = {
178 | "Transform2D": {
179 | "x": "columns[0]",
180 | "y": "columns[1]",
181 | "origin": "columns[2]",
182 | },
183 | "Basis": {
184 | "x": "rows[0]",
185 | "y": "rows[1]",
186 | "z": "rows[2]",
187 | },
188 | "Plane": {
189 | "x": "normal.x",
190 | "y": "normal.y",
191 | "z": "normal.z",
192 | },
193 | }
194 |
195 | OPERATOR_METHODS = {
196 | "Vector2": [
197 | METHOD_OP_NEG,
198 | METHOD_OP_EQUALS,
199 | METHOD_OP_LESS,
200 | METHOD_OP_LESS_EQAUL,
201 | METHOD_OP_ADD,
202 | METHOD_OP_ADD_ASSIGN,
203 | METHOD_OP_SUB,
204 | METHOD_OP_SUB_ASSIGN,
205 | METHOD_OP_MUL,
206 | METHOD_OP_MUL_ASSIGN,
207 | METHOD_OP_DIV,
208 | METHOD_OP_DIV_ASSIGN,
209 | ],
210 | "Vector3": [
211 | METHOD_OP_NEG,
212 | METHOD_OP_EQUALS,
213 | METHOD_OP_LESS,
214 | METHOD_OP_LESS_EQAUL,
215 | METHOD_OP_ADD,
216 | METHOD_OP_ADD_ASSIGN,
217 | METHOD_OP_SUB,
218 | METHOD_OP_SUB_ASSIGN,
219 | METHOD_OP_MUL,
220 | METHOD_OP_MUL_ASSIGN,
221 | METHOD_OP_DIV,
222 | METHOD_OP_DIV_ASSIGN,
223 | ],
224 | "Basis": [
225 | METHOD_OP_EQUALS,
226 | METHOD_OP_ADD,
227 | METHOD_OP_ADD_ASSIGN,
228 | METHOD_OP_SUB,
229 | METHOD_OP_SUB_ASSIGN,
230 | METHOD_OP_MUL,
231 | METHOD_OP_MUL_ASSIGN,
232 | ],
233 | "Quaternion": [
234 | METHOD_OP_NEG,
235 | METHOD_OP_EQUALS,
236 | METHOD_OP_ADD,
237 | METHOD_OP_ADD_ASSIGN,
238 | METHOD_OP_SUB,
239 | METHOD_OP_SUB_ASSIGN,
240 | ],
241 | "Rect2": [METHOD_OP_EQUALS],
242 | "Transform2D": [
243 | METHOD_OP_EQUALS,
244 | METHOD_OP_MUL,
245 | METHOD_OP_MUL_ASSIGN,
246 | ],
247 | "Color": [
248 | METHOD_OP_NEG,
249 | METHOD_OP_EQUALS,
250 | METHOD_OP_LESS,
251 | METHOD_OP_ADD,
252 | METHOD_OP_ADD_ASSIGN,
253 | METHOD_OP_SUB,
254 | METHOD_OP_SUB_ASSIGN,
255 | METHOD_OP_MUL,
256 | METHOD_OP_MUL_ASSIGN,
257 | METHOD_OP_DIV,
258 | METHOD_OP_DIV_ASSIGN,
259 | ],
260 | "RID": [
261 | METHOD_OP_EQUALS,
262 | METHOD_OP_LESS,
263 | METHOD_OP_LESS_EQAUL,
264 | ],
265 | "Plane": [
266 | METHOD_OP_NEG,
267 | METHOD_OP_EQUALS,
268 | ],
269 | "AABB": [
270 | METHOD_OP_EQUALS,
271 | ],
272 | "Transform3D": [
273 | METHOD_OP_EQUALS,
274 | METHOD_OP_MUL,
275 | METHOD_OP_MUL_ASSIGN,
276 | ],
277 | }
278 |
279 |
280 | def apply_pattern(template, values):
281 | for key in values:
282 | template = template.replace("${" + key + "}", values[key])
283 | return template
284 |
285 |
286 | def parse_class(cls):
287 | class_name = cls.get("name")
288 | ret = {"name": class_name}
289 | members = []
290 | methods = []
291 | operators = []
292 | constants = []
293 | ret["properties"] = members
294 | ret["methods"] = methods
295 | ret["operators"] = operators
296 | ret["constants"] = constants
297 | ret["constructor_argc"] = MAX_CONSTRUCTOR_ARGC[class_name]
298 |
299 | for m in cls.find("members") if cls.find("members") is not None else []:
300 | m_dict = dict(m.attrib)
301 | type = m_dict["type"]
302 | name = m_dict["name"]
303 | if (class_name in IGNORED_PROPS) and (name in IGNORED_PROPS[class_name]):
304 | continue
305 | if type in TYPE_MAP:
306 | type = TYPE_MAP[type]
307 | native_prop = name
308 | if class_name in PROPERTY_REMAP:
309 | if name in PROPERTY_REMAP[class_name]:
310 | native_prop = PROPERTY_REMAP[class_name][name]
311 | members.append({"name": name, "type": type, "native": native_prop})
312 |
313 | for m in cls.find("methods") if cls.find("methods") is not None else []:
314 | m_dict = dict(m.attrib)
315 | method_name = m_dict["name"]
316 | if method_name == class_name:
317 | continue # ignore constructors
318 | if class_name in IGNORED_PROPS and method_name in IGNORED_PROPS[class_name]:
319 | continue # ignored methods
320 | if class_name == "PackedByteArray" and method_name.startswith("encode_") or method_name.startswith("decode_"):
321 | continue # ignore decode/encode methods
322 | if class_name == "PackedByteArray" and method_name == "get_string_from_wchar":
323 | continue
324 | return_type = m.find("return").attrib["type"] if m.find("return") != None else "void"
325 | if return_type in TYPE_MAP:
326 | return_type = TYPE_MAP[return_type]
327 | arguments = []
328 | for arg in m.iter("param"):
329 | dictArg = dict(arg.attrib)
330 | if "dictArg" in dictArg:
331 | dictArg.pop("index")
332 | dictArg["default_value"] = dictArg["default"] if "default" in dictArg else None
333 | if "default" in dictArg:
334 | dictArg.pop("default")
335 | type = dictArg["type"]
336 | if type in TYPE_MAP:
337 | type = TYPE_MAP[type]
338 | arguments.append(
339 | {
340 | "type": type,
341 | "default_value": dictArg["default_value"],
342 | "has_default_value": "default" in dictArg,
343 | }
344 | )
345 | methods.append(
346 | {
347 | "name": method_name,
348 | "native_method": method_name,
349 | "return": return_type,
350 | "arguments": arguments,
351 | }
352 | )
353 | if class_name.startswith("Packed") and class_name.endswith("Array"):
354 | methods.append(METHOD_PACKED_ARRAY_GET)
355 | # add operator methods
356 | if class_name in OPERATOR_METHODS:
357 | for em in OPERATOR_METHODS[class_name]:
358 | operators.append(em)
359 |
360 | for c in cls.find("constants") if cls.find("constants") is not None else []:
361 | const_name = c.get("name")
362 | if class_name in IGNORED_PROPS and const_name in IGNORED_PROPS[class_name]:
363 | continue
364 | constants.append(dict(c.attrib))
365 | return json.loads(
366 | apply_pattern(
367 | json.dumps(ret),
368 | {
369 | "class_name": class_name,
370 | },
371 | )
372 | )
373 |
374 |
375 | def generate_api_json(MODULES_DIR):
376 | DOCS_DIR = os.path.abspath(os.path.join(MODULES_DIR, "../../doc/classes"))
377 | if not os.path.isdir(DOCS_DIR) and len(sys.argv) > 1:
378 | DOCS_DIR = sys.argv[-1]
379 | OUTPUT_FILE = os.path.join(MODULES_DIR, "builtin_api.gen.json")
380 |
381 | classes = []
382 | for cls in BUILTIN_CLASSES:
383 | tree = ET.parse(open(os.path.join(DOCS_DIR, cls + ".xml"), "r"))
384 | data = tree.getroot()
385 | classes.append(parse_class(data))
386 | json.dump(classes, open(OUTPUT_FILE, "w"), ensure_ascii=False, indent=2, sort_keys=True)
387 |
388 |
389 | if __name__ == "__main__":
390 | generate_api_json(".")
391 |
--------------------------------------------------------------------------------
/icons/JavaScript.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/icons/JavaScriptModule.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/javascript.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef JAVASCRIPT_H
3 | #define JAVASCRIPT_H
4 |
5 | #include "core/io/resource_loader.h"
6 | #include "core/io/resource_saver.h"
7 | #include "core/object/script_language.h"
8 | #include "scene/resources/text_file.h"
9 |
10 | #include "javascript_binder.h"
11 |
12 | #define EXT_NAME "JavaScript"
13 | #define EXT_JSCLASS "mjs"
14 | #define EXT_TSCLASS "ts"
15 | #define EXT_JSMODULE "js"
16 | #define EXT_JSON "json"
17 | #define EXT_GENERATE "//generatedPath="
18 |
19 | class JavaScript : public Script {
20 | GDCLASS(JavaScript, Script);
21 |
22 | private:
23 | friend class JavaScriptInstance;
24 | friend class QuickJSBinder;
25 | friend class ResourceFormatLoaderJavaScript;
26 |
27 | HashSet