├── .gitignore ├── LICENSE ├── README.md └── addons └── native_integration ├── CreateClassDialog.gd ├── NativeIntegration.gd ├── NativeMain.tscn ├── NativeMainWindow.gd ├── NativeProject.gd ├── base_files ├── build.bat ├── build.sh ├── cpp.txt ├── gdlibrary.txt └── hpp.txt ├── icons ├── error.svg ├── error.svg.import ├── question.svg ├── question.svg.import ├── thumbs-up.svg └── thumbs-up.svg.import └── plugin.cfg /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 nonunknown 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 | # WIP - Godot Native Integration ( Experimental Release) 2 | 3 | 4 | ### Description 5 | 6 | Provides a interface for easy GDNative management/building all-in-one inside the engine. 7 | This is a implementation of @WillNationsDev's proposal #119 for godot engine - https://github.com/godotengine/godot-proposals/issues/119 8 | 9 | All feedback is important on this stage of development so dont forget to create an issue, and tell your experience/idea/bug report 10 | 11 | ### Why this plugin exists? 12 | 13 | Well the current workflow for doing Native stuff is very complex, so this plugin facilitate the workflow. 14 | 15 | ### Plans for the future 16 | 17 | * Add support for all languages that godot-engine support 18 | * Multiple Projects managing 19 | * Cross-compiling support (if possible remote compiling with travis-ci) 20 | 21 | ## Requeriments 22 | 23 | * Git (To download git repos) 24 | The other requirements are the same for compiling the godot's source code 25 | * For Linux: 26 | https://docs.godotengine.org/en/stable/development/compiling/compiling_for_x11.html 27 | * For Windows: 28 | https://docs.godotengine.org/en/stable/development/compiling/compiling_for_windows.html 29 | 30 | ## Instructions 31 | 32 | * 1 - When You install like any plugin, and enable it (image below) it will take a little longer because it will install the necessary files at the godot data folder. 33 | 34 | ![test](https://i.imgur.com/kY2hap3.png) 35 | 36 | * 2 - These new generated files Can be accessed via: 37 | 38 | ![](https://i.imgur.com/qEwGjFO.png) 39 | 40 | * 3 - You'll be able to see a folder called native 41 | 42 | ![](https://i.imgur.com/5wLcxGA.png) 43 | 44 | * 4 - Inside the engine a button called native will appear on top-right corner: 45 | 46 | ![](https://i.imgur.com/kAtr079.png) 47 | 48 | * 5 - This is the main window: 49 | 50 | ![](https://i.imgur.com/Bd5pxbK.png) 51 | 52 | * 6 - About: 53 | - PROJECT NAME: For now only one project is supported, but in further updates you will be able to manage as many projects as you want 54 | - GENERATE BINDINGS: Generate necessary stuff for compiling your native code (if everything goes well a green icon will be shown) 55 | - COMPILE SOURCES: Compile your created classes, so you first must create your classes modify them (going into `native/src/my_project` see step 2) 56 | - PLATFORM: Select which OS you want to build for, (currently only works with the one you are working on e.g: if you are on windows just leave, or if you are on linux leave there) 57 | - TARGET: You can use release (for final stuff) or debug ( for testing purposes, larger file) 58 | - PROCESSOR CORES: How many cores your processor has (faster compiling) 59 | - INSERT NEW CLASS: Create your classes there 60 | 61 | * 7 - Final: 62 | Now just modify your classes (step 2 - for accesing them) and click COMPILE SOURCES, and if no error appears on output you're done! 63 | 64 | ### Credits 65 | 66 | A huge thanks to this guy: -> 67 | 68 | ![](https://i.imgur.com/DCEHh03.png) 69 | 70 | Without him this project wouldn't be possible he helped with SCons file for building, also a lot of help with my errors during development 71 | -------------------------------------------------------------------------------- /addons/native_integration/CreateClassDialog.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends WindowDialog 3 | 4 | onready var native_main = get_parent() 5 | onready var te_name:LineEdit = $VBoxContainer/HBoxContainer/TextEdit 6 | onready var msg:Label = $VBoxContainer/msg 7 | var file:File = File.new() 8 | 9 | func _create_src_files(): 10 | var file_name:String = te_name.text 11 | var path:String = native_main.get_project_src_path()+"/%s.%s" 12 | file.open("res://addons/native_integration/base_files/cpp.txt",File.READ) 13 | var cpp = file.get_as_text() 14 | file.close() 15 | 16 | 17 | file.open("res://addons/native_integration/base_files/hpp.txt",File.READ) 18 | var hpp = file.get_as_text() 19 | file.close() 20 | 21 | file.open( path % [file_name, "cpp"],File.WRITE) 22 | file.store_string(cpp.replace("%CLASS_NAME%",file_name)) 23 | file.close() 24 | file.open(path % [file_name, "hpp"],File.WRITE) 25 | hpp = hpp.replace("%DEF%",file_name.to_upper()) 26 | file.store_string(hpp.replace("%CLASS_NAME%",file_name)) 27 | file.close() 28 | hide() 29 | native_main.update_class_list() 30 | pass 31 | 32 | func _on_bt_done_pressed(): 33 | var project_folder = native_main 34 | _create_src_files() 35 | pass # Replace with function body. 36 | -------------------------------------------------------------------------------- /addons/native_integration/NativeIntegration.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | class_name NativeIntegration 4 | 5 | var dir:Directory = Directory.new() 6 | var slash = "/" 7 | var main_window:Control = null 8 | var bt_main:Button = Button.new() 9 | const main_path = "res://addons/native_integration/NativeMain.tscn" 10 | func _enter_tree(): 11 | bt_main.text = "Native" 12 | bt_main.connect("pressed",self,"_on_bt_main_pressed") 13 | add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR,bt_main) 14 | main_window = load(main_path).instance() 15 | 16 | add_child(main_window) 17 | 18 | if (OS.get_name() == "Windows"): slash = "\\" 19 | 20 | dir.open(ProjectSettings.globalize_path("user://")) 21 | dir.change_dir("../../") 22 | if dir.dir_exists(dir.get_current_dir()+slash+"native"): 23 | print("it has") 24 | 25 | else: 26 | print("not exitst") 27 | var output:Array 28 | OS.execute("git",["clone","https://github.com/nonunknown/godot-cpp-base.git", dir.get_current_dir()+slash+"native", "--recursive"],true,output,true) 29 | print(output) 30 | 31 | # dir.change_dir(dir.get_current_dir()+slash+"native"+slash+"godot-cpp") 32 | # print("new dir %s" % dir.get_current_dir()) 33 | main_window.set_native_path(dir.get_current_dir()) 34 | 35 | func _exit_tree(): 36 | remove_child(main_window) 37 | remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR,bt_main) 38 | pass 39 | 40 | func _on_bt_main_pressed(): 41 | main_window.about_to_open() 42 | main_window.get_node("Dialog").show() 43 | pass 44 | -------------------------------------------------------------------------------- /addons/native_integration/NativeMain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://addons/native_integration/NativeMainWindow.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/native_integration/icons/question.svg" type="Texture" id=2] 5 | [ext_resource path="res://addons/native_integration/icons/thumbs-up.svg" type="Texture" id=3] 6 | [ext_resource path="res://addons/native_integration/icons/error.svg" type="Texture" id=4] 7 | [ext_resource path="res://addons/native_integration/CreateClassDialog.gd" type="Script" id=5] 8 | 9 | [node name="NativeMain" type="Control"] 10 | use_parent_material = true 11 | anchor_right = 1.0 12 | anchor_bottom = 1.0 13 | mouse_filter = 2 14 | script = ExtResource( 1 ) 15 | __meta__ = { 16 | "_edit_use_anchors_": false 17 | } 18 | icons = [ ExtResource( 2 ), ExtResource( 3 ), ExtResource( 4 ) ] 19 | np_le_proj = NodePath("Dialog/vbc/p/vbcc/gc/hbc/le_project") 20 | np_bt_createproj = NodePath("Dialog/vbc/p/vbcc/gc/hbc/bt_createproj") 21 | np_bt_genbin = NodePath("Dialog/vbc/p/vbcc/bt_genbind") 22 | np_bt_compile = NodePath("Dialog/vbc/p/vbcc/bt_compile") 23 | np_ob_platform = NodePath("Dialog/vbc/p/vbcc/gc2/ob_platform") 24 | np_ob_target = NodePath("Dialog/vbc/p/vbcc/gc2/ob_target") 25 | np_sb_proc = NodePath("Dialog/vbc/p/vbcc/gc2/sb_proc") 26 | np_bt_createclass = NodePath("Dialog/vbc/p/vbcc/bt_create_class") 27 | 28 | [node name="Dialog" type="ConfirmationDialog" parent="."] 29 | visible = true 30 | use_parent_material = true 31 | anchor_left = 0.5 32 | anchor_top = 0.5 33 | anchor_right = 0.5 34 | anchor_bottom = 0.5 35 | margin_left = -325.0 36 | margin_top = -271.0 37 | margin_right = 325.0 38 | margin_bottom = 271.0 39 | rect_min_size = Vector2( 150, 52.5 ) 40 | window_title = "Native Settings" 41 | __meta__ = { 42 | "_edit_use_anchors_": false 43 | } 44 | 45 | [node name="vbc" type="VBoxContainer" parent="Dialog"] 46 | anchor_right = 1.0 47 | anchor_bottom = 1.0 48 | margin_left = 8.0 49 | margin_top = 8.0 50 | margin_right = -8.0 51 | margin_bottom = -36.0 52 | custom_constants/separation = 18 53 | __meta__ = { 54 | "_edit_use_anchors_": false 55 | } 56 | 57 | [node name="rtl" type="RichTextLabel" parent="Dialog/vbc"] 58 | margin_right = 634.0 59 | margin_bottom = 30.0 60 | custom_colors/default_color = Color( 0.556863, 0.556863, 0.556863, 1 ) 61 | bbcode_enabled = true 62 | bbcode_text = "[center]In order to compile stuff, 63 | make sure you have[url=https://docs.godotengine.org/en/stable/development/compiling/index.html] these installed on your machine[/url]" 64 | text = "In order to compile stuff, 65 | make sure you have these installed on your machine" 66 | fit_content_height = true 67 | 68 | [node name="p" type="Panel" parent="Dialog/vbc"] 69 | margin_top = 48.0 70 | margin_right = 634.0 71 | margin_bottom = 498.0 72 | size_flags_vertical = 3 73 | 74 | [node name="vbcc" type="VBoxContainer" parent="Dialog/vbc/p"] 75 | anchor_right = 1.0 76 | anchor_bottom = 1.0 77 | margin_left = 13.1225 78 | margin_top = 4.0 79 | margin_right = -10.8776 80 | margin_bottom = -4.0 81 | custom_constants/separation = 10 82 | __meta__ = { 83 | "_edit_use_anchors_": false 84 | } 85 | 86 | [node name="gc" type="GridContainer" parent="Dialog/vbc/p/vbcc"] 87 | margin_right = 610.0 88 | margin_bottom = 24.0 89 | columns = 2 90 | __meta__ = { 91 | "_edit_use_anchors_": false 92 | } 93 | 94 | [node name="lb_pname" type="Label" parent="Dialog/vbc/p/vbcc/gc"] 95 | margin_top = 5.0 96 | margin_right = 303.0 97 | margin_bottom = 19.0 98 | size_flags_horizontal = 3 99 | text = "Project Name" 100 | 101 | [node name="hbc" type="HBoxContainer" parent="Dialog/vbc/p/vbcc/gc"] 102 | margin_left = 307.0 103 | margin_right = 610.0 104 | margin_bottom = 24.0 105 | size_flags_horizontal = 3 106 | 107 | [node name="le_project" type="LineEdit" parent="Dialog/vbc/p/vbcc/gc/hbc"] 108 | margin_right = 247.0 109 | margin_bottom = 24.0 110 | hint_tooltip = "Mus be a UNIQUE NAME for each project, since the compile stuff is installed globally a name must be used to identify only \"local\" scripts." 111 | size_flags_horizontal = 3 112 | text = "my_project" 113 | virtual_keyboard_enabled = false 114 | 115 | [node name="bt_createproj" type="Button" parent="Dialog/vbc/p/vbcc/gc/hbc"] 116 | margin_left = 251.0 117 | margin_right = 303.0 118 | margin_bottom = 24.0 119 | text = "create" 120 | expand_icon = true 121 | __meta__ = { 122 | "_edit_use_anchors_": false 123 | } 124 | 125 | [node name="hs" type="HSeparator" parent="Dialog/vbc/p/vbcc"] 126 | margin_top = 34.0 127 | margin_right = 610.0 128 | margin_bottom = 38.0 129 | 130 | [node name="bt_genbind" type="Button" parent="Dialog/vbc/p/vbcc"] 131 | margin_top = 48.0 132 | margin_right = 610.0 133 | margin_bottom = 68.0 134 | disabled = true 135 | text = "Generate Bindings" 136 | icon = ExtResource( 2 ) 137 | expand_icon = true 138 | __meta__ = { 139 | "_edit_use_anchors_": false 140 | } 141 | 142 | [node name="bt_compile" type="Button" parent="Dialog/vbc/p/vbcc"] 143 | margin_top = 78.0 144 | margin_right = 610.0 145 | margin_bottom = 98.0 146 | disabled = true 147 | text = "Compile Sources" 148 | icon = ExtResource( 2 ) 149 | expand_icon = true 150 | __meta__ = { 151 | "_edit_use_anchors_": false 152 | } 153 | 154 | [node name="gc2" type="GridContainer" parent="Dialog/vbc/p/vbcc"] 155 | margin_top = 108.0 156 | margin_right = 610.0 157 | margin_bottom = 180.0 158 | columns = 2 159 | __meta__ = { 160 | "_edit_use_anchors_": false 161 | } 162 | 163 | [node name="lb_platform" type="Label" parent="Dialog/vbc/p/vbcc/gc2"] 164 | margin_top = 3.0 165 | margin_right = 303.0 166 | margin_bottom = 17.0 167 | size_flags_horizontal = 3 168 | text = "Platform" 169 | 170 | [node name="ob_platform" type="OptionButton" parent="Dialog/vbc/p/vbcc/gc2"] 171 | margin_left = 307.0 172 | margin_right = 610.0 173 | margin_bottom = 20.0 174 | size_flags_horizontal = 3 175 | text = "windows" 176 | items = [ "windows", null, false, 0, null, "linux", null, false, 1, null, "osx", null, false, 2, null ] 177 | selected = 0 178 | __meta__ = { 179 | "_edit_use_anchors_": false 180 | } 181 | 182 | [node name="lb_target" type="Label" parent="Dialog/vbc/p/vbcc/gc2"] 183 | margin_top = 27.0 184 | margin_right = 303.0 185 | margin_bottom = 41.0 186 | size_flags_horizontal = 3 187 | text = "Target" 188 | 189 | [node name="ob_target" type="OptionButton" parent="Dialog/vbc/p/vbcc/gc2"] 190 | margin_left = 307.0 191 | margin_top = 24.0 192 | margin_right = 610.0 193 | margin_bottom = 44.0 194 | size_flags_horizontal = 3 195 | text = "release" 196 | items = [ "release", null, false, 0, null, "debug", null, false, 1, null ] 197 | selected = 0 198 | __meta__ = { 199 | "_edit_use_anchors_": false 200 | } 201 | 202 | [node name="lb_proc" type="Label" parent="Dialog/vbc/p/vbcc/gc2"] 203 | margin_top = 53.0 204 | margin_right = 303.0 205 | margin_bottom = 67.0 206 | size_flags_horizontal = 3 207 | text = "Processor Cores" 208 | 209 | [node name="sb_proc" type="SpinBox" parent="Dialog/vbc/p/vbcc/gc2"] 210 | margin_left = 307.0 211 | margin_top = 48.0 212 | margin_right = 610.0 213 | margin_bottom = 72.0 214 | size_flags_horizontal = 3 215 | min_value = 1.0 216 | max_value = 16.0 217 | value = 1.0 218 | 219 | [node name="hs2" type="HSeparator" parent="Dialog/vbc/p/vbcc"] 220 | margin_top = 190.0 221 | margin_right = 610.0 222 | margin_bottom = 194.0 223 | 224 | [node name="bt_create_class" type="Button" parent="Dialog/vbc/p/vbcc"] 225 | margin_top = 204.0 226 | margin_right = 610.0 227 | margin_bottom = 224.0 228 | text = "Insert New Class" 229 | expand_icon = true 230 | __meta__ = { 231 | "_edit_use_anchors_": false 232 | } 233 | 234 | [node name="ClassList" type="ItemList" parent="Dialog/vbc/p/vbcc"] 235 | margin_top = 234.0 236 | margin_right = 610.0 237 | margin_bottom = 442.0 238 | size_flags_vertical = 3 239 | allow_reselect = true 240 | auto_height = true 241 | 242 | [node name="WindowDialog" type="WindowDialog" parent="."] 243 | anchor_left = 0.5 244 | anchor_top = 0.5 245 | anchor_right = 0.5 246 | anchor_bottom = 0.5 247 | margin_left = -202.0 248 | margin_top = -53.0 249 | margin_right = 203.0 250 | margin_bottom = 90.0 251 | popup_exclusive = true 252 | window_title = "Create a Class" 253 | script = ExtResource( 5 ) 254 | __meta__ = { 255 | "_edit_use_anchors_": false 256 | } 257 | 258 | [node name="VBoxContainer" type="VBoxContainer" parent="WindowDialog"] 259 | anchor_right = 1.0 260 | anchor_bottom = 1.0 261 | margin_left = 26.0 262 | margin_top = 12.0 263 | margin_right = -26.0 264 | margin_bottom = -13.0 265 | __meta__ = { 266 | "_edit_use_anchors_": false 267 | } 268 | 269 | [node name="HBoxContainer" type="HBoxContainer" parent="WindowDialog/VBoxContainer"] 270 | margin_right = 353.0 271 | margin_bottom = 24.0 272 | 273 | [node name="Label" type="Label" parent="WindowDialog/VBoxContainer/HBoxContainer"] 274 | margin_top = 5.0 275 | margin_right = 83.0 276 | margin_bottom = 19.0 277 | text = "Class Name: " 278 | 279 | [node name="TextEdit" type="LineEdit" parent="WindowDialog/VBoxContainer/HBoxContainer"] 280 | margin_left = 87.0 281 | margin_right = 353.0 282 | margin_bottom = 24.0 283 | size_flags_horizontal = 3 284 | 285 | [node name="msg" type="Label" parent="WindowDialog/VBoxContainer"] 286 | margin_top = 28.0 287 | margin_right = 353.0 288 | margin_bottom = 94.0 289 | size_flags_vertical = 3 290 | align = 1 291 | valign = 1 292 | 293 | [node name="bt_done" type="Button" parent="WindowDialog/VBoxContainer"] 294 | margin_top = 98.0 295 | margin_right = 353.0 296 | margin_bottom = 118.0 297 | size_flags_vertical = 0 298 | text = "Done" 299 | 300 | [connection signal="meta_clicked" from="Dialog/vbc/rtl" to="." method="_on_RichTextLabel_meta_clicked"] 301 | [connection signal="pressed" from="Dialog/vbc/p/vbcc/gc/hbc/bt_createproj" to="." method="_on_bt_createproj_pressed"] 302 | [connection signal="pressed" from="Dialog/vbc/p/vbcc/bt_genbind" to="." method="_on_bt_genbind_pressed"] 303 | [connection signal="pressed" from="Dialog/vbc/p/vbcc/bt_compile" to="." method="_on_bt_compile_pressed"] 304 | [connection signal="pressed" from="Dialog/vbc/p/vbcc/bt_create_class" to="." method="_on_bt_create_class_pressed"] 305 | [connection signal="pressed" from="WindowDialog/VBoxContainer/bt_done" to="WindowDialog" method="_on_bt_done_pressed"] 306 | -------------------------------------------------------------------------------- /addons/native_integration/NativeMainWindow.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | class_name NativeMain 4 | 5 | export(Array,Texture) var icons 6 | export var np_le_proj:NodePath 7 | export var np_bt_createproj:NodePath 8 | export var np_bt_genbin:NodePath 9 | export var np_bt_compile:NodePath 10 | export var np_ob_platform:NodePath 11 | export var np_ob_target:NodePath 12 | export var np_sb_proc:NodePath 13 | export var np_bt_createclass:NodePath 14 | 15 | onready var le_proj:LineEdit = get_node(np_le_proj) 16 | onready var bt_createproj:Button = get_node(np_bt_createproj) 17 | onready var bt_genbin:Button = get_node(np_bt_genbin) 18 | onready var bt_compile:Button = get_node(np_bt_compile) 19 | onready var ob_platform:OptionButton = get_node(np_ob_platform) 20 | onready var ob_target:OptionButton = get_node(np_ob_target) 21 | onready var sb_proc:SpinBox = get_node(np_sb_proc) 22 | onready var bt_createclass:Button = get_node(np_bt_createclass) 23 | #export var np_:NodePath 24 | 25 | onready var file:File = File.new() 26 | 27 | var native_path:String 28 | 29 | func get_project_bin_path() -> String: return "%s/native/bin/%s" % [native_path, proj.proj_name] 30 | func get_project_src_path() -> String: return "%s/native/src/%s" % [native_path, proj.proj_name] 31 | 32 | func set_native_path(path:String): 33 | native_path = path 34 | print("base path is: "+native_path) 35 | 36 | func _on_RichTextLabel_meta_clicked(meta): 37 | OS.shell_open(meta) 38 | pass # Replace with function body. 39 | 40 | func _disable_buttons(disable:bool=true): 41 | var buttons = [bt_compile,bt_genbin] 42 | 43 | for bt in buttons: 44 | if bt is Button: 45 | bt.disabled = disable 46 | 47 | 48 | func _on_bt_genbind_pressed(): 49 | _disable_buttons(true) 50 | var dir:Directory = Directory.new() 51 | dir.change_dir("%s/native/godot-cpp/" % native_path) 52 | var output:Array 53 | # var platform = "windows" 54 | # print(OS.get_name()) 55 | # if OS.get_name() == "X11": platform = "linux" 56 | print("the dir bindinging: "+dir.get_current_dir()) 57 | var platform = ob_platform.get_item_text(ob_platform.get_selected_id()) 58 | var target = ob_target.get_item_text(ob_target.get_selected_id()) 59 | var nproc = sb_proc.value 60 | var files = dir_contents(native_path+"/native/godot-cpp/bin",false) 61 | var generate_bindings:bool = true 62 | 63 | if files != []: 64 | bt_genbin.set_button_icon(icons[1]) 65 | for f in files: 66 | var file:String = f 67 | if platform in file: 68 | if target in file: 69 | generate_bindings = false 70 | print("Bindings for selected options already exists") 71 | 72 | if generate_bindings: 73 | var path = "%s/native/godot-cpp/" % native_path 74 | var windows_stuff:String = "" 75 | if platform == "windows": windows_stuff = "use_mingw=yes" 76 | var result = OS.execute("scons",["-C",path,"-j%d" % nproc, "platform=%s" % platform,"generate_bindings=yes","target=%s" % target, windows_stuff,"bits=64"],true,output,true) 77 | if result != 0: 78 | bt_genbin.set_button_icon(icons[2]) 79 | print(str(result)) 80 | print(output) 81 | _disable_buttons(false) 82 | pass # Replace with function body. 83 | 84 | 85 | #Project Stuff 86 | const save_name:String = "NativeIntegrationSAVE.tres" 87 | var proj:NativeProject = null 88 | 89 | func about_to_open(): 90 | #Check for save file 91 | var file = File.new() 92 | if file.file_exists("res://%s" % save_name): 93 | print("Save File Found") 94 | load_project() 95 | else: 96 | print("Project Not found, please create a new project and click create button before procedding") 97 | update_class_list() 98 | func load_project(): 99 | proj = ResourceLoader.load("res://%s" % save_name) as NativeProject 100 | le_proj.text = proj.proj_name 101 | le_proj.set_editable(false) 102 | bt_createproj.disabled = true 103 | 104 | bt_genbin.disabled = false 105 | 106 | pass 107 | 108 | func save_project(): 109 | if proj == null: 110 | proj = NativeProject.new() 111 | proj.proj_name = le_proj.text 112 | ResourceSaver.save("res://%s" % save_name,proj) 113 | load_project() 114 | pass 115 | 116 | func create_project(): 117 | var project_name:String = le_proj.text 118 | project_name = project_name.to_lower() 119 | project_name = project_name.replace(" ","_") 120 | 121 | #Check folders src/n and bin/n for a folder with project name 122 | var already_exists:bool = false 123 | for dir in dir_contents("%s/src/%s" % [native_path, project_name]): 124 | if project_name in dir: 125 | 126 | already_exists = true 127 | break 128 | if !already_exists: 129 | for dir in dir_contents("%s/src/%s" % [native_path, project_name]): 130 | if project_name in dir: 131 | already_exists = true 132 | break 133 | 134 | if already_exists: 135 | printerr("Error project: %s already exists, use another name" % project_name) 136 | return 137 | 138 | bt_createproj.disabled = true 139 | le_proj.set_editable(false) 140 | 141 | var dir:Directory = Directory.new() 142 | var folders = ["bin","src"] 143 | dir.open(native_path+"/native") 144 | for folder in folders: 145 | var path = dir.get_current_dir()+"/%s/%s" % [folder, project_name] 146 | print("Creating dir at: " + dir.get_current_dir()) 147 | dir.make_dir(path) 148 | 149 | print("Directories created") 150 | save_project() 151 | 152 | pass 153 | 154 | func create_class(): 155 | $WindowDialog.show() 156 | 157 | func dir_contents(path,folder_only:bool = true) -> Array: 158 | var dir = Directory.new() 159 | var contents:Array = [] 160 | if dir.open(path) == OK: 161 | dir.list_dir_begin() 162 | var file_name = dir.get_next() 163 | while file_name != "": 164 | if dir.current_is_dir() and folder_only: 165 | contents.append(file_name) 166 | elif !folder_only: 167 | contents.append(file_name) 168 | file_name = dir.get_next() 169 | else: 170 | printerr("An error occurred when trying to access the path.") 171 | return contents 172 | 173 | func _on_bt_compile_pressed(): 174 | file.open("res://addons/native_integration/base_files/gdlibrary.txt",File.READ) 175 | var gdlib = file.get_as_text() 176 | file.close() 177 | var headers:String = "" 178 | var classes:String = "" 179 | for c in get_classes(): 180 | headers += '#include "%s.hpp"\n' % c 181 | classes += "register_class<%s>();\n\t" % c 182 | 183 | gdlib = gdlib % [headers,classes] 184 | file.open(get_project_src_path()+"/gdlibrary.cpp",File.WRITE) 185 | file.store_string(gdlib) 186 | file.close() 187 | 188 | _disable_buttons(true) 189 | var dir:Directory = Directory.new() 190 | dir.change_dir(get_project_src_path()) 191 | var output:Array 192 | print("the dir bindinging: "+dir.get_current_dir()) 193 | var platform = ob_platform.get_item_text(ob_platform.get_selected_id()) 194 | var target = ob_target.get_item_text(ob_target.get_selected_id()) 195 | var nproc = sb_proc.value 196 | var files = dir_contents(native_path+"/native/godot-cpp/bin",false) 197 | 198 | if files != []: 199 | bt_genbin.set_button_icon(icons[1]) 200 | for f in files: 201 | var file:String = f 202 | if platform in file: 203 | if !target in file: 204 | printerr("You must generate bindings for these options first") 205 | return 206 | 207 | 208 | var windows_stuff:String = "" 209 | if platform == "windows": windows_stuff = "use_mingw=yes" 210 | print("compiling on path %s" % native_path) 211 | print("src folder %s" % get_project_bin_path()) 212 | var path = native_path+"/native" 213 | print("path: %s" % path) 214 | 215 | # var cmd:PoolStringArray = ["-C",'"%s"' % path,'target=release','platform=windows','src_path="%s/src/my_project"' % path, '-j4' ,windows_stuff, 'bits=64'] 216 | # var result =OS.execute("scons",cmd,true,output,true) 217 | var result = -1 218 | if OS.get_name() == "Windows": 219 | file.open("res://addons/native_integration/base_files/build.bat",File.READ_WRITE) 220 | path = path.replace("/","\\") 221 | var target_path = path+"\\bin\\%s" % proj.proj_name 222 | var src_path = path+"\\src\\%s" % proj.proj_name 223 | var cmd = file.get_as_text() % [path,target_path,src_path,target,str(nproc) ] 224 | file.close() 225 | file.open("res://temp_build.bat",File.WRITE) 226 | file.store_string(cmd) 227 | file.close() 228 | 229 | result = OS.shell_open( ProjectSettings.globalize_path("res://temp_build.bat")) 230 | elif OS.get_name() == "X11": 231 | file.open("res://addons/native_integration/base_files/build.sh",File.READ) 232 | var target_path = path+"/bin/%s" % proj.proj_name 233 | var src_path = path+"/src/%s" % proj.proj_name 234 | var cmd = file.get_as_text() % [path, target_path,src_path,target,str(nproc)] 235 | file.close() 236 | file.open("res://temp_build.sh",File.WRITE) 237 | file.store_string(cmd) 238 | file.close() 239 | result = OS.shell_open( ProjectSettings.globalize_path("res://temp_build.sh")) 240 | if result != 0: 241 | bt_compile.set_button_icon(icons[2]) 242 | else: 243 | var error = -1 244 | var lib:GDNativeLibrary = GDNativeLibrary.new() 245 | 246 | if OS.get_name() == "Windows": 247 | error = dir.copy(get_project_bin_path()+"/windows/libcdt-gd.dll","res://libcdt-gd.dll") 248 | lib.set("entry/Windows.64", "res://libcdt-gd.dll") 249 | else: 250 | error = dir.copy(get_project_bin_path()+"/x11/libcdt-gd.so","res://libcdt-gd.so") 251 | lib.set("entry/X11.64", "res://libcdt-gd.so") 252 | if error != OK: 253 | print("Error at copying dll to that folder: %d" % error) 254 | return 255 | # lib.config_file.set_value("resource","entry/Windows.64","res://libcdt-gd.dll") 256 | # lib.config_file.set_value("resource","dependency/Windows.64","[ ]") 257 | 258 | error = ResourceSaver.save("res://gdlib.gdnlib",lib) 259 | if error != OK: 260 | printerr("Error at saving GDLib: %d" % error) 261 | return 262 | 263 | for c in get_classes(): 264 | var gdns:NativeScript = NativeScript.new() 265 | 266 | gdns.set("class_name",c) 267 | gdns.library = lib 268 | gdns.script_class_name = c 269 | error = ResourceSaver.save("res://%s.gdns" % c,gdns) 270 | if error !=OK: 271 | printerr("Error at saving GDNS: %s, error num: %d" % [c, error]) 272 | return 273 | print("DONE") 274 | pass 275 | 276 | print(str(result)) 277 | print(output) 278 | _disable_buttons(false) 279 | 280 | pass # Replace with function body. 281 | 282 | 283 | func _on_bt_createproj_pressed(): 284 | create_project() 285 | pass # Replace with function body. 286 | 287 | 288 | func _on_bt_create_class_pressed(): 289 | create_class() 290 | pass # Replace with function body. 291 | 292 | func get_classes() -> Array: 293 | var dir = Directory.new() 294 | var path = native_path+"/native/src/%s" % proj.proj_name 295 | print(path) 296 | var contents = dir_contents(path,false) 297 | print(contents) 298 | var list = [] 299 | for file in contents: 300 | if file == "gdlibrary.cpp": continue 301 | if file.ends_with(".cpp"): 302 | list.append(file.split(".")[0]) 303 | return list 304 | 305 | func update_class_list(): 306 | 307 | var class_list:ItemList = $Dialog/vbc/p/vbcc/ClassList 308 | class_list.clear() 309 | for item in get_classes(): 310 | class_list.add_item(item) 311 | -------------------------------------------------------------------------------- /addons/native_integration/NativeProject.gd: -------------------------------------------------------------------------------- 1 | extends Resource 2 | class_name NativeProject 3 | 4 | export(String) var proj_name 5 | 6 | -------------------------------------------------------------------------------- /addons/native_integration/base_files/build.bat: -------------------------------------------------------------------------------- 1 | scons -C "%s" bits=64 target_path="%s" src_path="%s" platform=windows use_mingw=yes target=%s -j%s 2 | -------------------------------------------------------------------------------- /addons/native_integration/base_files/build.sh: -------------------------------------------------------------------------------- 1 | scons -C "%s" bits=64 target_path="%s" src_path="%s" platform=linux target=%s -j%s -------------------------------------------------------------------------------- /addons/native_integration/base_files/cpp.txt: -------------------------------------------------------------------------------- 1 | #include "%CLASS_NAME%.hpp" 2 | 3 | void %CLASS_NAME%::_register_methods() { 4 | register_method("first_method",&%CLASS_NAME%::first_method); 5 | } 6 | 7 | 8 | 9 | void %CLASS_NAME%::first_method() { 10 | //LOL 11 | } 12 | 13 | %CLASS_NAME%::%CLASS_NAME%() {} 14 | 15 | %CLASS_NAME%::~%CLASS_NAME%() {} -------------------------------------------------------------------------------- /addons/native_integration/base_files/gdlibrary.txt: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace godot; 4 | 5 | // Project includes 6 | //#include "headerfile.h**" 7 | %s 8 | 9 | // godot_gdnative_init 10 | extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options* o) 11 | { 12 | godot::Godot::gdnative_init(o); 13 | } 14 | 15 | // godot_gdnative_terminate 16 | extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options* o) 17 | { 18 | godot::Godot::gdnative_terminate(o); 19 | } 20 | 21 | // godot_nativescript_init 22 | extern "C" void GDN_EXPORT godot_nativescript_init(void* handle) 23 | { 24 | godot::Godot::nativescript_init(handle); 25 | 26 | //Register your files here! 27 | //register_class(); 28 | %s 29 | } 30 | -------------------------------------------------------------------------------- /addons/native_integration/base_files/hpp.txt: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #ifndef %DEF% 8 | #define %DEF% 9 | 10 | using namespace godot; 11 | 12 | class %CLASS_NAME% : public Reference { 13 | GODOT_CLASS(%CLASS_NAME%, Reference); 14 | 15 | public: 16 | static void _register_methods(); 17 | void first_method(); 18 | 19 | %CLASS_NAME%(); 20 | ~%CLASS_NAME%(); 21 | 22 | 23 | private: 24 | int value = 10; 25 | 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /addons/native_integration/icons/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 26 | 29 | 30 | 31 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /addons/native_integration/icons/error.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/error.svg-e0a60b5a1691704acac240388c8d00ae.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/native_integration/icons/error.svg" 13 | dest_files=[ "res://.import/error.svg-e0a60b5a1691704acac240388c8d00ae.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=false 34 | svg/scale=2.0 35 | -------------------------------------------------------------------------------- /addons/native_integration/icons/question.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 14 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /addons/native_integration/icons/question.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/question.svg-fc79a579f8adb9d5bde83f29565d5803.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/native_integration/icons/question.svg" 13 | dest_files=[ "res://.import/question.svg-fc79a579f8adb9d5bde83f29565d5803.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=false 34 | svg/scale=2.0 35 | -------------------------------------------------------------------------------- /addons/native_integration/icons/thumbs-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/native_integration/icons/thumbs-up.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/thumbs-up.svg-afe8460a631bf69a92d5ecc5f26ca383.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/native_integration/icons/thumbs-up.svg" 13 | dest_files=[ "res://.import/thumbs-up.svg-afe8460a631bf69a92d5ecc5f26ca383.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=false 34 | svg/scale=2.0 35 | -------------------------------------------------------------------------------- /addons/native_integration/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="NativeIntegration" 4 | description="Enable Godot Engine to deal with GDNative compilation stuff 5 | all inside the engine" 6 | author="Nonunknown" 7 | version="1.0" 8 | script="NativeIntegration.gd" 9 | --------------------------------------------------------------------------------